Templates features

Custom Twig tags

Gimme allows you to fetch the Meta object you need in any place of your template. It supports single Meta objects (with gimme ) and collections of Meta objects (with gimmelist).

gimme

The tag gimme has one required parameter and one optional parameter:

  • (required) Meta object type (and name of variable available inside block), for example: article
  • (optional) Keword with and parameters for Meta Loader, for example: { param: "value" }
1
2
3
4
{% gimme article %}
    {# article Meta will be available under "article" variable inside block #}
    {{ article.title }}
{% endgimme %}

Meta Loaders sometimes require special parameters - like the article number, language of the article, user id, etc..

1
2
3
4
{% gimme article with { articleNumber: 1 } %}
    {# Meta Loader will use provided parameters to load article Meta #}
    {{ article.title }}
{% endgimme %}

gimmelist

The gimmelist tag has two required parameters and two optional parameters:

  • (required) Name of variable available inside block: article
  • (required) Keyword from and type of requested Metas in collection: from articles with filters passed to Meta Loader as extra parameters (start, limit, order)
  • (optional) Keyword with and parameters for Meta Loader, for example: with {foo: 'bar', param1: 'value1'}
  • (optional) Keyword without and parameters for Meta Loader, for example: without {source: 'AAP'}
  • (optional) Keyword if and expression used for results filtering
  • (optional) Keyword ignoreContext and optional array of selected meta to be ignored

Example of the required parameters:

1
2
3
{% gimmelist article from articles %}
    {{ article.title }}
{% endgimmelist %}

Example with ignoring selected context parameters:

1
2
{% gimmelist article from articles ignoreContext ['route', 'article'] %}
...

Example with ignoring whole context

1
2
{% gimmelist article from articles ignoreContext [] %}
...

Or even without empty array

1
2
{% gimmelist article from articles ignoreContext %}
...

Example with filtering articles by metadata:

1
2
3
{% gimmelist article from articles with {metadata: {byline: "Karen Ruhiger", located: "Sydney"}} %}
    {{ article.title }}
{% endgimmelist %}

The above example will list all articles by metadata which contain byline equals to Karen Ruhiger AND located equals to Sydney.

To list articles by authors you can also do:

1
2
3
4
{% gimmelist article from articles with {author: ["Karen Ruhiger", "Doe"]} %}
    {{ article.title }}
    Author(s): {% for author in article.authors %}<img src="{{ url(author.avatar) }}" />{{ author.name }} ({{ author.role }}) {{ author.biography }} - {{ author.jobTitle.name }},{% endfor %}
{% endgimmelist %}

It will then list all articles written by Karen Ruhiger AND Doe.

To list articles from the Forbes source but without an AAP source you can also do:

1
2
3
{% gimmelist article from articles with {source: ["Forbes"]} without {source: ["AAP"]} %}
    {% for source in article.sources %} {{ source.name }} {% endfor %}
{% endgimmelist %}

It will then list all articles with source Forbes and without AAP.

Listing article’s custom fields:

1
2
3
4
{% gimmelist article from articles %}
    {{ article.title }}
    {{ article.extra['my-custom-field'] }}
{% endgimmelist %}

Example with usage of all parameters:

1
2
3
4
5
6
7
{% gimmelist article from articles|start(0)|limit(10)|order('id', 'desc')
    with {foo: 'bar', param1: 'value1'}
    contextIgnore ['route', 'article']
    if article.title == "New Article 1"
%}
    {{ article.title }}
{% endgimmelist %}

How to work with gimmelist pagination?

gimmelist is based on Twig for tag, like in Twig there is loop variable available. In addition to default loop properties there is also totalLength. It’s filled by loader with number of total elements in storage which are matching criteria. Thanks to this addition we can build real pagination.

TemplateEngine Bundle provides simple default pagination template file: pagination.html.twig.

Note

You can override that template with SWPTemplatesSystemBundle/views/pagination.html.twig file in Your theme. Or You can use own file used for pagination rendering.

Here is commented example of pagination:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
{# Setup list and pagination parameters #}
{% set itemsPerPage, currentPage = 1, app.request.get('page', 1) %}
{% set start = (currentPage / itemsPerPage) - 1 %}

{# List all articles from route '/news' and limit them to `itemsPerPage` value starting from `start` value #}
{% gimmelist article from articles|start(start)|limit(itemsPerPage) with {'route': '/news'} %}

    <li><a href="{{ url(article) }}">{{ article.title }} </a></li>

    {# Render pagination only at end of list #}
    {% if loop.last  %}
        {#
            Use provided by default pagination template

            Parameters:
            * currentFilters (array) : associative array that contains the current route-arguments
            * currentPage (int) : the current page you are in
            * paginationPath (Meta|string) : the route name (or supported by router Meta object) to use for links
            * lastPage (int) : represents the total number of existing pages
            * showAlwaysFirstAndLast (bool) : Always show first and last link (just disabled)
        #}
        {% include '@SWPTemplatesSystem/pagination.html.twig' with {
            currentFilters: {}|merge(app.request.query.all()),
            currentPage: currentPage,
            paginationPath: gimme.route,
            lastPage: (loop.totalLength/itemsPerPage)|round(1, 'ceil'),
            showAlwaysFirstAndLast: true
        } only %}
    {% endif %}
{% endgimmelist %}

For referrence, see original pagination.html.twig template (if you want to customize it and use instead of default one):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
{#
  Source: http://dev.dbl-a.com/symfony-2-0/symfony2-and-twig-pagination/
  Updated by: Simon Schick <simonsimcity@gmail.com>

  Parameters:
    * currentFilters (array) : associative array that contains the current route-arguments
    * currentPage (int) : the current page you are in
    * paginationPath (string) : the route name to use for links
    * showAlwaysFirstAndLast (bool) : Always show first and last link (just disabled)
    * lastPage (int) : represents the total number of existing pages
#}
{% spaceless %}
    {% if lastPage > 1 %}

        {# the number of first and last pages to be displayed #}
        {% set extremePagesLimit = 3 %}

        {# the number of pages that are displayed around the active page #}
        {% set nearbyPagesLimit = 2 %}

        <nav class="pagination">
            <div class="numbers">
                <ul>
                    {% if currentPage > 1 %}
                        <li><a href="{{ path(paginationPath, currentFilters|merge({page: currentPage-1})) }}">Previous</a></li>

                        {% for i in range(1, extremePagesLimit) if ( i < currentPage - nearbyPagesLimit ) %}
                            <li><a href="{{ path(paginationPath, currentFilters|merge({page: i})) }}">{{ i }}</a></li>
                        {% endfor %}

                        {% if extremePagesLimit + 1 < currentPage - nearbyPagesLimit %}
                            <span class="sep-dots">...</span>
                        {% endif %}

                        {% for i in range(currentPage-nearbyPagesLimit, currentPage-1) if ( i > 0 ) %}
                            <li><a href="{{ path(paginationPath, currentFilters|merge({page: i})) }}">{{ i }}</a></li>
                        {% endfor %}
                    {% elseif showAlwaysFirstAndLast %}
                        <span class="disabled">Previous</span>
                    {% endif %}

                    <li class="current"><a href="{{ path(paginationPath, currentFilters|merge({ page: currentPage })) }}">{{ currentPage }}</a></li>

                    {% if currentPage < lastPage %}
                        {% for i in range(currentPage+1, currentPage + nearbyPagesLimit) if ( i <= lastPage ) %}
                            <li><a href="{{ path(paginationPath, currentFilters|merge({page: i})) }}">{{ i }}</a></li>
                        {% endfor %}

                        {% if  (lastPage - extremePagesLimit) > (currentPage + nearbyPagesLimit) %}
                            <li><span class="sep-dots">...</span></li>
                        {% endif %}

                        {% for i in range(lastPage - extremePagesLimit+1, lastPage) if ( i > currentPage + nearbyPagesLimit ) %}
                            <li><a href="{{ path(paginationPath, currentFilters|merge({page: i})) }}">{{ i }}</a></li>
                        {% endfor %}

                        <li><a href="{{ path(paginationPath, currentFilters|merge({page: currentPage+1})) }}">Next</a></li>
                    {% elseif showAlwaysFirstAndLast %}
                        <li><span class="disabled">Next</span></li>
                    {% endif %}
                </ul>
            </div>
        </nav>
    {% endif %}
{% endspaceless %}

How to work with Meta objects

On the template level, every variable in Context and fetched by gimme and gimmelist is a representation of Meta objects.

dump

1
{{ dump(article) }}

print

1
{{ article }}

If the meta configuration has the to_string property then the value of this property will be printed, otherwise it will be represented as JSON.

access property

1
2
{{ article.title }}
{{ article['title']}}

generate url

1
2
{{ url(article) }}    // absolute url
{{ path(article) }}   // relative path

Here’s an example using gimmelist:

1
2
3
{% gimmelist article from articles %}
    <li><a href="{{ url(article) }}">{{ article.title }} </a></li>
{% endgimmelist %}

Stringy twig extensions

We have extended the twig syntax, adding a number of functions for working with strings from a php library. A list of the functions together with a description of each, and of how they are to be invoked in PHP can be found here: https://github.com/danielstjules/Stringy#instance-methods

To call one of these functions in twig, if it returns a boolean, it is available as a twig function. So, for example, the function contains() can be called like this in twig:

1
2
{% set string_var = 'contains' %}
{% if contains(string_var, 'tain') %}string_var{% endif %} // will render contains

Any php function which returns a string is available in twig as a filter. So, for example, the function between() can be called like this in twig:

1
2
{% set string_var = 'Beginning' %}
{{ string_var|between('Be', 'ning') }} // will render gin

And the function camelize(), which doesn’t require any parameters, can simply be called like this:

1
2
{% set string_var = 'Beginning' %}
{{ string_var|camelize }} // will render bEGINNING

Redirects

We provide two functions which can be used for redirects:

redirect

1
2
{# redirect(route, code, parameters) #}
{{ redirect('homepage', 301, [] }}
  • route param can be string with ruute name or route meta object (article meta object will work also).
  • code is a redirection HTTP code (301 by default)
  • parameters - if route requires any it can be provided here

notFound

1
{{ notFound('Error message visible for reader' }}

notFound function will redirect user to 404 error page with provided message (it’s usefull when in your custom route, loader can’t find requested data).