How to create a Prestashop 1.5 module

The module API in Prestashop 1.4 (and before) used to be great. It was easy to understand and extremely straightforward. With version 1.5, it only got better!

The new module API is more complete and allows for a better file organization. We’ll look at all that in detail by creating an actual module. Also, this article assumes that you have a good knowledge of the Prestashop system.

Here are some screenshots of the end result we are after :

You can download all the code we are going to create at the bottom of this article. Or you can follow the step-by-step tutorial!

Step 1: Setting up the files

The first thing we have to do is create the basic files and folders needed for the module. We will create the following files/folders in our Prestashop’s “modules” folder:

  • /modules/skeleton/ – This folder will contain all the files we need for our module.
  • /modules/skeleton/skeleton.php – This will be the main file for our module. It is very important that this file bears the same name as our directory.
  • /modules/skeleton/logo.png – This is the main logo of our module. It will always be associated to our module. Not having one will make you look amateur. Ideally it has to be 32×32 pixels.
  • /modules/skeleton/logo.gif – Used when Prestashop needs a very small logo. Like in the autocomplete box in the backoffice modules area. This one should be 16×16 pixels.

Step 2: Creating the constructor

Now that we have the essentials set up, let’s get started with the actual coding. Open your skeleton.php file and add the following code :

if (!defined('_PS_VERSION_'))
  exit;

class Skeleton extends Module
{
  public function __construct()
  {
    $this->name = 'skeleton';
    $this->tab = 'front_office_features';
    $this->version = '1.0';
    $this->author = 'Jevin O. Sewaruth';

    parent::__construct();

    $this->displayName = $this->l('Skeleton Module');
    $this->description = $this->l('This is just an empty module. You should modify it to make your own.');

    $this->confirmUninstall = $this->l('Are you sure you want to uninstall this module?');

    $this->_checkContent();

    $this->context->smarty->assign('module_name', $this->name);
  }
}

This is our module’s constructor. It will provide all the necessary information about our module to Prestashop. Some points to note:

  • The first line checks if _PS_VERSION_ is defined. This is to prevent people from accessing our file directly by calling http://www.site.com/modules/skeleton/skeleton.php.
  • Then we will create a class with Skeleton as name. It is crucial for our class to have the same name as our main php file. Our class will extend the Module class, which provides the module functionalities.
  • The name field should be lowercase like our main php file and our main directory.
  • The tab represents the module category. The easiest way to get the appropriate tab for your module is to examine the links of the categories from the module administration area (there is a  complete list on the left). The link will contain the filterCategory parameter, e.g. filterCategory=front_office_features.
  • The confirmUninstall field is not mandatory, but can be important depending on the type of module.
  • Assigning the module name to Smarty in the constructor allows us to use the module’s name in the template. If used correctly, you will be able to reuse your template files for other modules.

Now let’s have a look at the _checkContent() method:

  private function _checkContent()
  {
    if (!Configuration::get('MOD_SKELETON_NAME') &&
      !Configuration::get('MOD_SKELETON_COLOR'))
      $this->warning = $this->l('You need to configure this module.');
  }

Pretty straightforward. We verify if the two settings MOD_SKELETON_NAME and MOD_SKELETON_COLOR are set. If not, we show a warning in the modules area.

You may note the naming. It will help you get around the numerous other settings, if ever you need to dive into the database.

Step 3: Adding the install/uninstall methods

Next we need to add these 4 methods to our skeleton.php file:

  public function install()
  {
    if (!parent::install() ||
      !$this->registerHook('displayHeader') ||
      !$this->registerHook('displayLeftColumn') ||
      !$this->registerHook('displayRightColumn') ||
      !$this->registerHook('displayFooter') ||
      !$this->_createContent())
      return false;
    return true;
  }

  public function uninstall()
  {
    if (!parent::uninstall() ||
      !$this->_deleteContent())
      return false;
    return true;
  }

  private function _createContent()
  {
    if (!Configuration::updateValue('MOD_SKELETON_NAME', '') ||
      !Configuration::updateValue('MOD_SKELETON_COLOR', ''))
      return false;
    return true;
  }

  private function _deleteContent()
  {
    if (!Configuration::deleteByName('MOD_SKELETON_NAME') ||
      !Configuration::deleteByName('MOD_SKELETON_COLOR'))
      return false;
    return true;

  }

Here’s what it does:

  • The install() method will call the parent install method. The parent method will handle all the dirty work for us. After that we can just call registerHook() to place our modules at different places. You can find the list of hooks in the module positions administration area. Look for the Technical name label like Technical name:displayLeftColumn.
  • The _createContent() allows us to create and initialise our configuration variables. I have created a separate method for that so that I don’t have to modify the install method on each and every method.
  • The uninstall() and _deleteContent() methods are the counterparts of the above two. Nothing too complicated here.

Please note that it’s very bad practice to put everything in the configuration table. If you have a lot of data, you should consider creating your own tables.

Step 4: Creating the hooks

The hooks are the main part of the Prestashop module API. There are hooks in every important area of Prestashop and our module can place itself over there. We will be placing our modules in 4 hooks:

  public function hookDisplayHeader()
  {
    $this->context->controller->addCSS($this->_path.'css/style.css', 'all');
    $this->context->controller->addJS($this->_path.'js/script.js', 'all');
  }

  public function hookDisplayLeftColumn()
  {
    $this->context->smarty->assign(array(
      'placement' => 'left',
    ));

    return $this->display(__FILE__, 'left.tpl');
  }

  public function hookDisplayRightColumn()
  {
    $this->context->smarty->assign(array(
      'placement' => 'right',
    ));

    return $this->display(__FILE__, 'right.tpl');
  }

  public function hookDisplayFooter()
  {
    $this->context->smarty->assign(array(
      'module_link' => $this->context->link->getModuleLink('skeleton', 'details'),
    ));

    return $this->display(__FILE__, 'footer.tpl');
  }

You will notice that your hook method will always be in the format “hook{NameOfHook}”. As for the code, here is an explanation of what it does:

  • The hookDisplayHeader() will inject code in the header of your pages. This is typically used to add CSS or Javascript code. And that’s exactly what we are doing here. Prestashop already has $this->context->controller->addCSS() and $this->context->controller->addJS() methods. You should use them because it will allow Prestashop to minify your CSS/JS if the option is activated. We will create our CSS/JS files in a moment.
  • The  hookDisplayLeftColumn() and hookDisplayRightColumn() are very similar in this example. They are assigning a variable to Smarty, the template engine and then are calling their corresponding template files (which we will create in a short while).
  • The last method hookDisplayFooter() is quite similar to the previous two except that it is using $this->context->link->getModuleLink() to create and assign a link to Smarty. It is actually generating a link to an independent page called details.

You will note the use of $this->context->link over the global variable $link. This allow us to write cleaner code, without polluting the namespace like we had to do in  version 1.4.

Now let’s create our template files. Open your Prestashop folder and create these files:

  • /modules/skeleton/css – This folder will contain all our CSS files.
  • /modules/skeleton/css/style.css
  • /modules/skeleton/js – All our JS files goes here.
  • /modules/skeleton/js/script.js
  • /modules/skeleton/views/templates/hook – This folder will contain all our hook templates.
  • /modules/skeleton/views/templates/hook/left.tpl
  • /modules/skeleton/views/templates/hook/right.tpl
  • /modules/skeleton/views/templates/hook/footer.tpl

All very simple. You might want to put some dummy content in these files so that you can see how they show up on the Prestashop front.

Step 5: Creating our independent page

Sometimes you may want to have a full page for your module. This is where the independent page comes in. This part is totally new in the 1.5 module API.

The first thing to do, is to create these folders/files:

  • /modules/skeleton/controllers/front/ – This will contain all our module controllers.
  • /modules/skeleton/controllers/front/details.php
  • /modules/skeleton/views/templates/front/ – This will contain the templates to our module controllers.
  • /modules/skeleton/views/templates/front/details.tpl

With that done, let’s have a look at our details.php file:

if (!defined('_PS_VERSION_'))
  exit;

class SkeletonDetailsModuleFrontController extends ModuleFrontController
{
  public function initContent()
  {
    parent::initContent();

    $this->context->smarty->assign(array(
      'skeleton_name' => Configuration::get('MOD_SKELETON_NAME'),
      'skeleton_color' => Configuration::get('MOD_SKELETON_COLOR'),
    ));

    $this->setTemplate('details.tpl');
  }
}

So basically we have a class that extends the ModuleFrontController class, which provides the basic functionalities that we’re after. It is very important to follow the naming here. It should be “{ModuleName}{ControllerName}ModuleFrontController”. The naming is quite tricky, go figure why they chose it.

There’s nothing complicated about the code itself. You create the initContent() method, call the parent method, do your logic and call the setTemplate() method.

Now, there are two ways of accessing this independent page:

  1. Without Friendly URL activated : http://www.site.com/index.php?fc=module&module=skeleton&controller=details
  2. With Friendly URL activated : http://www.site.com/module/skeleton/details

Quite slick, huh!

Step 6: Create the module configuration area

Most modules will need a configuration page, accessible from the administration area only. The Prestashop module API does a good job of providing that.

To create our configuration area, we will need to edit the skeleton.php file to add these 3 methods:

  public function getContent()
  {
    $message = '';

    if (Tools::isSubmit('submit_'.$this->name))
      $message = $this->_saveContent();

    $this->_displayContent($message);

    return $this->display(__FILE__, 'settings.tpl');
  }

  private function _saveContent()
  {
    $message = '';

    if (Configuration::updateValue('MOD_SKELETON_NAME', Tools::getValue('MOD_SKELETON_NAME')) &&
      Configuration::updateValue('MOD_SKELETON_COLOR', Tools::getValue('MOD_SKELETON_COLOR')))
      $message = $this->displayConfirmation($this->l('Your settings have been saved'));
    else
      $message = $this->displayError($this->l('There was an error while saving your settings'));

    return $message;
  }

  private function _displayContent($message)
  {
    $this->context->smarty->assign(array(
      'message' => $message,
      'MOD_SKELETON_NAME' => Configuration::get('MOD_SKELETON_NAME'),
      'MOD_SKELETON_COLOR' => Configuration::get('MOD_SKELETON_COLOR'),
    ));
  }

Here’s what they do:

  • The getContent() method tells Prestashop that our module needs a configuration page. The code inside, tells how the page should be constructed. The first thing we’re doing here is verifying the presence of a submit button called submit_skeleton. If it’s present, we call _saveContent().
  • The _saveContent() method will save our configuration data. You will note that it calls the displayConfirmation() and displayError() methods. These are Prestashop methods and they generate success/error messages (in HTML format) in the style of Prestashop’s administration area. This output is then passed to Smarty for display.
  • Ultimately our module will call _displayContent() and will return the settings.tpl template.

Which means we have to create the settings.tpl file like so:

  • /modules/skeleton/settings.tpl

And this is what the code will look like:

{$message}
<fieldset>
  <legend>Settings</legend>
  <form method="post">
    <p>
      <label for="MOD_SKELETON_NAME">Name:</label>
      <input id="MOD_SKELETON_NAME" name="MOD_SKELETON_NAME" type="text" value="{$MOD_SKELETON_NAME}" />
    </p>
    <p>
      <label for="MOD_SKELETON_COLOR">Color:</label>
      <input id="MOD_SKELETON_COLOR" name="MOD_SKELETON_COLOR" type="text" value="{$MOD_SKELETON_COLOR}" />
    </p>
    <p>
      <label>&nbsp;</label>
      <input id="submit_{$module_name}" name="submit_{$module_name}" type="submit" value="Save" class="button" />
    </p>
  </form>
</fieldset>

Here’s what you should note:

  • The {$message} Smarty variable is going to output any success/error messages. If it’s empty, nothing will be shown.
  • The HTML structure used here is on purpose. This will allow Prestashop to correctly style our form. Then, we can concentrate on the other parts of our module.
  • Notice the name of our submit button: submit_{$module_name}, which effectively equates to “submit_skeleton”. By not hardcoding the module’s name in our template, we are making sure that we have a nice base module to easily build up on.

Now there’s not much to do, except to go in your Prestashop modules administration area and install the module you just created.

Wrap-up

It took me a while to write this, so I hope you enjoyed it. If you want me to expand on any particular point, just post a comment and I’ll take care of it.

All the codes written here is available on Github. You are welcome to download it: https://github.com/jevin/Prestashop-Module-Skeleton

 

41 Comments to “How to create a Prestashop 1.5 module”

  1. M8ke says:

    Hi ! Awesome share ! As a prestashop newbie, that was very helpful…
    Any idea how to target our module to display only on homepage the cleanest way ? (not using the backoffice ‘exceptions’)

  2. Eduardo says:

    Hi, excellent tutorial. I’m trying to create an admin module, how can I adapt this code to achieve it?

  3. bilal says:

    Great tut.
    Can i adopt this to create a module that display additional product information on a product page? A block above or below the ‘description’ area.
    I am selling tires and wheels on http://www.shoptwm.com and I want to display additional product information from my custom database table.

    • Jevin says:

      Of course you can!

      Have a look at these hooks :
      – HOOK_EXTRA_RIGHT: To place content below the “Add to cart” button
      – HOOK_PRODUCT_TAB & HOOK_PRODUCT_TAB_CONTENT: To place an additional tab beside “More info” and “Comments”
      – HOOK_PRODUCT_FOOTER: To place a content after the “More info” block

      Hope that helps.

  4. Nice tutor, thanks dude it’s very usefull. one more, can I apply it with database, because I want to make a list. where I have to apply the script. Thank you.

  5. Luca says:

    Thank you very much. I already built modules, but the very important row here is

    return $this->display(__FILE__, ‘settings.tpl’);

    in getContent()! :)

    I didn’t know I could use a smarty template right in configuration page. Really really useful! Thank you!!!

  6. Teo says:

    Great tutorial. Could you give some sample code snippets that show how to use the hook actionValidateOrder to trigger some basic back office actions? I would like to automatically create a Cart Rule when a specific product is ordered. The functional use case is creating a gift certificate when a product, called “Gift Certificate” is ordered. Thanks again!

    • Jevin says:

      Hey Teo, the following code should get you started:

      public function hookActionValidateOrder()
      {
      $current_cart = $this->context->cart;

      $cart_rule = new CartRule();

      $cart_rule->name = ‘CART_’ . $current_cart->id;
      // You need to populate the other fields too

      $cart_rule->add();
      }

  7. bilal says:

    Hello ,

    can i access the smarty variable ‘reference’ on the module tpl file?

    I want to create a custom modules using this tut to connect to an external database and using the current loaded product ‘reference’ variable search and display product extra specification in a tabular format.

    anybody have an idea how to achieve this?

    Thanks,
    Bilal

    • Jevin says:

      Hey Bilal,

      You’ll have to do all your processing in the main module file (skeleton.php in our example), then send the results to the template (skeleton.tpl in our example).

      I’ll need to have a look at your code to be able to guide you further. Feel free to contact me privately via the “Contact” link on top.

  8. Jan says:

    Is it possible to insert the MOD_SKELETON_NAME value in the Home Text Editor (Text part) module and email template? And how would you do that?

    • Jevin says:

      It’s possible. Add the following lines to your skeleton.php file:

      public function hookDisplayHome()
      {
      return Configuration::get(‘MOD_SKELETON_NAME’);
      }

      This is barebones code, you might want to check the content of MOD_SKELETON_NAME first.

      Once the code is in skeleton.php file, simple position the module on the “displayHome” hook.

  9. cddin says:

    Hi, great tutorial. I’m able to create and view a custom page (http://www.site.com/index.php?fc=module&module=skeleton&controller=details)..

    but now I need to link to this custom page.. How to add a button in product page (example: “start customize”) and link to custom page? I’m guessing to hook my template to “HOOK_EXTRA_RIGHT” or “HOOK_PRODUCT_TAB”?

    and for sure I need to pass some parameter to that custom page link(example: id_product)

    What I try to do is, each product have a button to custom product skin.. and the skin editor created using flash n embed it in the custom page… Thanks in advance

  10. JigaR Mehta says:

    Found this really helpful. Thanks a tonne.

  11. JigaR Mehta says:

    Don’t know if I’m doing something wrong, but the same thing does not work for Admin Controllers. Can you help with a sample for Admin Controllers?

  12. Avinash says:

    Hai, i am a beginner using the prestashop..thanks for your tutorial..my doubt is that can we create a search filter module without altering the prestashop core code…??? Hope u answer…

    • Jevin says:

      You do not need to alter the Prestashop core for a search filter module.

      On a side note, altering the Prestashop core is a very amateur solution. A good developer will always find a solution where altering the core is not required. ;-)

  13. subhash says:

    HI, How to get the total amount in words in prestashop pdf invoice

  14. subhash says:

    Means if it is ‘$1024′ it should get ‘One Thousand Twenty Four’

  15. silviu says:

    Hi, thank you or this great share.
    I am thinking now how can I create a video player module. upload video rom backend to article description and this will be dispalyed in product description page. im thinking to jwplayer …

    • Jevin says:

      Unless you have a powerful (read expensive) hosting account, I wouldn’t advise you to host videos on your server. Instead setup a Youtube or Vimeo account, then embed the videos directly in the description of the product in the backoffice.

      Hope that helps.

      • Silviu says:

        Thank you for your response. But I want to be easy to use, something like browse for file and upload tem, not to embed and upload to ither sites and that all stuff. Need something user friendly

        • Jevin says:

          I see what you’re after. Unfortunately, that requires a fair amount of time to analyze and code. If you’re willing to contract the module creation to me, feel free to contact me via the link on top of the page.

  16. SC says:

    Hi Jevin,

    Thank you for your great tutorial. I want to create a PS 1.5 module to list out products of the same category in the left column whenever a category button is clicked on the top horizontal menu. I’ve tried to understand and examine files like categorycontroller.php, category.tpl and product-list.tpl but don’t know where to start with after reading your tutorials.

    Could you please give me some hints or directions. Thank you in advance.

    Regards,
    SC

    • Jevin says:

      Try to install my skeleton module. It will automatically place some dummy content in the left and right sidebars. This is a good starting point to make the modifications you’re after.

  17. Franklin says:

    Hi Jevin,

    I am creating a module in prestashop 1.5.4.1. I want to add a button in orders view page of the back office. Can you give you suggestions..

    • Jevin says:

      You need to use a hook called “displayAdminOrder”. The following function should get you started:

      public function hookDisplayAdminOrder()
      {
      return ‘BACKOFFICE BUTTON';
      }

  18. luigi says:

    hello, sorry for my English, I use google translator, and I hope to explain as best as possible.

    First of all thank you for writing this, I would like to ask a question.

    I must add a search field domains, my host sent me a css file to add, but I have no idea how to do. my site is powered by prestashop 1.5.4.1 and changed to 2 columns. Would you be so kind as to help me?

    thanks

  19. Marko says:

    I am interested in creating a plugin that would allow a “name your own price” function to a product in Prestashop. I would like that module to allow customers to change the price of the product from $1 up to $20, and have different products for certain price points.

    An Example :

    If they donate $1 – 4.99, they receive 1 bottle of wine.
    If they donate $5 – 9.99, they receive 2 bottles of wine.
    If they donate $10 – 20, they receive 4 bottles and a bottle opener.

    Jevin, do you know if this is possible?

  20. Padmaja says:

    Hi jevin,
    Thanks for giving this tutorial. I want to add content in center of home page instead of left and right of the page. please give me the solution. Thanks in advance.

  21. I would like to thank for this tutorial information you provided. stepwise instructions helped me to know about the concept.

  22. Franklin says:

    Hi

    I am crating a prestashop module. When the customer click “I confirm my order” in front end, i want the order details in my module. How do i get these details..!

    Prestshop version is 1.5.4.1

Leave a reply