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

Updated the docs for the new way to render partials/ESI/HInclude #2121

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 3 commits into from
Jan 13, 2013
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
made changes to take into account the new usage of the different cont…
…ent rendering strategies
  • Loading branch information
fabpot committed Jan 12, 2013
commit c2d0b9991cb4b256bcdb893b3a7878ca1d3a9604
9 changes: 0 additions & 9 deletions 9 book/_security-2012-6431.rst.inc

This file was deleted.

111 changes: 64 additions & 47 deletions 111 book/http_cache.rst
Original file line number Diff line number Diff line change
Expand Up @@ -881,58 +881,37 @@ matter), Symfony2 uses the standard ``render`` helper to configure ESI tags:

.. code-block:: jinja

{% render url('latest_news', { 'max': 5 }), {'standalone': true} %}
{# you can use a controller reference #}
{{ render_esi(controller('...:news', { 'max': 5 })) }}

{# ... or a URL #}
{{ render_esi(url('latest_news', { 'max': 5 })) }}

.. code-block:: php

<?php echo $view['actions']->render(
new ControllerReference('...:news', array('max' => 5)),
array('strategy' => 'esi'))
?>

<?php echo $view['actions']->render(
$view['router']->generate('latest_news', array('max' => 5), true),
array('standalone' => true)
array('strategy' => 'esi')
) ?>

.. include:: /book/_security-2012-6431.rst.inc

The ``render`` tag takes the absolute url to the embedded action. This means
that you need to define a new route to the controller that you're embedding:

.. code-block:: yaml

# app/config/routing.yml
latest_news:
pattern: /esi/latest-news/{max}
defaults: { _controller: AcmeNewsBundle:News:news }
requirements: { max: \d+ }

.. caution::

Unless you want this URL to be accessible to the outside world, you
should use Symfony's firewall to secure it (by allowing access to your
reverse proxy's IP range). See the :ref:`Securing by IP<book-security-securing-ip>`
section of the :doc:`Security Chapter </book/security>` for more information
on how to do this.

.. tip::
By using the ``esi`` rendering strategy (via the ``render_esi`` Twig
function), you tell Symfony2 that the action should be rendered as an ESI tag.
You might be wondering why you would want to use a helper instead of just
writing the ESI tag yourself. That's because using a helper makes your
application work even if there is no gateway cache installed.

The best practice is to mount all your ESI urls on a single prefix (e.g.
``/esi``) of your choice. This has two main advantages. First, it eases
the management of ESI urls as you can easily identify the routes used for ESI.
Second, it eases security management since securing all urls starting
with the same prefix is easier than securing each individual url. See
the above note for more details on securing ESI URLs.

By setting ``standalone`` to ``true`` in the ``render`` Twig tag, you tell
Symfony2 that the action should be rendered as an ESI tag. You might be
wondering why you would want to use a helper instead of just writing the ESI tag
yourself. That's because using a helper makes your application work even if
there is no gateway cache installed.

When standalone is ``false`` (the default), Symfony2 merges the included page
content within the main one before sending the response to the client. But
when standalone is ``true``, *and* if Symfony2 detects that it's talking
to a gateway cache that supports ESI, it generates an ESI include tag. But
if there is no gateway cache or if it does not support ESI, Symfony2 will
just merge the included page content within the main one as it would have
done were standalone set to ``false``.
When using the default ``render`` function (or setting the strategy to
``default``), Symfony2 merges the included page content within the main one
before sending the response to the client. But when using ``esi`` strategy,
*and* if Symfony2 detects that it's talking to a gateway cache that supports
ESI, it generates an ESI include tag. But if there is no gateway cache or if
it does not support ESI, Symfony2 will just merge the included page content
within the main one as it would have done if you had used ``render``.

.. note::

Expand All @@ -947,14 +926,52 @@ of the master page.

public function newsAction($max)
{
// ...
// ...

$response->setSharedMaxAge(60);
$response->setSharedMaxAge(60);
}

With ESI, the full page cache will be valid for 600 seconds, but the news
component cache will only last for 60 seconds.

When using a controller reference, the ESI tag should reference the embedded
action as an accessible URL so the gateway cache can fetch it independently of
the rest of the page. Of course, an action can't be accessed via a URL unless
it has a route that points to it. Symfony2 takes care of this via a generic
route and controller. For the ESI include tag to work properly, you must
define the ``_proxy`` route:

.. configuration-block::

.. code-block:: yaml

# app/config/routing.yml
_proxy:
resource: "@FrameworkBundle/Resources/config/routing/proxy.xml"
prefix: /proxy

.. code-block:: xml

<!-- app/config/routing.xml -->
<?xml version="1.0" encoding="UTF-8" ?>

<routes xmlns="http://symfony.com/schema/routing"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">

<import resource="@FrameworkBundle/Resources/config/routing/proxy.xml" prefix="/proxy" />
</routes>

.. code-block:: php

// app/config/routing.php
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;

$collection->addCollection($loader->import('@FrameworkBundle/Resources/config/routing/proxy.xml', '/proxy'));

return $collection;

One great advantage of this caching strategy is that you can make your
application as dynamic as needed and at the same time, hit the application as
little as possible.
Expand All @@ -967,7 +984,7 @@ little as possible.
obey the ``max-age`` directive and cache the entire page. And you don't
want that.

The ``render`` helper supports two other useful options:
The ``render_esi`` helper supports two other useful options:

* ``alt``: used as the ``alt`` attribute on the ESI tag, which allows you
to specify an alternative URL to be used if the ``src`` cannot be found;
Expand Down
76 changes: 19 additions & 57 deletions 76 book/templating.rst
Original file line number Diff line number Diff line change
Expand Up @@ -623,43 +623,8 @@ The ``recentList`` template is perfectly straightforward:
(e.g. ``/article/*slug*``). This is a bad practice. In the next section,
you'll learn how to do this correctly.

Even though this controller will only be used internally, you'll need to
create a route that points to the controller:

.. configuration-block::

.. code-block:: yaml

latest_articles:
pattern: /articles/latest/{max}
defaults: { _controller: AcmeArticleBundle:Article:recentArticles }

.. code-block:: xml

<?xml version="1.0" encoding="UTF-8" ?>

<routes xmlns="http://symfony.com/schema/routing"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">

<route id="latest_articles" pattern="/articles/latest/{max}">
<default key="_controller">AcmeArticleBundle:Article:recentArticles</default>
</route>
</routes>

.. code-block:: php

use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;

$collection = new RouteCollection();
$collection->add('latest_articles', new Route('/articles/latest/{max}', array(
'_controller' => 'AcmeArticleBundle:Article:recentArticles',
)));

return $collection;

To include the controller, you'll need to refer to it using an absolute url:
To include the controller, you'll need to refer to it using the standard
string syntax for controllers (i.e. **bundle**:**controller**:**action**):

.. configuration-block::

Expand All @@ -669,7 +634,7 @@ To include the controller, you'll need to refer to it using an absolute url:

{# ... #}
<div id="sidebar">
{% render url('latest_articles', { 'max': 3 }) %}
{{ render(controller('AcmeArticleBundle:Article:recentArticles', { 'max': 3 })) }}
</div>

.. code-block:: html+php
Expand All @@ -679,12 +644,10 @@ To include the controller, you'll need to refer to it using an absolute url:
<!-- ... -->
<div id="sidebar">
<?php echo $view['actions']->render(
$view['router']->generate('latest_articles', array('max' => 3), true)
new ControllerReference('AcmeArticleBundle:Article:recentArticles', array('max' => 3))
) ?>
</div>

.. include:: /book/_security-2012-6431.rst.inc

Whenever you find that you need a variable or a piece of information that
you don't have access to in a template, consider rendering a controller.
Controllers are fast to execute and promote good code organization and reuse.
Expand All @@ -703,13 +666,20 @@ Symfony2 uses the standard ``render`` helper to configure ``hinclude`` tags:

.. code-block:: jinja

{% render url('...'), {'standalone': 'js'} %}
{{ render_hinclude(controller('...')) }}

{{ render_hinclude(url('...')) }}

.. code-block:: php

<?php echo $view['actions']->render(
new ControllerReference('...'),
array('strategy' => 'hinclude')
) ?>

<?php echo $view['actions']->render(
$view['router']->generate('...'),
array('standalone' => 'js')
array('strategy' => 'hinclude')
) ?>

.. note::
Expand Down Expand Up @@ -756,18 +726,14 @@ any global default templates that is defined):

.. code-block:: jinja

{% render '...:news' with
{},
{'standalone': 'js', 'default': 'AcmeDemoBundle:Default:content.html.twig'}
%}
{{ render_hinclude(controller('...'), {'default': 'AcmeDemoBundle:Default:content.html.twig'}) }}

.. code-block:: php

<?php echo $view['actions']->render(
'...:news',
array(),
new ControllerReference('...'),
array(
'standalone' => 'js',
'strategy' => 'hinclude',
'default' => 'AcmeDemoBundle:Default:content.html.twig',
)
) ?>
Expand All @@ -778,18 +744,14 @@ Or you can also specify a string to display as the default content:

.. code-block:: jinja

{% render '...:news' with
{},
{'standalone': 'js', 'default': 'Loading...'}
%}
{{ render_hinclude(controller('...'), {'default': 'Loading...'}) }}

.. code-block:: php

<?php echo $view['actions']->render(
'...:news',
array(),
new ControllerReference('...'),
array(
'standalone' => 'js',
'strategy' => 'hinclude',
'default' => 'Loading...',
)
) ?>
Expand Down
2 changes: 1 addition & 1 deletion 2 cookbook/service_container/scopes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ when compiling the container. Read the sidebar below for more details.
*RequestA*) is passed to it. Life is good!

* You've now made a subrequest in Symfony, which is a fancy way of saying
that you've called, for example, the `{% render ... %}` Twig function,
that you've called, for example, the `{{ render(...) }}` Twig function,
which executes another controller. Internally, the old `request` service
(*RequestA*) is actually replaced by a new request instance (*RequestB*).
This happens in the background, and it's totally normal.
Expand Down
2 changes: 1 addition & 1 deletion 2 cookbook/templating/render_without_controller.rst
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ this is probably only useful if you'd like to cache this page partial (see

.. code-block:: html+jinja

{% render url('acme_privacy') %}
{{ render(url('acme_privacy')) }}

.. code-block:: html+php

Expand Down
56 changes: 9 additions & 47 deletions 56 quick_tour/the_view.rst
Original file line number Diff line number Diff line change
Expand Up @@ -180,57 +180,19 @@ And what if you want to embed the result of another controller in a template?
That's very useful when working with Ajax, or when the embedded template needs
some variable not available in the main template.

Suppose you've created a ``fancyAction`` controller method, and you want to "render"
it inside the ``index`` template. First, create a route to your new controller
in one of your application's routing configuration files.

.. configuration-block::

.. code-block:: yaml

# app/config/routing.yml
fancy:
pattern: /included/fancy/{name}/{color}
defaults: { _controller: AcmeDemoBundle:Demo:fancy }

.. code-block:: xml

<!-- app/config/routing.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">

<route id="fancy" pattern="/included/fancy/{name}/{color}">
<default key="_controller">AcmeDemoBundle:Demo:fancy</default>
</route>
</routes>

.. code-block:: php

// app/config/routing.php
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;

$collection = new RouteCollection();
$collection->add('fancy', new Route('/included/fancy/{name}/{color}', array(
'_controller' => 'AcmeDemoBundle:Demo:fancy',
)));

return $collection;

To include the result (e.g. ``HTML``) of the controller, use the ``render`` tag:
Suppose you've created a ``fancyAction`` controller method, and you want to
"render" it inside the ``index`` template, which means including the result
(e.g. ``HTML``) of the controller, use the ``render`` function:

.. code-block:: jinja

{# src/Acme/DemoBundle/Resources/views/Demo/index.html.twig #}
{% render url('fancy', { 'name': name, 'color': 'green'}) %}

.. include:: /book/_security-2012-6431.rst.inc
{{ render(controller("AcmeDemoBundle:Demo:fancy", {'name': name, 'color': 'green'})) }}

The ``render`` tag will execute the ``AcmeDemoBundle:Demo:fancy`` controller
and include its result. For example, your new ``fancyAction`` might look
like this::
Here, the ``AcmeDemoBundle:Demo:fancy`` string refers to the ``fancy`` action
of the ``Demo`` controller. The arguments (``name`` and ``color``) act like
simulated request variables (as if the ``fancyAction`` were handling a whole
new request) and are made available to the controller::

// src/Acme/DemoBundle/Controller/DemoController.php

Expand All @@ -243,7 +205,7 @@ like this::

return $this->render('AcmeDemoBundle:Demo:fancy.html.twig', array(
'name' => $name,
'object' => $object
'object' => $object,
));
}

Expand Down
Loading
Morty Proxy This is a proxified and sanitized view of the page, visit original site.