渲染一个没有缓存的Twig模板

时间:2018-09-05 09:51:19

标签: php symfony twig

我们的Symfony项目有一个登录小部件,有人告诉我应该通过AJAX加载该小部件,以免干扰页面缓存。

它显示“登录”,或者显示用户的电子邮件地址(如果他已经登录)。

问题是,树枝模板也被缓存了!因此,通过ajax加载它没有帮助。

如何告诉Twig每次从头开始渲染我的模板,而不禁用整个站点的缓存?

模板本身非常简单:

    <small id="login-username">
        {% if is_granted('ROLE_USER') %}
            {{ app.user.username }}
        {% else %}
            {{ 'LoginWidgetElement.login' | trans }}
        {% endif %}
    </small>

元素的类也很简单:

<?php

namespace Xyz\Sports\Element\LoginWidget;

use Xyz\Library\AbstractElement;
use Sensio\Bundle\FrameworkExtraBundle\Configuration as Config;

/**
* @Config\Template("@LoginWidgetElement/login_widget.html.twig")
*/
class LoginWidgetElement extends AbstractElement
{
    public function render()
    {
        return [];
    }

    public function renderPreview()
    {
        return $this->render();
    }
}
  

更新

树枝模板似乎正在检查,因此我尝试发送一个响应,告诉浏览器不要缓存,但是在变量更改之前它仍然需要大约15个请求!!

细枝缓存:

<small id=\"login-username\">
            ";
        // line 9
        if ($this->extensions['Symfony\Bridge\Twig\Extension\SecurityExtension']->isGranted("ROLE_USER")) {
            // line 10
            echo "                ";
            echo twig_escape_filter($this->env, twig_get_attribute($this->env, $this->source, twig_get_attribute($this->env, $this->source, (isset($context["app"]) || array_key_exists("app", $context) ? $context["app"] : (function () { throw new Twig_Error_Runtime('Variable "app" does not exist.', 10, $this->source); })()), "user", array()), "username", array()), "html", null, true);
            echo "
            ";
        } else {
            // line 12
            echo "                ";
            echo twig_escape_filter($this->env, $this->extensions['Symfony\Bridge\Twig\Extension\TranslationExtension']->trans("LoginWidgetElement.login"), "html", null, true);
            echo "
            ";
        }
        // line 14
        echo "        </small>

因此有一个isGranted('ROLE_USER')支票。现在,在我的渲染方法中:

$response = new Response();
$response->headers->set('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0, post-check=0, pre-check=0');
$response->headers->set('Pragma', 'no-cache');

$body = $this->twig->render('@LoginWidgetElement/login_widget.html.twig');
$response->setContent($body);

return $response;

但是仍然没有雪茄:'-(

1 个答案:

答案 0 :(得分:1)

好像设置缓存头有它自己的方法,我们不应该只使用$response->headers->set($key, $val);

我将逻辑转换为可重用的特征:

<?php

namespace Xyz\Library\Traits;

use Symfony\Component\HttpFoundation\Response;

trait NoCacheHeadersTrait
{
    public function disableBrowserCache(Response $response) : Response
    {
        $response->headers->addCacheControlDirective('no-store', true);
        $response->headers->addCacheControlDirective('no-cache', true);
        $response->headers->addCacheControlDirective('must-revalidate', true);
        $response->headers->addCacheControlDirective('max-age', 0);
        $response->headers->addCacheControlDirective('post-check', 0);
        $response->headers->addCacheControlDirective('pre-check', 0);
        $response->headers->set('Pragma', 'no-cache');

        return $response;
    }
}

现在我use在类中的特征,在我的render方法中,它现在看起来像这样:

public function render()
{
    $response = $this->disableBrowserCache(new Response());
    $body = $this->twig->render('@LoginWidgetElement/login_widget.html.twig');
    $response->setContent($body);

    return $response;
}