Prestashop Quick Primer

Understanding Prestashop structure for Designers


Prestashop, like all PHP scripts will load the website using an index.php file. If you prestashop store is located at mystore.com, when a user enters the URL http://www.mystore.com, the webserver will load the index page. It is the information on the index page that determines what happens.

To understand what is going when you load your prestashop shop, we therefore need to understand what the index file does.

INDEX.PHP

The prestashop index.php page (v1.1.0.5) includes the following code

<?php
include(dirname(__FILE__).'/config/config.inc.php');
include(dirname(__FILE__).'/header.php');

$smarty->assign('HOOK_HOME', Module::hookExec('home'));
$smarty->display(_PS_THEME_DIR_.'index.tpl');

include(dirname(__FILE__).'/footer.php');

?>


Firstly the index.php includes the config.inc.php file located in the config directory. This file is to do with our configuration and other settings, config.inc.php will check if everything is installed and defines our base themes and directory defaults and paths, order statuses and other settings. But we not going to concern ourselves with any further explanations in this designers guide right now, beyond knowing it’s included.

However, as a designer, you may need to track errors from time to time so there is one thing I want to make you aware of right now. If you open /config/config.inc.php you will see a line as follows at the top of the file;

@ini_set('display_errors', 'off');
If you change this to
@ini_set('display_errors', 'on');


You have now enabled error reporting. Just remember to turn this back to off in a live installation.

Next, after our config is loaded the index.php file is told to include the header.php file from our root install. Root install means from directly within our prestashop site, not contained in any sub-directories.

This header.php file includes the following code

<?php

// P3P Policies (http://www.w3.org/TR/2002/REC-P3P-20020416/#compact_policies)
header('P3P: CP="IDC DSP COR CURa ADMa OUR IND PHY ONL COM STA"');

require_once(dirname(__FILE__).'/init.php');

/* CSS */
$css_files[_THEME_CSS_DIR_.'global.css'] = 'all';

/* Hooks are voluntary out the initialize array (need those variables already assigned) */
$smarty->assign(array(
    'HOOK_HEADER' => Module::hookExec('header'),
    'HOOK_LEFT_COLUMN' => Module::hookExec('leftColumn'),
    'HOOK_TOP' => Module::hookExec('top'),
    'static_token' => Tools::getToken(false),
    'token' => Tools::getToken(),
    'priceDisplayPrecision' => _PS_PRICE_DISPLAY_PRECISION_,
    'content_only' => intval(Tools::getValue('content_only'))
));

if(isset($css_files) AND !empty($css_files)) $smarty->assign('css_files', $css_files);
if(isset($js_files) AND !empty($js_files)) $smarty->assign('js_files', $js_files);

/* Display a maintenance page if shop is closed */
if (isset($maintenance) AND (!isset($_SERVER['REMOTE_ADDR']) OR $_SERVER['REMOTE_ADDR'] != Configuration::get('PS_MAINTENANCE_IP')))
{
    header('HTTP/1.1 503 temporarily overloaded');
    $smarty->display(_PS_THEME_DIR_.'maintenance.tpl');
    exit;
}

$smarty->display(_PS_THEME_DIR_.'header.tpl');

?>


Next we have

$smarty->assign('HOOK_HOME', Module::hookExec('home'));

This will assign a hook (we will get to hooks in a  while, but basically hooks allow the website administrator to specify where they want certain modules to be displayed within your Prestashop shop).

$smarty->display(_PS_THEME_DIR_.'index.tpl');

This line is saying display the index.tpl file in this position, from the default theme directory. (You define the theme to use in your backoffice>> preferances>>appearance)

And finally we have footer.php

include(dirname(__FILE__).'/footer.php');


so this line of php is saying include the file footer.php from our directory. The footer.php file has the following code

<?php

if (isset($smarty))
{
    $smarty->assign(array(
        'HOOK_RIGHT_COLUMN' => Module::hookExec('rightColumn'),
        'HOOK_FOOTER' => Module::hookExec('footer'),
        'content_only' => intval(Tools::getValue('content_only'))));
    $smarty->display(_PS_THEME_DIR_.'footer.tpl');
}

?>


(Each file that is included may itself, include PHP requests to include other files of course. But we are only concerned with understanding the principals of what is going on to give you a understanding of how Prestashop works).

Although we now have our configuration setting, Hooks and various php files included, you will notice we don’t yet have any HTML. This is where our template (tpl) comes in. Tpl files are the template files that include our HTML and our Smarty code. (We talk more about Smarty in a bit). These tpl files mostly reside in your themes directory but also exist in modules as each module someone writes will need its own template file(tpl) too.

If you now look at the header.php file, we can see the following code is being included with this.

$css_files[_THEME_CSS_DIR_.'global.css'] = 'all';
if(isset($css_files) AND !empty($css_files)) $smarty->assign('css_files', $css_files);
if(isset($js_files) AND !empty($js_files)) $smarty->assign('js_files', $js_files);

$smarty->display(_PS_THEME_DIR_.'maintenance.tpl');  -  Will display a maintenance page called maintenance.tpl if your shop is closed */

$smarty->display(_PS_THEME_DIR_.'header.tpl');


So our global.css is being called from our theme directory and our required CSS and JavaScript files are included. The actual display HTML (which represents part of our webpage layout) comes from the header.tpl file

Our index.php also calls index.tpl and footer.php also calls (or requests) footer.tpl. Again these tpl files determine our sites html layout and exist within out themes folder.

If it sounds  a bit complex so far, stick with me, it will get easier,

Ok, so breaking this down, our index.php file includes header.php, index.tpl and footer.tpl from our themes directory. Then header.php is calling header.tpl and footer.php is calling footer.tpl.

Thus our main HTML is derived from these three template.tpl files.

Now lets open header.tpl, index.tpl and footer.tpl. This should make a lot more sense to Web designers

Header.tpl

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="{$lang_iso}">
    <head>
        <base href="{$protocol}{$smarty.server.HTTP_HOST|escape:'htmlall':'UTF-8'}{$base_dir}" />
        <title>{$meta_title|escape:'htmlall':'UTF-8'}</title>
{if isset($meta_description) AND $meta_description}
        <meta name="description" content="{$meta_description|escape:htmlall:'UTF-8'}" />
{/if}
{if isset($meta_keywords) AND $meta_keywords}
        <meta name="keywords" content="{$meta_keywords|escape:htmlall:'UTF-8'}" />
{/if}
        <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8" />
        <meta name="generator" content="PrestaShop" />
        <meta name="robots" content="{if isset($nobots)}no{/if}index,follow" />
        <link rel="icon" type="image/vnd.microsoft.icon" href="{$img_ps_dir}favicon.ico" />
        <link rel="shortcut icon" type="image/x-icon" href="{$img_ps_dir}favicon.ico" />
{if isset($css_files)}
    {foreach from=$css_files key=css_uri item=media}
    <link href="{$css_uri}" rel="stylesheet" type="text/css" media="{$media}" />
    {/foreach}
{/if}
        <script type="text/javascript" src="{$base_dir}js/tools.js"></script>
        <script type="text/javascript">
            var baseDir = '{$base_dir}';
            var static_token = '{$static_token}';
            var token = '{$token}';
            var priceDisplayPrecision = {$priceDisplayPrecision*$currency->decimals};
        </script>
        <script type="text/javascript" src="{$base_dir}js/jquery/jquery-1.2.6.pack.js"></script>
        <script type="text/javascript" src="{$base_dir}js/jquery/jquery.easing.1.3.js"></script>
{if isset($js_files)}
    {foreach from=$js_files item=js_uri}
    <script type="text/javascript" src="{$js_uri}"></script>
    {/foreach}
{/if}
        {$HOOK_HEADER}
    </head>
   
    <body {if $page_name}id="{$page_name|escape:'htmlall':'UTF-8'}"{/if}>
    {if !$content_only}
        <div id="page">

            <!-- Header -->
            <div>
                <h1 id="logo"><a href="{$base_dir}" title="{$shop_name|escape:'htmlall':'UTF-8'}"><img src="{$img_ps_dir}logo.jpg" alt="{$shop_name|escape:'htmlall':'UTF-8'}" /></a></h1>
                <div id="header">
                    {$HOOK_TOP}
                </div>
            </div>

            <!-- Left -->
            <div id="left_column" class="column">
                {$HOOK_LEFT_COLUMN}
            </div>

            <!-- Center -->
            <div id="center_column">
    {/if}

Index.tpl

{$HOOK_HOME}

Footer.tpl


    {if !$content_only}
            </div>

<!-- Right -->
            <div id="right_column" class="column">
                {$HOOK_RIGHT_COLUMN}
            </div>

<!-- Footer -->
            <div id="footer">{$HOOK_FOOTER}</div>
        </div>
    {/if}
    </body>
</html>


Now let’s View the source for our homepage (With all modules un-installed and a small amount of JavaScript removed from footer so we can focus on the rendered HTML, derived from our key tpl files), here is what we now have

!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
  <head>
    <base href="http://127.0.0.1/prestashop/" />
    <title>Prestashop demo</title>
    <meta name="description" content="Shop powered by PrestaShop" />
    <meta name="keywords" content="shop, prestashop" />
    <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8" />
    <meta name="generator" content="PrestaShop" />
    <meta name="robots" content="index,follow" />
    <link rel="icon" type="image/vnd.microsoft.icon" href="/prestashop/img/favicon.ico" />
    <link rel="shortcut icon" type="image/x-icon" href="/prestashop/img/favicon.ico" />
    <link href="/prestashop/themes/commotion/css/global.css" rel="stylesheet" type="text/css" media="all" />
        <script type="text/javascript" src="/prestashop/js/tools.js"></script>
        <script type="text/javascript">
            var baseDir = '/prestashop/';
            var static_token = '8d6a4d79d983512d770333775a7d8d24';
            var token = '521aacf70fb52a35b4f94e01366c4c64';
            var priceDisplayPrecision = 2;
        </script>
        <script type="text/javascript" src="/prestashop/js/jquery/jquery-1.2.6.pack.js"></script>
        <script type="text/javascript" src="/prestashop/js/jquery/jquery.easing.1.3.js"></script>
  </head>
    <body id="index">
            <div id="page">

            <!-- Header -->
            <div>
                <h1 id="logo"><a href="/prestashop/" title="Prestashop demo"><img src="/prestashop/img/logo.jpg" alt="Prestashop demo" /></a></h1>
                <div id="header">
                   
                </div>
            </div>

            <!-- Left -->
            <div id="left_column" class="column">
               
            </div>

            <!-- Center -->
            <div id="center_column">
                     </div>

<!-- Right -->
            <div id="right_column" class="column">
               
            </div>

<!-- Footer -->
            <div id="footer">
        </div>
        </div>
        </body>
</html>


So basically to recap. Index.php loads first, this requests other php pages that are defined in this php file and those php pages then call the tpl files which are together rendered as a webpage.

Notice that index.tpl has just one line: {$HOOK_HOME}. This is beacuse the index file will only show modules assigned to the homepage. Our category and product pages  will display other modules.

Also, as you will discover, we have a different body ID on each of these different pages, index.tpl, category.tpl, product.tpl for example so we have the flexibility to style pages differently using just our global.css rules to target the body ID. Where does this come from? If you look at the header.tpl file you will see a line

<body {if $page_name}id="{$page_name|escape:'htmlall':'UTF-8'}"{/if}> and it is this code that gets the page name. So category.tpl will have the <body id="category">

Please be aware that many Prestashop sections are incomplete and our of date as this site is no longer maintained

PRESTASHOP GUIDES

prestashop admin guide prestashop designers guide

CATEGORIES

Prestashop Designers Guide