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 theme’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

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

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:


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

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.


{hook h='customCMS'}

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

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:


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

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

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:

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

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

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

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

	public function hookcustomCMS($params)
	{
		return $this->hookDisplayHome($params);
	}

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:

	public function hookcustomCMS($params)
	{

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

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.

You like the tuts and want to say "thank you"? Well, you can always feel free to donate:

  • Himanshu Bisht

    Can we do the same way in Ps 1.7.2?
    Thanks

  • NemoPS

    Try using if {$cms->id == 1}, using the specific ID for the page you want it to display on

  • Andrea

    {hook h=’customCMS’}
    What is this ?

  • Nes

    Thanks Nemo! Clear and useful ;)

  • Vikas Chauhan

    Hi Nemo,

    I want to add hook for showing blockcart module into a cms page, using prestashop1.6.1

    Basically we want to show cart summary on screen directly not on hover on as shown in header.

    Tell me the solution.

    Thanks

  • Mihai Danielescu

    not working dude, fuck u, fuck prestashop

  • NemoPS

    You can extend this

    http://nemops.com/page-specific-prestashop-module/#.VtVwLvk4Hmg

    And check if the current page is a category, then check if the needed ID is submitted

  • PR Tech

    Hello, I have been working with prestashop for 3 years now and needed this solution desperately. Unfortunately It did not work for me. I really need help figuring this out. I need to change the Quick Search module to a specific CMS Page. I am using Prestashop 1.5.4.1 and I could not find the “cms.tpl” inside the modules’ folder.

    Please help me! Great Thanks.

    • NemoPS

      Cms.tpl was there in 1.5 as well. It’s not in the modules’ folder, but the theme’s

  • waterproof

    Great thanks for this tutorial ! But I’ve any problem. I wish to get the module Gallery with Facebook button into one CMS page. So, I made what you say. But I’ve 2 errors about syntax in gallery_module.php.

    So I make again from the first step : including the new hook into cms.tpl (in theme) with {hook h=’galleryCMS’}. At this step, I suppose I would see a new position into the list in the backend ? But I don’t see the new position in the list. What is wrong ? Thanks for your help !
    .

  • Nicole

    Thanks for the tutorial. Is there a way to add different products to the featured list on the cms pages compared to the home page?

    • NemoPS

      Hello!
      There is, you should simply use 2 different functions for the 2 hooks (in the home and in the CMS page)

  • Димитър Илков

    Actually module can inject content to the cms page from displayFooter. Just grab the cms variable from Smarty and alter it as you wish

    public function hookDisplayFooter(){
    $cms_var = $this->context->smarty->getVariable(‘cms’);
    if(is_object($cms)){
    /** @var CMS $cms */
    $cms = $cms_var->value;

    if(Validate::isLoadedObject($cms))
    $cms->content .= $this->display(__FILE__,’my_custom_template.tpl’);
    }
    }

  • http://pelechano.es Enrique Gómez

    Is good to know that you can also pass params to the hook. For example
    {hook h=”displayAdminCustomers” id_customer=$customer->id}

    So in the hook method

    public function hookDisplayAdminCustomers($params) you can access $params[‘id_customer’]

  • Andrea Bernardi

    is it possible creating a custom hook for Home pages?

    thx

    • http://pelechano.es Enrique Gómez

      You can create hooks in any tpl. The important issue is having a module that hooks into that new hook and fills with info

Store Top Sales

You like the tuts and want to say "thank you"? Well, you can always feel free to donate: