Symfony Templates Cookbook: Difference between revisions
| (9 intermediate revisions by the same user not shown) | |||
| Line 9: | Line 9: | ||
`{% ... %}` encloses logic. | `{% ... %}` encloses logic. | ||
<syntaxhighlight lang=" | <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=" | <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=" | <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 69: | Line 73: | ||
{% endblock %} | {% endblock %} | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== Extending a block in a child template == | |||
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="twig"> | |||
{# app/Resources/views/base.html.twig #} | |||
{% block JavaScripts %} | |||
<script src="{{ asset('js/core.js') }}"></script> | |||
<script src="{{ asset('js/more.js') }}"></script> | |||
{% endblock %} | |||
</syntaxhighlight> | |||
<syntaxhighlight lang="twig"> | |||
{# app/Resources/views/child.html.twig #} | |||
{% block JavaScripts %} | |||
{{ parent() }} | |||
<script src="{{ asset('js/child.js') }}"></script> | |||
{% endblock %} | |||
</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`.
[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]
- ↑ Creating and Using Templates, Symfony documentation
- ↑ Template Inheritance and Layouts, Symfony documentation
- ↑ Including Other Templates, Symfony template documentation
- ↑ How To Write a Custom Twig Extension, Symfony documentation