Templates
Warning: You are browsing the documentation for Symfony 2.x, which is no longer maintained.
Read the updated version of this page for Symfony 7.1 (the current stable version).
When PHP was created 20 years ago, developers loved its simplicity and how well it blended HTML and dynamic code. But as time passed, other template languages - like Twig - were created to make templating even better.
Best Practice
Use Twig templating format for your templates.
Generally speaking, PHP templates are much more verbose than Twig templates because they lack native support for lots of modern features needed by templates, like inheritance, automatic escaping and named arguments for filters and functions.
Twig is the default templating format in Symfony and has the largest community support of all non-PHP template engines (it's used in high profile projects such as Drupal 8).
In addition, Twig is the only template format with guaranteed support in Symfony 3.0. As a matter of fact, PHP may be removed from the officially supported template engines.
Template Locations
Best Practice
Store all your application's templates in app/Resources/views/
directory.
Traditionally, Symfony developers stored the application templates in the
Resources/views/
directory of each bundle. Then they used the Twig namespaced
path to refer to them (e.g. @AcmeDemo/Default/index.html.twig
).
But for the templates used in your application, it's much more convenient
to store them in the app/Resources/views/
directory. For starters, this
drastically simplifies their logical names:
Templates Stored inside Bundles | Templates Stored in app/ |
---|---|
@AcmeDemo/index.html.twig |
index.html.twig |
@AcmeDemo/Default/index.html.twig |
default/index.html.twig |
@AcmeDemo/Default/subdir/index.html.twig |
default/subdir/index.html.twig |
Another advantage is that centralizing your templates simplifies the work of your designers. They don't need to look for templates in lots of directories scattered through lots of bundles.
Best Practice
Use lowercased snake_case for directory and template names.
Best Practice
Use a prefixed underscore for partial templates in template names.
You often want to reuse template code using the include
function to avoid
redundant code. To determine those partials easily in the filesystem you should
prefix partials and any other template without HTML body or extends
tag
with a single underscore.
Twig Extensions
Best Practice
Define your Twig extensions in the AppBundle/Twig/
directory and
configure them using the app/config/services.yml
file.
Our application needs a custom md2html
Twig filter so that we can transform
the Markdown contents of each post into HTML.
To do this, first, install the excellent Parsedown Markdown parser as a new dependency of the project:
1
$ composer require erusev/parsedown
Then, create a new Markdown
service that will be used later by the Twig
extension. The service definition only requires the path to the class:
1 2 3 4 5
# app/config/services.yml
services:
# ...
app.markdown:
class: AppBundle\Utils\Markdown
And the Markdown
class just needs to define one single method to transform
Markdown content into HTML:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
namespace AppBundle\Utils;
class Markdown
{
private $parser;
public function __construct()
{
$this->parser = new \Parsedown();
}
public function toHtml($text)
{
return $this->parser->text($text);
}
}
Next, create a new Twig extension and define a new filter called md2html
using the Twig\TwigFilter
class. Inject the newly defined markdown
service in the constructor of the Twig extension:
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
namespace AppBundle\Twig;
use AppBundle\Utils\Markdown;
use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
class AppExtension extends AbstractExtension
{
private $parser;
public function __construct(Markdown $parser)
{
$this->parser = $parser;
}
public function getFilters()
{
return array(
new TwigFilter(
'md2html',
array($this, 'markdownToHtml'),
array('is_safe' => array('html'), 'pre_escape' => 'html')
),
);
}
public function markdownToHtml($content)
{
return $this->parser->toHtml($content);
}
public function getName()
{
return 'app_extension';
}
}
Lastly define a new service to enable this Twig extension in the app (the service name is irrelevant because you never use it in your own code):
1 2 3 4 5 6 7 8
# app/config/services.yml
services:
app.twig.app_extension:
class: AppBundle\Twig\AppExtension
arguments: ['@app.markdown']
public: false
tags:
- { name: twig.extension }
Next: Forms