PrestaShop Smarty vs Twig: What's Changing in Templates

385 views

The Template Engine Transition in PrestaShop

PrestaShop is undergoing one of its most significant architectural changes in recent history — the migration from Smarty to Twig as its primary template engine. This transition, which began with PrestaShop 1.7 and reached a major milestone with PrestaShop 9.0 (released June 2025), affects every developer, theme designer, and module creator working with the platform.

Understanding this change is essential whether you are maintaining an existing store, planning an upgrade, or developing new modules and themes. This guide covers what has changed, what is still changing, and how to prepare your PrestaShop projects for the Twig era.

What Are Smarty and Twig?

Smarty - The Legacy Engine

Smarty is a PHP template engine that has powered PrestaShop since its early days. It separates PHP business logic from HTML presentation, allowing designers to create template files (.tpl) without needing deep PHP knowledge. Smarty has been reliable and well-understood by the PrestaShop community for over a decade.

Key characteristics of Smarty -

  • Template files use the .tpl extension
  • Variables are accessed using curly braces and dollar signs - {$variable}
  • Modifiers use pipe syntax - {$variable|escape:'html'}
  • Blocks use paired tags - {block name='content'}{/block}
  • Template inheritance through {extends file='parent.tpl'}

Twig - The Modern Engine

Twig is the template engine built by SensioLabs, the same company behind the Symfony framework. Since PrestaShop has been progressively adopting Symfony components, moving to Twig is a natural alignment. Twig is the standard template engine in the Symfony ecosystem and is used by millions of applications worldwide.

Key characteristics of Twig -

  • Template files use the .html.twig extension
  • Variables use double curly braces - {{ variable }}
  • Filters use pipe syntax - {{ variable|escape('html') }}
  • Blocks use paired tags - {% block content %}{% endblock %}
  • Template inheritance through {% extends 'parent.html.twig' %}

Syntax Comparison - Side by Side

The syntax differences between Smarty and Twig are relatively minor, which makes the learning curve manageable for experienced PrestaShop developers.

Outputting Variables

FeatureSmartyTwig
Simple variable{$product.name}{{ product.name }}
Array access{$products[0].name}{{ products[0].name }}
Object method{$product->getName()}{{ product.getName() }}
Default value{$var|default:'N/A'}{{ var|default('N/A') }}

Control Structures

<!-- Smarty: if/else -->
{if $product.active}
  <span class="badge badge-success">Active</span>
{elseif $product.pending}
  <span class="badge badge-warning">Pending</span>
{else}
  <span class="badge badge-danger">Inactive</span>
{/if}

<!-- Twig: if/else -->
{% if product.active %}
  <span class="badge badge-success">Active</span>
{% elseif product.pending %}
  <span class="badge badge-warning">Pending</span>
{% else %}
  <span class="badge badge-danger">Inactive</span>
{% endif %}

Loops

<!-- Smarty: foreach loop -->
{foreach $products as $product}
  <div class="product">
    <h3>{$product.name}</h3>
    <p>{$product.price|number_format:2:',':'.'}</p>
  </div>
{foreachelse}
  <p>No products found.</p>
{/foreach}

<!-- Twig: for loop -->
{% for product in products %}
  <div class="product">
    <h3>{{ product.name }}</h3>
    <p>{{ product.price|number_format(2, ',', '.') }}</p>
  </div>
{% else %}
  <p>No products found.</p>
{% endfor %}

Template Inheritance

<!-- Smarty: child template -->
{extends file='parent.tpl'}
{block name='content'}
  <h1>{$page_title}</h1>
  {$HOOK_PRODUCT_FOOTER}
{/block}

<!-- Twig: child template -->
{% extends 'parent.html.twig' %}
{% block content %}
  <h1>{{ page_title }}</h1>
  {{ renderhooksarray('displayProductFooter') }}
{% endblock %}

Including Templates

<!-- Smarty -->
{include file='./product-card.tpl' product=$product}

<!-- Twig -->
{% include 'catalog/product-card.html.twig' with {'product': product} %}

<!-- Twig (modern embed approach) -->
{{ include('catalog/product-card.html.twig', {product: product}) }}

What Has Already Changed - The Timeline

PrestaShop 1.7 (2016)

The migration began. The back office started adopting Symfony controllers for new pages, with those pages using Twig templates. Legacy pages continued using Smarty through the AdminController system. The front office remained entirely Smarty-based.

PrestaShop 8.x (2022-2024)

More back office pages were migrated to Symfony and Twig. Key admin pages including Products, Orders, and Customers received Twig-based rewrites. However, many admin pages still used Smarty through the legacy AdminController framework. The front office (themes) continued using Smarty exclusively.

PrestaShop 9.0 (June 2025)

A major milestone. The back office is now fully migrated to Symfony controllers and Twig templates. All administrative pages use Twig. However, Smarty is still present in the codebase because -

  • The front office (themes) still primarily uses Smarty
  • Many third-party modules still use Smarty templates for their front-end output
  • Module admin pages using legacy AdminControllers still rely on Smarty

Impact on Store Owners

If You Are Running PrestaShop 1.7 or 8.x

Nothing changes immediately. Your current themes and modules will continue working as they do today. However, you should begin planning for the eventual upgrade to PrestaShop 9.0 and beyond.

If You Are Upgrading to PrestaShop 9.0

The most significant impact is on modules that modify back office pages. Modules that use Smarty-based admin templates or hook into legacy AdminControllers may need updates to work with the new Twig-based admin interface. Contact your module developers to verify compatibility before upgrading.

Your front office theme should continue working if it is a standard Smarty-based theme designed for PrestaShop 8.x, as the front office Smarty rendering is still supported.

For the Long Term

The direction is clear - PrestaShop will eventually move entirely to Twig for both front and back office. New theme frameworks will likely be Twig-based. If you are investing in a new custom theme, consider working with a developer who understands both Smarty and Twig to future-proof your investment.

Impact on Module Developers

Back Office Module Templates

If your module adds admin pages, you now have two approaches depending on your target PrestaShop versions -

For PrestaShop 8.x compatibility (legacy approach) -

// Legacy AdminController using Smarty
class AdminMyModuleController extends ModuleAdminController
{
    public function renderList()
    {
        $this->context->smarty->assign([
            'my_data' => $this->getMyData(),
        ]);
        return $this->display(__FILE__, 'views/templates/admin/list.tpl');
    }
}

For PrestaShop 9.0+ (modern approach) -

// Symfony Controller using Twig
class MyModuleAdminController extends FrameworkBundleAdminController
{
    public function listAction(): Response
    {
        return $this->render('@Modules/mymodule/views/templates/admin/list.html.twig', [
            'my_data' => $this->getMyData(),
        ]);
    }
}

Front Office Module Templates

For now, front office module templates continue using Smarty. You can still create .tpl files in your module's views/templates/front/ and views/templates/hook/ directories. This will not change in the near term.

Supporting Multiple PrestaShop Versions

If your module needs to work across PrestaShop 8.x and 9.x, you will need to include both Smarty and Twig templates and detect the PrestaShop version at runtime -

// Detect which template engine to use
if (version_compare(_PS_VERSION_, '9.0.0', '>=')) {
    // Use Twig template
    return $this->render('@Modules/mymodule/admin/config.html.twig', $params);
} else {
    // Use Smarty template
    $this->context->smarty->assign($params);
    return $this->display($this->file, 'views/templates/admin/config.tpl');
}

Impact on Theme Developers

Current State

PrestaShop front office themes currently use Smarty templates. The default theme (classic in 1.7/8.x, hummingbird in later versions) is built with Smarty .tpl files. Theme overrides in themes/your-theme/modules/ use Smarty files.

Future Direction

PrestaShop is working toward Twig-based front office themes. When this transition completes -

  • Theme files will use .html.twig instead of .tpl
  • Theme template structure will align more closely with Symfony conventions
  • Template variables will be passed through Twig context rather than Smarty assigns
  • Theme inheritance and overrides will use Twig's block system

Preparing Themes for Migration

If you are developing a new theme today, you can prepare by -

  • Keeping your template logic simple and avoiding complex Smarty plugins
  • Using standard Smarty features rather than custom modifiers
  • Organizing templates with clear inheritance and reusable blocks
  • Documenting which variables each template expects

Advantages of Twig Over Smarty

Better Security

Twig auto-escapes output by default, meaning you have to explicitly mark content as safe using the |raw filter. This significantly reduces the risk of XSS (Cross-Site Scripting) vulnerabilities caused by forgetting to escape user input.

<!-- Twig: auto-escaped by default -->
{{ user_input }}  <!-- HTML entities escaped automatically -->
{{ trusted_html|raw }}  <!-- Explicitly marked as safe -->

<!-- Smarty: manual escaping needed -->
{$user_input|escape:'html'}  <!-- Must remember to escape -->
{$user_input}  <!-- DANGEROUS: no escaping -->

Symfony Integration

Since PrestaShop uses Symfony, Twig integrates natively with Symfony's routing, form rendering, translation system, and security components. This eliminates the "glue code" needed to connect Smarty templates with Symfony services.

Better Error Messages

Twig provides clear, developer-friendly error messages that point to exact line numbers and explain what went wrong. Smarty errors can sometimes be cryptic, especially when dealing with nested includes and variable scope issues.

Modern Tooling

Twig has excellent IDE support with syntax highlighting, auto-completion, and linting available in PhpStorm, VS Code, and other editors. The Symfony Debug Toolbar also provides template rendering insights that are not available with Smarty.

Sandboxed Execution

Twig supports sandboxed template execution, allowing you to safely render user-provided templates without risking PHP code execution. This is particularly important for marketplace environments where third-party code is involved.

Common Migration Patterns

Translating Strings

<!-- Smarty -->
{l s='Add to cart' mod='mymodule'}

<!-- Twig -->
{{ 'Add to cart'|trans({}, 'Modules.Mymodule.Shop') }}

Hook Rendering

<!-- Smarty -->
{hook h='displayProductButtons'}

<!-- Twig -->
{{ renderhook('displayProductButtons') }}

Asset URLs

<!-- Smarty -->
<link rel="stylesheet" href="{$module_dir}views/css/style.css">
<img src="{$img_dir}logo.png" alt="Logo">

<!-- Twig -->
<link rel="stylesheet" href="{{ asset('modules/mymodule/views/css/style.css') }}">
<img src="{{ asset('img/logo.png') }}" alt="Logo">

Form Rendering

<!-- Smarty: manual form HTML -->
<form action="{$action_url}" method="post">
  <input type="text" name="name" value="{$config.name|escape:'html'}">
  <button type="submit">{l s='Save'}</button>
</form>

<!-- Twig: Symfony form rendering -->
{{ form_start(form) }}
  {{ form_row(form.name) }}
  <button type="submit" class="btn btn-primary">
    {{ 'Save'|trans({}, 'Admin.Actions') }}
  </button>
{{ form_end(form) }}

Back Office Template Overrides in PrestaShop 9

In PrestaShop 9.0, modules can override back office Twig templates by recreating the same directory structure. For example, to override the product catalog page template -

# Original template location
# src/PrestaShopBundle/Resources/views/Admin/Product/CatalogPage/catalog.html.twig

# Module override location
modules/mymodule/views/PrestaShop/Admin/Product/CatalogPage/catalog.html.twig

You can extend the original template using the @PrestaShopCore namespace -

{# modules/mymodule/views/PrestaShop/Admin/Product/CatalogPage/catalog.html.twig #}
{% extends '@PrestaShopCore/Admin/Product/CatalogPage/catalog.html.twig' %}

{% block product_catalog_tools %}
  {{ parent() }}
  <div class="my-custom-toolbar">
    <!-- Additional toolbar content -->
  </div>
{% endblock %}

Practical Advice for Store Owners

Do Not Panic

The migration is gradual. Smarty is not being removed overnight. Your existing store, theme, and modules will continue to work. Plan your migration at a comfortable pace.

Check Module Compatibility Before Upgrading

Before upgrading to PrestaShop 9.0, verify that every module you use is compatible. Check with module developers and look for updated versions. This is the single most important step in a successful upgrade.

Consider Professional Help for Complex Stores

If your store has extensive customizations, custom theme modifications, or many third-party modules, consider hiring a PrestaShop developer experienced with both Smarty and Twig to plan and execute your migration.

Test Everything in a Staging Environment

Never upgrade your production store directly. Set up a staging environment, perform the upgrade there, test every page and function, and only go live once everything works correctly.

Was this answer helpful?

Still have questions?

Can't find what you're looking for? Send us your question and we'll get back to you quickly.

Loading...
Back to top