For developers, a tutorial on how to inject assets into head/> or body/>

Talk about writing modules and plugins for CMS Made Simple, or about specific core functionality. This board is for PHP programmers that are contributing to CMSMS not for site developers
Post Reply

Was this post useful?

Yes
0
No votes
No
0
No votes
 
Total votes: 0

User avatar
magallo
Dev Team Member
Dev Team Member
Posts: 109
Joined: Thu Mar 24, 2011 12:37 am

For developers, a tutorial on how to inject assets into head/> or body/>

Post by magallo »

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:

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;
    }
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

Code: Select all

$this->AddEventHandler('Core', 'ContentPostRender', false);
xxx.module.php

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);
			}
		}
	}
	
action.detail.php

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" />';
(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.
Post Reply

Return to “Developers Discussion”