For developers, a tutorial on how to inject assets into head/> or body/>
Posted: Mon Oct 30, 2023 9:53 am
If like me, you found yourself in need of injecting assets into the head section of the template for a custom module that requires for example a javascript plugin, a css, or anything else, this tutorial will probably help you.
While developing a custom module you probably noticed the the following line in your main custom.module.php file:
In this case, "_output_header_assets()" is a function that loads selected assets and GetHeaderHTML() This will eventually render these assets into the <head> section of the admin template.
This comes pretty handy when the admin section of your module requires certain plugins to work with your module. For example drag&drop, multi upload plugins etc...
But what if your frontend needs a plugin to work side by side with your module? What's the point you ask?
A while back i was working on the YelpRank module for CMSMS and i needed to deliver the javascript and the stylesheet that handles the stars behavior to the frontend. It goes without saying that if the frontend template has assets that conflict with the module assets things my break but under normal conditions, things should work just fine.
Solution
So lets pretend your module has a detail template to display more information about an item. You need to load a js or css file into the template so here is how i'd do it:
method.install.php
xxx.module.php
action.detail.php
(when pasting the code into your own code, replace __script__ with script and __body with body)
You might need to update your module version in order to load the "ContentPostRender" Action Or Reinstall the module if that's easier.
At this point we will be using the $this->FrontEndJS and $this->FrontEndCSS to load the different assets into the head or body section of the template as per our "ContentPostRender" method.
Hope this help and feel free to contact me with any question.
While developing a custom module you probably noticed the the following line in your main custom.module.php file:
Code: Select all
public function GetHeaderHTML() { return $this->_output_header_javascript(); }
Code: Select all
protected function _output_header_assets()
{
$out = '';
$urlpath = $this->GetModuleURLPath()."/js";
$jsfiles = array('jquery.iframe-transport.js');
$jsfiles[] = 'jquery.fileupload.js';
$jsfiles[] = 'jQueryRotate-2.2.min.js';
$jsfiles[] = 'jquery.jrac.js';
$fmt = '<__script__ type="text/javascript" src="%s/%s"></__script>';
foreach( $jsfiles as $one ) {
$out .= sprintf($fmt,$urlpath,$one)."\n";
}
$urlpath = $this->GetModuleURLPath();
$fmt = '<link rel="stylesheet" type="text/css" href="%s/%s"/>';
$cssfiles = array('css/style.jrac.css');
$cssfiles[] = 'css/style.css';
foreach( $cssfiles as $one ) {
$out .= sprintf($fmt,$urlpath,$one);
}
return $out;
}
This comes pretty handy when the admin section of your module requires certain plugins to work with your module. For example drag&drop, multi upload plugins etc...
But what if your frontend needs a plugin to work side by side with your module? What's the point you ask?
A while back i was working on the YelpRank module for CMSMS and i needed to deliver the javascript and the stylesheet that handles the stars behavior to the frontend. It goes without saying that if the frontend template has assets that conflict with the module assets things my break but under normal conditions, things should work just fine.
Solution
So lets pretend your module has a detail template to display more information about an item. You need to load a js or css file into the template so here is how i'd do it:
method.install.php
Code: Select all
$this->AddEventHandler('Core', 'ContentPostRender', false);
Code: Select all
/**
* DoEvent methods
*/
function DoEvent($originator, $eventname, &$params) {
if ($originator == 'Core' && $eventname == 'ContentPostRender')
{
$pos_top = stripos($params["content"], "</head");
if ($pos_top !== FALSE && !empty($this->FrontEndCSS))
{
$params["content"] = substr($params["content"], 0, $pos_top) . $this->FrontEndCSS . substr($params["content"], $pos_top);
}
$pos_btm = strripos($params["content"], "<__body");
if ($pos_btm !== FALSE && !empty($this->FrontEndJS))
{
$params["content"] = substr($params["content"], 0, $pos_btm) . $this->FrontEndJS . substr($params["content"], $pos_btm);
}
}
}
Code: Select all
$this->FrontEndJS = '<__script__ src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js';
$this->FrontEndCSS = '<link rel="stylesheet" href="' . $this->GetModuleURLPath() . '/css/style.css" type="text/css" media="screen" />';
You might need to update your module version in order to load the "ContentPostRender" Action Or Reinstall the module if that's easier.
At this point we will be using the $this->FrontEndJS and $this->FrontEndCSS to load the different assets into the head or body section of the template as per our "ContentPostRender" method.
Hope this help and feel free to contact me with any question.