Please note that this version only works currently for Smarty v2, enabling smarty v3 will cause an error. I’ll post an update that resolves this issue shortly.
Update: This article has been revised in: 1.4 Plugins Revisited
In a previous article Display Module Output Anywhere I touched on the subject of subverting Prestashop’s internal Module architecture to our own ends. In this article we’ll be looking at creating a new mechanism for injecting module output into themes that doesn’t rely on tedious code changes, and should be able to be employed by (almost) anyone regardless of programming ability.
How about being able to display the home featured products anywhere in your template files just by adding a single line (as below)?
{plugin module='homefeatured' hook='home'}
If this looks like something you would find useful, then read on….
Hooks – A sledgehammer to crack a nut
I was recently faced with a design “problem” which I’m sure many of us working with Prestashop have faced. In this case there was a requirement to add featured products at the bottom of every cms page. It sounds really simple, but it’s actually a lot more complicated than it needs to be.
Modules are great for packaging up custom output for display. With modules you can create your own slideshows, tag clouds etc. and distribute them for use by non-programmers easily with just a click of a button. The major stumbling block to them being the ultimate “drop-in” component however is that modules are limited to rendering their output at very specific points within a theme, defined in Prestashop as “hooks”. The only control a theme designer has is to move an entire “hook point”, and these are pretty much hard-coded into the Prestashop core. Worse still – each module needs to be written to specifically support each hook point you may want to hook it to, and in reality many modules only support a limited selection of the available hooks.
The above limitations are only made worse by the fact that the ability to move the pre-defined hook points is limited almost to being within a single template file. In reality you can move a hook outside it’s “default” template file, but only to another template file which is rendered after its default one. For example you can move the header hook into the footer template, but not vice versa. This is due to the fact that the smarty variables used to hold the hook output are only in scope from the point in the page rendering process at which they’re defined.
In partial mitigation of this, as of version 1.4, it is now possible to override the core points at which Prestashop sets the scope of these hook variables. With proper care you can override the necessary controllers and redefine the order in which the hook points are rendered. You can also create your own hook points and populate them with appropriate content should you wish, although this may well be outwith the comfort zone of most end-users and theme designers, and in many cases will require modifications to modules which may cause issues when upgrading them later.
My Solution: “Plugins”
As stated at the beginning of this article; wouldn’t it be nice to just be able to add a single line of uncomplicated code in any template file, exactly where you want the output of a pre-existing module’s hook function to display? For example:
{plugin module='homefeatured' hook='home'}
Here’s how…..
The Plugin Core Class
For this to work we simply need to extend Prestashop a little by adding a new core class. For those who have been following articles on this site for some time you will recognise that this is based on my previous article on displaying module output.
// File: classes/Plugin.php
class PluginCore
{
public function moduleoutput($module, $hook, $hookArgs = array())
{
global $cart, $cookie;
$output = '';
if (!isset($hookArgs['cookie']) OR !$hookArgs['cookie'])
$hookArgs['cookie'] = $cookie;
if (!isset($hookArgs['cart']) OR !$hookArgs['cart'])
$hookArgs['cart'] = $cart;
$hookArgs['altern'] = 1;
$instance = Module::getInstanceByName($module);
if (is_callable(array($instance, 'hook'.$hook)))
$output = call_user_func(array($instance,'hook'.$hook), $hookArgs);
echo $output;
}
}
You may also have noticed that in addition to the two parameters we passed in the initial smarty template code example above (‘module’ and ‘hook’), this function takes a third parameter ‘$hookArgs’. This is to allow for the rare case where a module hook function expects additional arguments. It is unlikely that this will ever be used in practice in a theme. Surprisingly, the above is the bulk of the changes required to get this technique to work, in fact just by adding the above file we could insert module output into our theme’s template files, although we would have to use the {php} tags in smarty to call our class. To make this even more end-user friendly however, we’re next going to add an override to the FrontController class so that we can integrate this into Smarty via a ‘plugin’ template function.
// File: override/classes/FrontController.php
function smartyEcartPlugin($params, &$smarty)
{
return Plugin::moduleoutput($params['module'], $params['hook'], isset($params['args']) ? $params['args'] : array());
}
class FrontController extends FrontControllerCore
{
function __construct()
{
parent::__construct();
}
function init()
{
parent::init();
global $smarty;
$this->smarty = $smarty; // Not really sure why, but necessary.
if (!Configuration::get('PS_FORCE_SMARTY_2'))
{
$this->smarty->registerPlugin('function', 'plugin', 'smartyEcartPlugin');
} else {
$this->smarty->register_function('plugin', 'smartyEcartPlugin');
}
}
}
With the addition of just these two files you can now call module hook functions from anywhere within your theme’s template files using the syntax used in the example at the start of this article e.g.
{plugin module='homefeatured' hook='home'}
or
{plugin module='blocksearch' hook='top'}
Note: Modules still have to be installed so that you can use them in your theme. If you do not wish the module to display output in it’s default location then you should install the module and then remove unwanted hooks via the “positions” admin menu. There will also be cases where certain modules cannot display their output, and also cases where a particular module’s hook support function would not make sense in the context of a particular theme file.
I have kept the code to an absolute minimum and will likely extend some of the functions to perform some form of validation and perhaps even caching, but in essence the above is all you need to do to implement this handy theme shortcut. One of the reasons for implementing the code as a core class rather than just implementing all the code within the FrontController override is so that the Plugin class itself can be extended with an override. Have fun.
Download the required files
Please regard these files as experimental. They are not guaranteed in any way and could cause your store to function incorrectly.
Download Prestashop 1.4 Theme Plugin Extension








This is brilliant, you’ve explained my exact problem very well and your solution makes things so much easier to put where I want them. Thank you!
Won’t this confuse end-users about real positioning of the modules?
I don’t believe it does, at least it doesn’t make the process any more confusing than the traditional hook< ->position mechanism. I’ve used it to build in user-editable content on pages, and to remove lots of hard-coded elements from theme files, so I think overall it makes the theme more usable.
Great gem of plugin code.
It was not clear to me when you override the FrontController in override/classes/FrontController.php do you copy the original class file and add your code. Or just only your code?
And does your code already work for Smarty 3?
Update 2
think it haves to do with specific module,
nc image gallery, since e.g search module works!
Thanks again
Panagiotis
Update,
sorry
i had renamed
FrontController.php to _FrontController.php
(for replacing the one placed there)
Corrected with renaming back to FrontController.php
Now nothing happens
I have the same results as before plugin.
Hi Paul
i am trying to make the plugin work @ 1.4.1 installation.
unfortunatelly, i get only a blank page when
adding
{plugin module=’homefeatured’ hook=’home’}
at e.g categories.tpl
is something new at 1.4.1
or you have any suggestions?
Thanks again for the effort
Panagiotis
Hi,
The idea for this article is awesome! But I have problems using this plugin with Prestashop 1.4.1.0. I am not a prestashop programmer and I don’t really like the smarty theme system utilized by prestashop. Actually, I don’t know how to use this plugin. Am I supposed to add the lines from your “FrontController.php” to the “_FrontController.php” located in override/classes? I am sorry if I confused you in any way, but I just don’t get prestashop..
Please help! Thank you very much!
For Prestashop 1.4.0.17 i had to change the code in override/classes/FrontController
self::$smarty->registerPlugin(‘function’, ‘plugin’, array(‘FrontController’,'smartyEcartPlugin’));
Hey Paul,
This is an amazingly simple yet superior answer to Prestashop’s issues with hooks. I congratulate you on your ingenuity.
This is exactly what I need to solve some issues I am facing in Prestashop, sadly however I am going to have to wait till you solve your issues with smarty v3 since that is what my client wishes to use.
Keep up the good work.
Rob
Hi,
I’m now trying to make a project on PS 1.4 and I found your great plugin but it doesn’t supports Smarty 3 and in backoffice of PS 1.4 i found the notice:
“Smarty 2 will be unsupported from PrestaShop v1.5)”
*(
Hi there,
This looks exactly like the solution I’ve been looking for!
I’m new to Prestashop theming, so maybe you would provide me some information on where to extract the files into my PS installation? Can I place them in my theme directory so that everything is ‘collected and in place’ regarding future updates of PS?
Thanks!
Hi Paul,
I’ve been developing on PrestaShop for nearly 2 years now, and I’ve had massive trouble trying to work around hooks. Creating new hooks, hacking the core files, all of the usual.
This is a really function feature you’ve dreamt up, and I just want to thank you for it.
Having just downloaded and began working on 1.4 (1.2.5 until now), all the new /override/ functionality + your function open up so many possibilities.
So thanks again!
Mark
I have tested your plugin and I must say that it was perfect to construct complex and original design. But with the 1.4 rc5 it seems like we need to use smarty v3, did you finish your code update about that ?
Hi Paul
Have you passed this onto the Prestashop Devs i’m sure they would be interested in this.
I have unfortunately noticed that there’s a problem with the way I’ve implemented this when using smarty v3 – it appears that it doesn’t detect that the same plugin is being declared twice and throws an error (due to the fact that these inherited functions are called by child classes). I’ve got a newer version in the works so I’ll need to provide some updated code. I’ve also been playing with adding other little shortcuts, like being able to get the Prestashop configuration variables direct to the theme (things like the store name, address, email, telephone etc.); this can be handy as it saves having to write modules whose only purpose is to assign variables to smarty. Displaying the contents of a cms “page” is another one, so you can have editable blocks of text in your theme – something I need for a project I’m working on at the moment (if you set them as “disabled” in the back office, then there’s no danger of getting weird extra cms pages that seem out of context).
I’m just finishing the final testing (on a site I’m working on) and I’ll publish it. I’ve tried to do it this time in a way that’s easily extensible, and with some more examples.
Thanks for trying it and providing some feedback.