This is the documentation for concrete5 version 5.6 and earlier. View Current Documentation

When a block has a number of different templates and each template has different asset requirements for jQuery plugins, loading all of these plugins for any template can be a big overhead.

This problem came to a head when I was developing a range of different slideshow and image gallery templates for my Sorcerer’s Gallery addon. The core of the addon selected files to show, then various templates would show those files as a slideshow, as a slider, as thumbnails with fancybox and more. Each of these templates had its own requirement for loading jQuery plugins as block assets.

My solution was, in the block controller on_page_view() method, to look at the block template name and match that against jQuery files to load.

Get the block template name

First, from the block controller I needed to get the block template name. My first attempt wasto do:

$blockObject = $this->getBlockObject();
$template = $blockObject->getBlockFilename();

Unfortunately that falls over because the $blockObject is not always returned, so I added a fallback and wrapped it all in a method in my block controller:

public function get_block_template_name(){
    $blockObject = $this->getBlockObject();
    if (is_object($blockObject)) {
        $template = $blockObject->getBlockFilename();
        if ($template){
            return $template;
        }
    }
    // sometimes doesn't get returned by the above !!
    $db = Loader::db();
    $template = $db->getOne('SELECT bFilename FROM Blocks WHERE bID = ? ', array($this->bID));
    if ($template){
        return $template;
    }
    return 'view';
}

Parse the template name for asset requirements

With the template name, I could now use that to intelligently load the assets a template needed. At this stage it could be a simple switch statement based on the template. However, I wanted to allow for some future proofing so users of my block could add their own templates using assets already provided by my block.

My next step was to have a naming convention for templates that described the assets required and to parse the template name to extract that requirement.

public function template_asset_requirements(){
    $template = $this->get_block_template_name();
    $asset_keys = array();

    if ($template == 'view'){ // default view uses fancybox
        $asset_keys[] = 'fancybox';
    }
    if (preg_match("/fancy/i",$template)){
        $asset_keys[] = 'fancybox';
    }
    if (preg_match("/cycle/i",$template)){
        $asset_keys[] = 'cycle';
    }
    if (preg_match("/ease/i",$template) || preg_match("/easing/i",$template)){
        $asset_keys[] = 'easing';
    }
    if (preg_match("/ajax/i",$template) || preg_match("/bbax/i",$template)){
        $asset_keys[] = 'blocks_by_ajax';
    }

    // more tests for further assets

    return array_unique($asset_keys);
}

Worth noting here is that I have allowed shortened or abbreviated keywords for assets within the template name. Template names are limited to 32 characters, so for some templates every character counts.

Load the required assets

Finally, in the on_page_view() method and ignoring additional tests for edit mode and other on_page_view code:

public function on_page_view() {
    $tar = $this->template_asset_requirements();

    if (in_array('fancybox',$tar)){
        // add header/footer items for fancybox
    }
    if (in_array('easing',$tar)){
        // add header/footer items for easing
    }
    if (in_array('cycle',$tar)){
        // add header/footer items for cycle
    }

    // more checks and asset loading
}

Thus any block template containing 'cycle' and 'ease' in the template filename would have the assets for the jQuery cycle and easing plugins loaded by the block controller.

Read more How-Tos by JohntheFish.

Loading Conversation