This module use Twig template engine as parser for Thelia and replace Smarty., (*1)
This module is not stable and is still in development. See the RoadMap if you want to know which features are missing, (*2)
You can only install this module with composer :, (*3)
$ composer require thelia/twig-module:dev-master
It is required to enable this module with the cli tools and then disable TheliaSmarty module :, (*4)
$ php Thelia module:refresh $ php Thelia module:activate TheliaTwig $ php Thelia module:deactivate TheliaSmarty
Template files must be suffixed by .twig
, for example index.html.twig
, (*5)
The template structure is the same as the actual structure, so you can referer to the actual documentation, (*6)
You can test the module with this module : https://github.com/bibich/TheliaTwigTest, (*7)
loop feature is a Twig tag, you have to use it like a block. All loop's parameters use literals syntax and are the same as the acutal parameters.
The tag start with loop
and finish with endloop
, (*8)
example :, (*9)
<ul> {% loop {type:"category", name:"cat", limit:"2"} %} <li>{{ ID }} : {{ TITLE }} <ul> {% loop {type:"product", name:"prod", category: ID} %} <li>Title : {{ TITLE }} </li> {% endloop %} </ul> </li> {% endloop %} </ul>
Conditional loops are implemented. As for Smarty a ifloop
can wrap a loop
and can be used after the related loop.
elseloop
must be used after the related loop
, (*10)
{% ifloop {rel:"cat"} %} <p>Before categories</p> <ul> {% loop {type:"category", name:"cat", limit:"2"} %} <li>{{ ID }} : {{ TITLE }} <ul> {% loop {type:"product", name:"prod", category: ID} %} <li>Title : {{ TITLE }} </li> {% endloop %} </ul> </li> {% endloop %} </ul> <p>After categories</p> {% endifloop %} {% elseloop {rel:"cat"} %} <p>there is no category</p> {% endelseloop %}
Paginated loop works exactly like paginated loop for Smarty, just the syntax change. See the official documentation for all parameters : http://doc.thelia.net/en/documentation/loop/index.html#page-loop, (*11)
Syntax example :, (*12)
Products Loop, (*13)
Pagination, (*14)
url is a function. It generates an absolute url for a given path or file., (*15)
url($path, $parameters = array(), $current = false, $file = null, $noAmp = false, $target = null)
parameters :, (*16)
Parameters | Description | example |
---|---|---|
path | The value of the path parameter is the route path you want to get as an URL | url("/product/") |
file | The value of the file parameter is the absolute path (from /web) of a real file, that will be served by your web server, and not processed by Thelia | url(null,[], false, "file.pdf") |
parameters | paremeters added to the query string | url("/product" ,{arg1:"val1", arg2:"val2"}) |
current | generate absolute URL grom the current URL | url(null ,[], true) |
noAmp | escape all & as & that may be present in the generated URL. |
url("/product" ,[], false, null, true) |
target | Add an anchor to the URL | url("/product" ,[], false, null, false, "cart") |
Complete example :, (*17)
<p> <a href="{{ url("/product/", {id: 2, arg1: "val1"}) }}">my link</a> </p>
generated link : http://domain.tld?id=2&arg1=val1, (*18)
same as url
function. This function just add a token paremeter in the url to prevent CSRF security issue., (*19)
example :, (*20)
<a href="{{ url_token("/product/", {id: 2, arg1: "val1"}) }}">my tokenized link</a>
generated link : http://domain.tld?id=2&arg1=val1&_token=UniqueToken, (*21)
return the current url, (*22)
current_url()
example :, (*23)
<a href="{{ current_url() }}">current link</a>
return the previous url saved in session, (*24)
previous_url
example :, (*25)
<a href="{{ previous_url() }}">previous link</a>
return the homepage url, (*26)
index_url()
example :, (*27)
<a href="{{ index_url() }}">index link</a>
default_domain is a tag for defining the default translation domain. If defined you don't need to specify it when you want to translation a string in the current template., (*28)
Usage :, (*29)
{% default_domain "fo.default" %}
tag for defining a locale and don't use the locale stored in session., (*30)
Usage :, (*31)
{% default_locale "fr_FR" %}
function for string translation, (*32)
intl($id, $parameters = [], $domain = null, $locale = null)
parameters :, (*33)
Parameters | Description | Example |
---|---|---|
id | the string to translate | intl('secure payment') |
parameters | variable use if a placeholder is used in the string to translate |
intl('secure payment %payment', {'%payment' => 'atos'}) => secure payment atos |
domain | message domain, will override domain defined with tag default_domain
|
{{ intl('secure payment', [], 'front') }} |
locale | specific locale to use for this translation. Will override locale defined with tag default_locale and the locale defined in session |
{{ intl('Secure payment', [], null, 'en_US') }} |
Complete example :, (*34)
{% default_domain "fo.default" %} {% default_locale "fr_FR" %} <p> translation : {{ intl('Secure payment', [], null, 'en_US') }} <br> translation 2 : {{ intl('Secure payment') }} <br> translation 3 : {{ intl('Sorry, an error occurred: %error', {'%error': 'foo'}, 'front') }} <br> </p>
tag checking if a user has access granted., (*35)
example :, (*36)
{% auth {role: "CUSTOMER", login_tpl:"login"} %}
Parameters :, (*37)
Parameters | Description |
---|---|
role | In Thelia 2, a user can only have one of these two roles: ADMIN and/or CUSTOMER |
resource | if a user can access to a specific resource. See : http://doc.thelia.net/en/documentation/templates/security.html#resource |
module | Name of the module(s) which the user must have access |
access | access mode : CREATE, VIEW, UPDATE, DELETE |
login_tpl | This argument is the name of the view name (the login page is "login"). If the user is not granted and this argument is defined, it redirects to this view. |
This tag checks if the customer's cart is empty, and redirects to the route "cart.view" if it is., (*38)
{% check_cart_not_empty %}
Check if the delivery module and address are valid, redirects to the route "order.delivery" if not., (*39)
{% check_valid_delivery %}
All data access function allow to access to a specific property of an entity. For some of them through an id present in the query string, for others through data saved in session, (*40)
Provides access to the current logged administrator attributes using the accessors., (*41)
<p> admin firstname : {{ admin('firstname') }} </p>
Provides access to an attribute of the current brand (brand_id parameter in the query string). If the product_id is in the query string, the brand function will find the brand linked to the product., (*42)
<p> brand title : {{ brand('title') }} </p>
list of implemented parameters :, (*43)
example :, (*44)
<p> number of products : {{ cart('count_product') }} </p>
Provides access to an attribute of the current category (category_id parameter is the query string). If the product_id is in the query string, the default category linked to this product is used., (*45)
<p> Category title : {{ category('title') }} </p>
return the value of a wanted configuration key. Default as second parameter if the key does not exists., (*46)
<p> default front office template : {{ config('active-front-template', 'default') }} </p>
Provides access to an attribute of the current content (content_id in the query string)., (*47)
<p> content title : {{ content('title') }} </p>
Provides access to an attribute for the default country, (*48)
<p> iso alpha2 code : {{ country('isoalpha2') }} </p>
Provides access to an attribute of the current currency (saved in session), (*49)
<p> currency symbol : {{ currency('symbol') }} </p>
Provides access to an attribute of the logged customer, (*50)
<p> customer first name : {{ customer('firstname') }} </p>
Provides access to an attribute of the current folder (folder_id in the query string). If the content_id parameter is in the query string, the default linked folder will be used., (*51)
<p>
folder title : {{ folder('title') }}
</p>
, (*52)
Provides access to an attribute of the current lang saved in session, (*53)
<p> locale : {{ lang('locale') }} </p>
Provides access to an attribute of the current order, (*54)
list of implemented parameters :, (*55)
example :, (*56)
<p> discount amount : {{ order('discount') }} </p>
Provides access to an attribute of the current product (product_id parameter in query string), (*57)
<p> product title : {{ product('title') }} </p>
retrieves the postage amount of the current cart if it exists., (*58)
Thelia uses the following rules to select the country :, (*59)
Inside the postage
block this variables are defined :, (*60)
{% postage %} postage : {{ postage ~ currency('symbol') }} {% endpostage %}
return date in expected format, (*61)
available parameters :, (*62)
DateTime
object (mandatory if timestamp is not present){% set myDate = date() %} {# format the date in datetime format for the current locale #} {{ format_date({date: myDate}) }} {# format the date in date format for the current locale #} {{ format_date({date: myDate, output:"date"}) }} {# format the date with a specific format (with the default locale on your system) #} {{ format_date({date: myDate, format:"Y-m-d H:i:s"}) }} {# format the date with a specific format with a specific locale #} {{ format_date({date: myDate, format:"D l F j", locale:"en_US"}) }} {{ format_date({date: myDate, format:"l F j", locale:"fr_FR"}) }} {# using a timestamp instead of a date #} {{ format_date({timestamp: myDate|date('U'), output:"datetime"}) }}
return numbers in expected format, (*63)
available parameters :, (*64)
{# specific format #} {{ format_number({number:"1246.12", decimals:"1", dec_point:",", thousands_sep:" "}) }} {# format for the current locale #} {{ format_number({number:"1246.12"}) }}
return money in expected format, (*65)
available parameters :, (*66)
{# will output "1 246,1 €" #} {{ format_number({number:"1246.12", decimals:"1", dec_point:",", thousands_sep:" ", symbol:"€"}) }}
Test if message exists for the given type., (*67)
available parameters :, (*68)
{% if has_flash('test') %} {# do something #} {% endif %}
Get all messages or messages for the given type. After the call of the function flash messages are deleted., (*69)
available parameter :, (*70)
{% if has_flash('notice') %}{% for message in flash('notice') %} {{ message }}{% endif %} {% for type, messages in flash() %}
{% endfor %}{% for message in messages %} {{ message }}{% endfor %}
{% endfor %}
hook
tagsThe tag hook
allows you to get the content related to a specific hook
specified by its name., (*71)
available parameters :, (*72)
{% hook {name: "hook_code", var1: "value1", var2: "value2", ... } %}
hookblock
and forhook
tagsThe tag hookblock
allows you to get the content related to a specific hook
specified by its name. The content is not injected directly, but has to be
manipulated by a forhook
tag., (*73)
available parameters :, (*74)
hookblock
eventThe tag forhook
iterates on the results of a hookblock
tag. You should
set the rel
attribute to establish the link. You can use the forhook
multiple
times., (*75)
{% hookblock {name: "hookblock_code", fields: "id,title, content", var1: "value1", ... } %} {% forhook {rel: 'hookblock_code'} %} <div id="{{ id }}"> <h2>{{ title }}</h2> <p>{{ content|raw }}</p> </div> {% endforhook %}
ifhook
and elsehook
tagsThese tags will test if hook
or hookblock
are empty or not., (*76)
{% ifhook {rel:"main.content-bottom"} %} {# displayed if main.content-bottom is not empty #}
{% hook {name: "main.content-bottom"} %} <hr class="space"> {% endifhook %} {% elsehook {rel:"main.content-bottom"} %} {# displayed if main.content-bottom is empty #}Back to top, (*77)
{% endelsehook %}
The tag thelia.parser.add_extension
allows you to add your own twig extension., (*78)
example :, (*79)
<service id="thelia.parser.loop_extension" class="TheliaTwig\Template\Extension\Loop"> <argument type="service" id="thelia.parser.loop_handler" /> <tag name="thelia.parser.add_extension" /> </service>