Child pages
  • Creating a PrestaShop module

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

A PrestaShop module consists of :

...

  • One file for PrestaShop 1.4: logo.gif, 16*16 pixels.
  • One file for PrestaShop 1.5: logo.png, 32*32 pixels.

...

a main PHP file with as many other PHP file as needed, and all the image and TPL files necessary to display the information.

Let's see an example with PrestaShop's blockuserinfo module:

...

A module is made of a lot of files, all stored in a folder that bears the same name as the module, that folder being in turn stored in the /modules folder at the root of the main PrestaShop folder: /modules/name_of_the_module/.

/views/templates/cssSub-folder for CSS files used.If the module needs to work with PrestaShop 1.4, the CSS files should be placed in a /css folder at the root of the module's folder.
/views/templates/jsSub-folder for JavaScript files.If the module needs to work with PrestaShop 1.4, the JavaScript files should be placed in a /js folder at the root of the module's folder.
/views/templates/imgSub-folder for image files.If the module needs to work with PrestaShop 1.4, the image files should be placed in a /img folder at the root of the module's folder.

Default files and folders for a PrestaShop 1.5 module:

  • "Bootstrap" Main file: name_of_the_module.php. This PHP file should have the same name as its root folder.
  • Cache configuration file (generated by PrestaShop): config.xml
  • Module-specific controllers, all in the /controllers sub-folder
  • Class-overriding code, all in the /override sub-folder (automatic install/uninstall using copy or merge)
  • .
  • View files: JavaScript, Modelsimages, CSS files, template files, etc. From v1.5 onward, these files They can be placed in sub-foldersfolders within the module's main folder:
    • /views/css sub-folder  folder for CSS files. If the module needs to work with PrestaShop 1.4, the CSS files should be placed in a /css folder at the root of the module's folder.
    • /views/img folder for image files. If the module needs to work with PrestaShop 1.4, the images files should be placed in an /img folder at the root of the module's folder.
    • /views/js folder for JavaScript files. If the module needs to work with PrestaShop 1.4, the JS files should be placed in a /js folder at the root of the module's folder.
    • /views/templates/admin sub-folder for JavaScript filesfiles used by the module's admin controller.
    • /views/templates/front sub-folder for files used by the module's front controller.
    • /views/templates/hookshook sub-folder for files used by the module's hooks
  • 16x16 module logo: name_of_the_module.jpg (JPG format)
  • 32x32 module logo: name_of_the_module.png (PNG format)
    • .
  • Module-specific controllers, all in the /controllers sub-folder.
  • Class-overriding code, all in the /override sub-folder (automatic install/uninstall using copy or merge).
  • Two icon files representing this module in the back-office.
    • One file for PrestaShop 1.4: logo.gif or logo.jpg, 16*16 pixels.
    • One file for PrestaShop 1.5: logo.png, 32*32 pixels.
  • Translation files: fr.php, en.php, es.php, etc. From v1.5 onward, all these files can be placed in the /translations sub-folder.
  • Optional: in a /themes/[theme name]/modules folder, a folder with the same name as the module, containing .tpl and language files if necessary. This last folder is essential during modifications of existing module, so that you can adapt it without having to touch its original files. Notably, it enables you to handle the module's display in various ways, according to the current theme.

Creating a first module

Let's create a simple first module; this will enable us to better describe its structure. We will call it "My module".

...

This checks for the existence of a PrestaShop constant, and if it does not exist, it stops the module from loading. The sole purpose of this is to prevent alicious malicious visitors to load this file directly.

...

  • The need_instance flag indicates whether to load the module's class when displaying the "Modules" page in the back-office. If set at 0, the module will not be loaded, and therefore will spend less resources to generate the "Modules" page. If your module needs to display a warning message in the "Modules" page, then you must set this attribute to 1.
  • ps_versionversions_compliancy is new since PrestaShop 1.5. It clearly indicates which version of PrestaShop this module is compatible with. In the example above, we explicitly write that this module will only work with PrestaShop 1.5.x, and no other major version.
  • dependencies is new since PrestaShop 1.5. It clearly indicates that the module needs another module to be activated in order to work properly. Your module could rely on features brought by this other module, or it might simply be a helpful addition which would make no sense with that other mode disabled. Use the module's folder name as identifier. In the example, we require the activation of the Blockcart module.

...

There are many more, such as getInt() or hasContext(), but these four are the ones you will most use.
As you can see, this in a very useful and easy to use object, and you will certainly use in many situations. Most modules use it too for their own settings.

Info
titleMultistore

All of By default, all these methods pertain to the current context. In the default context, these methods apply to the store which is currently being using by the administrator at the time they are called.They have work within the confines of the current store context, whether PrestaShop is using the multistore feature or not.

However, it is possible to work outside of the current context and impact other known stores. This is done using three optional parameters, which are not presented in the list above:

  • id_lang: enables you to force the language with which you want to work.
  • id_shop_group: enables you to indicate the shop group of the target store.
  • id_shop: enables you to indicate the the id of the target store.

By default, these three parameters use the values of the current context, but you can use them to target other stores.It is therefore possible to override these three parameters when dealing with a multistore installation, in order to work outside of the current context

Note that it is not recommended to change the default values of these variables, even more so if the module you are writing is to be used on other stores than your own. They should only be used if the module is for your own store, and you know the id and shop group of all of your shops.

You are not limited to your own variables: PrestaShop stores all its own configuration settings in the ps_configuration table. There are literally hundreds of settings, and you can access them just as easily as you would access your own. For instance:

...

Note that when using updateValue(), the content of $value can be anything, be it a string, a number, a serialized PHP array or a JSON object. As long as you properly code the data handling function, anything goes. For instance, here is how to handle a PHP array  array using the Configuration object:

...

The Shop object is a new addition to PrestaShop 1.5, which helps you manage the multistore feature. We will not dive in the specifics here, but will simply present the two method methods that are used in this sample code:

...

Appearance in the "Modules" page

...

  • A front-end controller must be a class that extends the ModuleFrontController class.
  • That controller must have one method: initContent(), which calls the parent class' iniContentinitContent() method...
  • ...which then calls the setTemplate() method with our display.tpl file.

...

  1. Using the Configuration::get() method, we retrieve the value of the currently chosen language ("PS_LANG_DEFAULT"). For security reasons, we cast the variable into an integer using (int).
  2. In preparation for the generation of the form, we must build an array of the various titles, textfields and other form specifics.
    To that end, we create the $fields_form variable, which will contain a multidimensional array. Each of the arrays it features contains the detailed description of the tags the form must contain. From this variable, PrestaShop will render the HTML form as it is described.
    In this example, we define three tags (<legend>, <input> and <submit>) and their attributes using arrays. The format is quite easy to get: the legend and submit arrays simply contain the attributes to each tag, while the input contains as many <input> tags are needed, each being in turn an array which contains the necessary attributes. For instance:

    Code Block
    'input' => array(
        array(
            'type' => 'text',
            'label' => $this->l('Configuration value'),
            'name' => 'MYMODULE_NAME',
            'size' => 20,
            'required' => true
        ))

    ...generates the following HTML tags:

    Code Block
    <label>Configuration value </label>
    <div class="margin-form">
      <input id="MYMODULE_NAME" class="" type="text" size="20" value="my friend" name="MYMODULE_NAME">
      <sup>*</sup>
    <div class="clear"></div>

    As you can see, PrestaShop is quite clever, and generates all the code that is needed to obtain a useful form.
    Note that the value os of the main array is actually retrieved later in the form generation code.

  3. We then create an instance of the HelperForm class. This section of the code is explained in the next section of this chapter.
  4. Once the HelperForm settings are all in place, we generate the form based on the content of the $fields_form variable.

...

  • $helper->module: requires the instance of the module that will use the form.
  • $helper->name_controller: requires the name of the module.
  • $helper->token: requires a unique token for the module. getAdminTokenLite() helps us generate one.
  • $helper->currentIndex:
  • $helper->default_form_language: requires the default language for the shop.
  • $helper->allow_employee_form_lang: requires the default language for the shop.
  • $helper->title: requires the title for the the form.
  • $helper->show_toolbar: requires a boolean value – whether the toolbar is displayed or not.
  • $helper->toolbar_scroll: requires a boolean value – whether the toolbar is always visible when scrolling or not.
  • $helper->submit_action: requires the action attribute for the form's <submit> tag.
  • $helper->toolbar_btn: requires the buttons that are displayed in the toolbar. In our example, the "Save" button and the "Back" button.
  • $helper->fields_value[]: this is where we can define the value of the named tag.

...

Info
titleTranslating complex code

As we can see, the basis of template file translation is to enclose them in the {l s='The string' mod='name_of_the_module'}. The changes in display.tpl and in mymodule.tpl's link and title texts are thus easy to understand. But added a trickier block of code for the "Hello World!" string: an if/else/then clause, and a text variable. Let's explore this code:

Here is the original code:

Code Block
Hello, 
  {if isset($my_module_name) && $my_module_name}
    {$my_module_name}
  {else}
    World
  {/if}
!

As you can see, we need to get the "Hello World" string translatable, but also to cater for the fact that there is a variable. As explained in the "Translations in PrestaShop 1.5" chapter, variables are to be marked using sprintf() markers, such as %s or %1$s.

Making "Hello %s!" translatable words in easy: we just need to use this code:

Code Block
{l s='Hello %s!' sprintf=$my_module_name mod='mymodule'}

But in our case, we also need to make sure that the %s is replaced by "World" in case the "my_module_name" value does not exist... and we must make "World" translatable too. This can be achieved by using Smarty {capture} function, which collects the output of the template between the tags into a variable instead of displaying, so that we can use it later on. We are going to use it in order to replace the variable with the translated "World" if the variable is empty or absent, using a temporary variable. Here is the final code:

Code Block
{if !isset($my_module_name) || !$my_module_name}
  {capture name='my_module_tempvar'}{l s='World' mod='mymodule'}{/capture}
  {assign var='my_module_name' value=$smarty.capture.my_module_tempvar}
{/if}
{l s='Hello %s!' sprintf=$my_module_name mod='mymodule'}

...