Symfony Templates Cookbook: Difference between revisions

From Littledamien Wiki
Jump to navigation Jump to search
No edit summary
 
(8 intermediate revisions by the same user not shown)
Line 9: Line 9:
`{% ... %}` encloses logic.  
`{% ... %}` encloses logic.  


<syntaxhighlight lang="php">
<syntaxhighlight lang="twig">
         <ul id="navigation">
         <ul id="navigation">
             {% for item in navigation %}
             {% for item in navigation %}
Line 18: Line 18:


`{# ... #}` encloses comments.<ref>[http://symfony.com/doc/current/book/templating.html Creating and Using Templates], Symfony documentation</ref>
`{# ... #}` encloses comments.<ref>[http://symfony.com/doc/current/book/templating.html Creating and Using Templates], Symfony documentation</ref>
== Links ==
Linking to controllers: `<nowiki>{{ path("controler_name") }}</nowiki>`, where `"controler_name"` is defined with the `name` attribute of a `@Route`.


== Headers and footers ==
== Headers and footers ==
Line 29: Line 33:
Base template:
Base template:


<syntaxhighlight lang="html4strict" highlight="6,10-15,19">
<syntaxhighlight lang="twig" highlight="6,10-15,19">
{# app/Resources/views/base.html.twig #}
{# app/Resources/views/base.html.twig #}
<!DOCTYPE html>
<!DOCTYPE html>
Line 56: Line 60:
Child template:
Child template:


<syntaxhighlight lang="html4strict" highlight="2,4,6">
<syntaxhighlight lang="twig" highlight="2,4,6">
{# app/Resources/views/Blog/index.html.twig #}
{# app/Resources/views/Blog/index.html.twig #}
{% extends 'base.html.twig' %}
{% extends 'base.html.twig' %}
Line 74: Line 78:
For example, a base template defines a core set of JavaScript and stylesheets for the site. A child template adds one stylesheet for a specific page on the site.
For example, a base template defines a core set of JavaScript and stylesheets for the site. A child template adds one stylesheet for a specific page on the site.


<syntaxhighlight lang="html4strict">
<syntaxhighlight lang="twig">
{# app/Resources/views/base.html.twig #}
{# app/Resources/views/base.html.twig #}
{% block JavaScripts %}
{% block JavaScripts %}
Line 83: Line 87:




<syntaxhighlight lang="html4strict">
<syntaxhighlight lang="twig">
{# app/Resources/views/child.html.twig #}
{# app/Resources/views/child.html.twig #}
{% block JavaScripts %}
{% block JavaScripts %}
Line 90: Line 94:
{% endblock %}
{% endblock %}
</syntaxhighlight>
</syntaxhighlight>
== Conditional blocks ==
Render the paragraph tags only if there is content to be displayed:
<syntaxhighlight lang="twig">
{% block teaser %}
{% if teaser_text|trim is defined %}
<p>{{ teaser_text }}</p>
{% endif %}
{% endblock %}
</syntaxhighlight>
<span style="font:red;">''NB There may be better ways of accomplishing this, but this method does work.</span>
== Including other templates ==
Templates are included using the `<nowiki>{{ include() }}</nowiki>` function.<ref>[http://symfony.com/doc/current/book/templating.html#including-other-templates Including Other Templates], Symfony template documentation</ref>
<syntaxhighlight lang="twig">
{{ include('Article/articleDetails.html.twig', { 'article': article }) }}
</syntaxhighlight>
== Creating custom Twig filters and functions ==
Create a class that holds the methods defining the filters and/or functions, then register that class as a Symfony service.<ref>[http://symfony.com/doc/current/cookbook/templating/twig_extension.html How To Write a Custom Twig Extension], Symfony documentation</ref>
The extension class:
<syntaxhighlight lang="php">
// src/AppBundle/Twig/AppExtension.php
namespace AppBundle\Twig;
class AppExtension extends \Twig_Extension
{
    public function getFilters()
    {
        return array(
            new \Twig_SimpleFilter('price', array($this, 'priceFilter')),
        );
    }
    public function priceFilter($number, $decimals = 0, $decPoint = '.', $thousandsSep = ',')
    {
        $price = number_format($number, $decimals, $decPoint, $thousandsSep);
        $price = '$'.$price;
        return $price;
    }
    public function getName()
    {
        return 'app_extension';
    }
}
</syntaxhighlight>
* `getName()` should return a unique identifier.
* Filters are registered in `getFilters()`.
* Functions are registered in `getFunctions()`.
Registering the class as a service:
<syntaxhighlight lang="yaml">
# app/config/services.yml
services:
    app.twig_extension:
        class: AppBundle\Twig\AppExtension
        public: false
        tags:
            - { name: twig.extension }
</syntaxhighlight>
Now any filter or function registered in the extension class can be used in Twig templates, e.g. `{{ product.total|price }}`.


== Notes ==
== Notes ==
<references/>
<references/>

Latest revision as of 22:37, 28 February 2015


Template tags[edit]

`{{ ... }} enclose variables. Object properties are referenced with dot notation: {{obj.prop}}. Functions can be put in tags too.

Filters can be applied with the pipe character: {{ title|upper }}.

{% ... %}` encloses logic.

<ul id="navigation">
            {% for item in navigation %}
                <li><a href="{{ item.href }}">{{ item.caption }}</a></li>
            {% endfor %}
        </ul>

{# ... #} encloses comments.[1]

Links[edit]

Linking to controllers: `{{ path("controler_name") }}, where "controler_name" is defined with the name attribute of a @Route`.

Headers and footers[edit]

Headers and footers are located in base templates.

Child templates extend the base template to use the header and footers.[2]

A base template can contain default content. If the child template doesn't define a block that exists in the parent template, and the parent template contains default content in the block, the content from the parent template will be used.

Base template:

{# app/Resources/views/base.html.twig #}
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>{% block title %}Test Application{% endblock %}</title>
    </head>
    <body>
        <div id="sidebar">
            {% block sidebar %}
                <ul>
                      <li><a href="/">Home</a></li>
                      <li><a href="/blog">Blog</a></li>
                </ul>
            {% endblock %}
        </div>

        <div id="content">
            {% block body %}{% endblock %}
        </div>
    </body>
</html>

Child template:

{# app/Resources/views/Blog/index.html.twig #}
{% extends 'base.html.twig' %}

{% block title %}My cool blog posts{% endblock %}

{% block body %}
    {% for entry in blog_entries %}
        <h2>{{ entry.title }}</h2>
        <p>{{ entry.body }}</p>
    {% endfor %}
{% endblock %}

Extending a block in a child template[edit]

For example, a base template defines a core set of JavaScript and stylesheets for the site. A child template adds one stylesheet for a specific page on the site.

{# app/Resources/views/base.html.twig #}
{% block JavaScripts %}
<script src="{{ asset('js/core.js') }}"></script>
<script src="{{ asset('js/more.js') }}"></script>
{% endblock %}


{# app/Resources/views/child.html.twig #}
{% block JavaScripts %}
{{ parent() }}
<script src="{{ asset('js/child.js') }}"></script>
{% endblock %}

Conditional blocks[edit]

Render the paragraph tags only if there is content to be displayed:

{% block teaser %}
	{% if teaser_text|trim is defined %}
	<p>{{ teaser_text }}</p>
	{% endif %}
{% endblock %}

NB There may be better ways of accomplishing this, but this method does work.

Including other templates[edit]

Templates are included using the `{{ include() }}` function.[3]

{{ include('Article/articleDetails.html.twig', { 'article': article }) }}

Creating custom Twig filters and functions[edit]

Create a class that holds the methods defining the filters and/or functions, then register that class as a Symfony service.[4]

The extension class:

// src/AppBundle/Twig/AppExtension.php
namespace AppBundle\Twig;

class AppExtension extends \Twig_Extension
{
    public function getFilters()
    {
        return array(
            new \Twig_SimpleFilter('price', array($this, 'priceFilter')),
        );
    }

    public function priceFilter($number, $decimals = 0, $decPoint = '.', $thousandsSep = ',')
    {
        $price = number_format($number, $decimals, $decPoint, $thousandsSep);
        $price = '$'.$price;

        return $price;
    }

    public function getName()
    {
        return 'app_extension';
    }
}
  • getName() should return a unique identifier.
  • Filters are registered in getFilters().
  • Functions are registered in getFunctions().

Registering the class as a service:

# app/config/services.yml
services:
    app.twig_extension:
        class: AppBundle\Twig\AppExtension
        public: false
        tags:
            - { name: twig.extension }

Now any filter or function registered in the extension class can be used in Twig templates, e.g. Template:Product.total.

Notes[edit]

  1. Creating and Using Templates, Symfony documentation
  2. Template Inheritance and Layouts, Symfony documentation
  3. Including Other Templates, Symfony template documentation
  4. How To Write a Custom Twig Extension, Symfony documentation