Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Use the Twig namespaced syntax for all templates #8120

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 7, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 9 additions & 11 deletions 20 best_practices/templates.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,22 +30,20 @@ Template Locations
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 logical name
to refer to them (e.g. ``AcmeDemoBundle:Default:index.html.twig``).
``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/``
================================================= ==================================
``AcmeDemoBundle:Default:index.html.twig`` ``default/index.html.twig``
``::layout.html.twig`` ``layout.html.twig``
``AcmeDemoBundle::index.html.twig`` ``index.html.twig``
``AcmeDemoBundle:Default:subdir/index.html.twig`` ``default/subdir/index.html.twig``
``AcmeDemoBundle:Default/subdir:index.html.twig`` ``default/subdir/index.html.twig``
================================================= ==================================
============================================ ==================================
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
Expand Down
2 changes: 1 addition & 1 deletion 2 components/form.rst
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ is created from the form factory.
->add('dueDate', 'date')
->getForm();

return $this->render('AcmeTaskBundle:Default:new.html.twig', array(
return $this->render('@AcmeTask/Default/new.html.twig', array(
'form' => $form->createView(),
));
}
Expand Down
4 changes: 2 additions & 2 deletions 4 controller/service.rst
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ Symfony's base controller::
public function indexAction($name)
{
return $this->render(
'AppBundle:Hello:index.html.twig',
'@App/Hello/index.html.twig',
array('name' => $name)
);
}
Expand Down Expand Up @@ -213,7 +213,7 @@ service and use it directly::
public function indexAction($name)
{
return $this->templating->renderResponse(
'AppBundle:Hello:index.html.twig',
'@App/Hello/index.html.twig',
array('name' => $name)
);
}
Expand Down
6 changes: 3 additions & 3 deletions 6 form/direct_submit.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ submissions::
return $this->redirectToRoute('task_success');
}

return $this->render('AppBundle:Default:new.html.twig', array(
return $this->render('@App/Default/new.html.twig', array(
'form' => $form->createView(),
));
}
Expand Down Expand Up @@ -67,7 +67,7 @@ method, pass the submitted data directly to
}
}

return $this->render('AppBundle:Default:new.html.twig', array(
return $this->render('@App/Default/new.html.twig', array(
'form' => $form->createView(),
));
}
Expand Down Expand Up @@ -126,7 +126,7 @@ a convenient shortcut to the previous example::
}
}

return $this->render('AppBundle:Default:new.html.twig', array(
return $this->render('@App/Default/new.html.twig', array(
'form' => $form->createView(),
));
}
Expand Down
2 changes: 1 addition & 1 deletion 2 form/dynamic_form_modification.rst
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,7 @@ your application. Assume that you have a sport meetup creation controller::
}

return $this->render(
'AppBundle:Meetup:create.html.twig',
'@App/Meetup/create.html.twig',
array('form' => $form->createView())
);
}
Expand Down
2 changes: 1 addition & 1 deletion 2 form/form_collections.rst
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ In your controller, you'll now initialize a new instance of ``TaskType``::
// ... maybe do some form processing, like saving the Task and Tag objects
}

return $this->render('AppBundle:Task:new.html.twig', array(
return $this->render('@App/Task/new.html.twig', array(
'form' => $form->createView(),
));
}
Expand Down
4 changes: 2 additions & 2 deletions 4 form/form_customization.rst
Original file line number Diff line number Diff line change
Expand Up @@ -327,8 +327,8 @@ name of all the templates as an array using the ``with`` keyword:

{# ... #}

The templates can also be located in different bundles, use the functional name
to reference these templates, e.g. ``AcmeFormExtraBundle:form:fields.html.twig``.
The templates can also be located in different bundles, use the Twig namespaced
path to reference these templates, e.g. ``@AcmeFormExtra/form/fields.html.twig``.

Child Forms
...........
Expand Down
6 changes: 3 additions & 3 deletions 6 reference/configuration/twig.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ TwigBundle Configuration ("twig")
- bootstrap_3_horizontal_layout.html.twig

# Example:
- MyBundle::form.html.twig
- @App/form.html.twig

globals:

Expand Down Expand Up @@ -75,7 +75,7 @@ TwigBundle Configuration ("twig")
optimizations="true"
>
<twig:form-theme>form_div_layout.html.twig</twig:form-theme> <!-- Default -->
<twig:form-theme>MyBundle::form.html.twig</twig:form-theme>
<twig:form-theme>@App/form.html.twig</twig:form-theme>

<twig:global key="foo" id="bar" type="service" />
<twig:global key="pi">3.14</twig:global>
Expand All @@ -91,7 +91,7 @@ TwigBundle Configuration ("twig")
$container->loadFromExtension('twig', array(
'form_themes' => array(
'form_div_layout.html.twig', // Default
'MyBundle::form.html.twig',
'@App/form.html.twig',
),
'globals' => array(
'foo' => '@bar',
Expand Down
35 changes: 13 additions & 22 deletions 35 templating.rst
Original file line number Diff line number Diff line change
Expand Up @@ -270,11 +270,9 @@ A child template might look like this:

.. note::

The parent template is identified by a special string syntax
(``base.html.twig``). This path is relative to the ``app/Resources/views``
directory of the project. You could also use the logical name equivalent:
``::base.html.twig``. This naming convention is explained fully in
:ref:`template-naming-locations`.
The parent template is stored in ``app/Resources/views/``, so its path is
simply ``base.html.twig``. The template naming conventions are explained
fully in :ref:`template-naming-locations`.

The key to template inheritance is the ``{% extends %}`` tag. This tells
the templating engine to first evaluate the base template, which sets up
Expand Down Expand Up @@ -382,43 +380,36 @@ to render/extend ``app/Resources/views/base.html.twig``, you'll use the
Referencing Templates in a Bundle
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

*If* you need to refer to a template that lives in a bundle, Symfony uses a **bundle**:**directory**:**filename**
string syntax. This allows for several types of templates, each which lives in a
specific location:
*If* you need to refer to a template that lives in a bundle, Symfony uses the
Twig namespaced syntax (``@BundleName/directory/filename.html.twig``). This allows
for several types of templates, each which lives in a specific location:

* ``AcmeBlogBundle:Blog:index.html.twig``: This syntax is used to specify a
* ``@AcmeBlog/Blog/index.html.twig``: This syntax is used to specify a
template for a specific page. The three parts of the string, each separated
by a colon (``:``), mean the following:
by a slash (``/``), mean the following:

* ``AcmeBlogBundle``: (*bundle*) the template lives inside the AcmeBlogBundle
(e.g. ``src/Acme/BlogBundle``);
* ``@AcmeBlog``: is the bundle name without the ``Bundle`` suffix. This template
lives in the AcmeBlogBundle (e.g. ``src/Acme/BlogBundle``);

* ``Blog``: (*directory*) indicates that the template lives inside the
``Blog`` subdirectory of ``Resources/views``;
``Blog`` subdirectory of ``Resources/views/``;

* ``index.html.twig``: (*filename*) the actual name of the file is
``index.html.twig``.

Assuming that the AcmeBlogBundle lives at ``src/Acme/BlogBundle``, the
final path to the layout would be ``src/Acme/BlogBundle/Resources/views/Blog/index.html.twig``.

* ``AcmeBlogBundle::layout.html.twig``: This syntax refers to a base template
* ``@AcmeBlog/layout.html.twig``: This syntax refers to a base template
that's specific to the AcmeBlogBundle. Since the middle, "directory", portion
is missing (e.g. ``Blog``), the template lives at
``Resources/views/layout.html.twig`` inside AcmeBlogBundle. Yes, there are 2
colons in the middle of the string when the "controller" subdirectory part is
missing.
``Resources/views/layout.html.twig`` inside AcmeBlogBundle.

In the :doc:`/templating/overriding` section, you'll find out how each
template living inside the AcmeBlogBundle, for example, can be overridden
by placing a template of the same name in the ``app/Resources/AcmeBlogBundle/views/``
directory. This gives the power to override templates from any vendor bundle.

.. tip::

Hopefully the template naming syntax looks familiar - it's similar to
the naming convention used to refer to :ref:`controller-string-syntax`.

Template Suffix
~~~~~~~~~~~~~~~

Expand Down
29 changes: 12 additions & 17 deletions 29 templating/namespaced_paths.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,26 @@
How to Use and Register Namespaced Twig Paths
=============================================

Usually, when you refer to a template, you'll use the ``MyBundle:Subdir:filename.html.twig``
format (see :ref:`template-naming-locations`).

Twig also natively offers a feature called "namespaced paths", and support
is built-in automatically for all of your bundles.

Take the following paths as an example:

.. code-block:: twig

{% extends "AppBundle::layout.html.twig" %}
{{ include('AppBundle:Foo:bar.html.twig') }}

With namespaced paths, the following works as well:
Usually, when you refer to a template, you'll use the Twig namespaced paths, which
are automatically registered for your bundles:

.. code-block:: twig

{% extends "@App/layout.html.twig" %}
{{ include('@App/Foo/bar.html.twig') }}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't we use tis:

- {{ include('@App/Foo/bar.html.twig') }}
+ {% include '@App/Foo/bar.html.twig' %}

or is the current one the recommended?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we always use the function instead of the tag.


Both paths are valid and functional by default in Symfony.
.. note::

In the past, Symfony used a different syntax to refer to templates. This
format, which uses colons (``:``) to separate each template path section, is
less consistent and has worse performance than the Twig syntax. For reference
purposes, this is the equivalent notation of the previous example:

.. tip::
.. code-block:: twig

As an added bonus, the namespaced syntax is faster.
{# the following template syntax is no longer recommended #}
{% extends "AppBundle::layout.html.twig" %}
{{ include('AppBundle:Foo:bar.html.twig') }}

Registering your own Namespaces
-------------------------------
Expand Down
8 changes: 4 additions & 4 deletions 8 templating/overriding.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ following::
$blogs = ...;

$this->render(
'AcmeBlogBundle:Blog:index.html.twig',
'@AcmeBlog/Blog/index.html.twig',
array('blogs' => $blogs)
);
}

When the ``AcmeBlogBundle:Blog:index.html.twig`` is rendered, Symfony actually
looks in two different locations for the template:
When ``@AcmeBlog/Blog/index.html.twig`` is rendered, Symfony actually looks in
two different locations for the template:

#. ``app/Resources/AcmeBlogBundle/views/Blog/index.html.twig``
#. ``src/Acme/BlogBundle/Resources/views/Blog/index.html.twig``
Expand All @@ -44,7 +44,7 @@ to create it). You're now free to customize the template.

This logic also applies to base bundle templates. Suppose also that each
template in AcmeBlogBundle inherits from a base template called
``AcmeBlogBundle::layout.html.twig``. Just as before, Symfony will look in
``@AcmeBlog/layout.html.twig``. Just as before, Symfony will look in
the following two places for the template:

#. ``app/Resources/AcmeBlogBundle/views/layout.html.twig``
Expand Down
Morty Proxy This is a proxified and sanitized view of the page, visit original site.