How to Add Hooks to PrestaShop CMS Pages

Prestashop CMS pages are useful, but lack the possibility of adding modules to any of them, specifically. Let’s see how to enhance these pages and create custom hooks for them!

Creating a custom hook for CMS pages

The first step is to create a new, custom hook and add it to the cms.tpl file. We will be using the new way to add hooks introduced in Prestashop 1.5.

Locate your cms.tpl inside the module’s folder, and open it up in any code editor. Please notice yours might look different from mine, as I am using Prestashop 1.6.0.8

[php htmlscript=”true”]
{if isset($cms) && !isset($cms_category)}
{if !$cms->active}
<br />
<div id="admin-action-cms">
<p>
<span>{l s=’This CMS page is not visible to your customers.’}</span>
<input type="hidden" id="admin-action-cms-id" value="{$cms->id}" />
<input type="submit" value="{l s=’Publish’}" name="publish_button" class="button btn btn-default"/>
<input type="submit" value="{l s=’Back’}" name="lnk_view" class="button btn btn-default"/>
</p>
<div class="clear" ></div>
<p id="admin-action-result"></p>
</p>
</div>
{/if}
<div class="rte{if $content_only} content_only{/if}">
{$cms->content}
</div>
{elseif isset($cms_category)}
<div class="block-cms">
<h1><a href="{if $cms_category->id eq 1}{$base_dir}{else}{$link->getCMSCategoryLink($cms_category->id, $cms_category->link_rewrite)}{/if}">{$cms_category->name|escape:’html’:’UTF-8′}</a></h1>
{if $cms_category->description}
<p>{$cms_category->description|escape:’html’:’UTF-8′}</p>
{/if}
{if isset($sub_category) && !empty($sub_category)}
<p class="title_block">{l s=’List of sub categories in %s:’ sprintf=$cms_category->name}</p>
<ul class="bullet list-group">
{foreach from=$sub_category item=subcategory}
<li>
<a class="list-group-item" href="{$link->getCMSCategoryLink($subcategory.id_cms_category, $subcategory.link_rewrite)|escape:’html’:’UTF-8′}">{$subcategory.name|escape:’html’:’UTF-8′}</a>
</li>
{/foreach}
</ul>
{/if}
{if isset($cms_pages) && !empty($cms_pages)}
<p class="title_block">{l s=’List of pages in %s:’ sprintf=$cms_category->name}</p>
<ul class="bullet list-group">
{foreach from=$cms_pages item=cmspages}
<li>
<a class="list-group-item" href="{$link->getCMSLink($cmspages.id_cms, $cmspages.link_rewrite)|escape:’html’:’UTF-8′}">{$cmspages.meta_title|escape:’html’:’UTF-8′}</a>
</li>
{/foreach}
</ul>
{/if}
</div>
{else}
<div class="alert alert-danger">
{l s=’This page does not exist.’}
</div>
{/if}
<br />
{strip}
{if isset($smarty.get.ad) && $smarty.get.ad}
{addJsDefL name=ad}{$base_dir|cat:$smarty.get.ad|escape:’html’:’UTF-8′}{/addJsDefL}
{/if}
{if isset($smarty.get.adtoken) && $smarty.get.adtoken}
{addJsDefL name=adtoken}{$smarty.get.adtoken|escape:’html’:’UTF-8′}{/addJsDefL}
{/if}
{/strip}

[/php]

We first need to decide where to put our module, if before the cms content, or after it. Whichever position you choose (you might also add two hooks, one before, one after), the important section of the page is the following:

[php htmlscript=”true”]

<div class="rte{if $content_only} content_only{/if}">
{$cms->content}
</div>

[/php]

I strongly advice to insert new hooks right outside the rte container block, to avoid cms styles to override the ones of any eventual module. At this point, let’s add the hook.

[php htmlscript=”true”]

{hook h=’customCMS’}

<div class="rte{if $content_only} content_only{/if}">
{$cms->content}
</div>

[/php]

As you can see, I decided to add mine right before the cms content block. It is important to notice the $content_only variable. If you prefer the hook not to be executed when viewing the cms page in a lighbox, you need to wrap it inside an if statement:

[php htmlscript=”true”]

{if !$content_only}
{hook h=’customCMS’}
{/if}

<div class="rte{if $content_only} content_only{/if}">
{$cms->content}
</div>

[/php]

This way, if you hooked something to your terms and conditions, this hook will not be executed when displaying the specific cms page in the checkout popup.

How to hook Modules to CMS pages

We have our custom hook. It’s time to decide which module we want to plug to a cms page.

Given that it cannot be done without modifying core module files (and by editing a native module we are not given the chance to upgrade it without losing modifications), to make our lives easier it’s generally a good idea to simply clone/call an existing hooking method.

In the example, I will use the Featured Products block module, to display the featured products list in a cms page (for no reason!). Therefore, open up homefeatured.php, located at modules/homefeatured, and then locate the install method:

[php]
public function install()
{
$this->_clearCache(‘*’);
Configuration::updateValue(‘HOME_FEATURED_NBR’, 8);

if (!parent::install()
|| !$this->registerHook(‘header’)
|| !$this->registerHook(‘addproduct’)
|| !$this->registerHook(‘updateproduct’)
|| !$this->registerHook(‘deleteproduct’)
|| !$this->registerHook(‘categoryUpdate’)
|| !$this->registerHook(‘displayHomeTab’)
|| !$this->registerHook(‘displayHomeTabContent’)
)
return false;

return true;
}
[/php]

We called our hook customCMS, so we need to register this during the module’s install:

[php]
public function install()
{
$this->_clearCache(‘*’);
Configuration::updateValue(‘HOME_FEATURED_NBR’, 8);

if (!parent::install()
|| !$this->registerHook(‘header’)
|| !$this->registerHook(‘addproduct’)
|| !$this->registerHook(‘updateproduct’)
|| !$this->registerHook(‘deleteproduct’)
|| !$this->registerHook(‘categoryUpdate’)
|| !$this->registerHook(‘displayHomeTab’)
|| !$this->registerHook(‘displayHomeTabContent’)
|| !$this->registerHook(‘customCMS’)
)
return false;

return true;
}
[/php]

Then, we need to add the hooking method at the end of the file, before the closing bracket

[php]
public function hookcustomCMS($params)
{
return $this->hookDisplayHome($params);
}
[/php]

This way, we are simply calling the default method used (not in 1.6, as that’s the tab one) to show the block in the homepage. We could as well clone the same method and change it as we prefer, of course (for example if we need to use another template), but this is the quickest way.

Save and reset the module, then navigate to any cms page:

How to add hooks to Prestashop CMS pages - Added featured products

It’s displaying, and that’s fine. However, it’s being shown in every CMS page! How to deal with it?

Target specific cms page in the hooking method

We obviously don’t want to display a module in every cms page, so we have to find a way to target each specific one. How? The quickest way is to use the CMS page ID, which is the number highlighted in the following screen.

How to add hooks to Prestashop CMS pages - CMS ID in page urls

If you use friendly urls, the ID will precede the page’s slug, like 1-delivery, where 1 is the ID. If not, the id is the number following id_cms= in the url.

Alternatively, it’s also displayed at the far left or the table listing all available cms pages, in the back office:

How to add hooks to Prestashop CMS pages - CMS ID in the  back office

Once we have this information, let’s use it in our new, custom hooking method:

[php]
public function hookcustomCMS($params)
{

if (Tools::getValue(‘id_cms’) != 1)
return;
return $this->hookDisplayHome($params);
}

[/php]

And we are done! Try to navigate to other pages. In my case, I will only see the block if I view the Delivery Information CMS.

Need Prestashop Modules? Have a look at my Prestashop Addons Store!

Looking for quality PrestaShop Web Hosting? Look no further than Arvixe Web Hosting!

Tags: , , , , , , , , | Posted under PrestaShop | RSS 2.0

Author Spotlight

Fabio Porta

Fabio has been involved in web development and design since 2005, when launched his first website at the age of 16. He’s now highly skilled in both client and server side development, along with design, and since August 2012 runs a successful website about PrestaShop tutorials and Prestashop Modules called Nemo’s Post Scriptum, at http://nemops.com

Leave a Reply

Your email address will not be published. Required fields are marked *