【问题标题】:How can you set a session-based variable in a twig base template?如何在 twig 基本模板中设置基于会话的变量?
【发布时间】:2014-08-08 21:55:16
【问题描述】:

我想将 twig 插入需要在基础中包含一些基于会话的数据的应用程序中。例如,客户端的当前时区显示在页脚中。单个控制器知道这一点是没有意义的,因为这与他们无关;但另一方面,他们选择并填充视图:

class MyController 
{

    public function index()
    {
        $template = $this->twig->loadTemplate('myPageTemplate.html.twig');
        return $template->render($dataArray);
    }
}

在选择视图之前,是否有一些格式良好的方法可以将数据对象传递给 twig,并使其可用于基本模板?在启动 Twig_Environment 并将其传入时你会做什么?

【问题讨论】:

  • 你可以使用 {{ session.name }}
  • 如果它有效的话,它似乎会从一个超级全球拉出来
  • app.session.get('Name'),抱歉 :) 你也可以使用 $twig->addGlobal('session', $_SESSION); 将其注册为全局变量;虽然
  • 你可以创建一个自定义的 twig 函数并在任何你想要的地方调用它,比如{{ your_function() }}

标签: php symfony twig template-inheritance


【解决方案1】:

需要在控制器中设置会话变量。正如in the docs 所见,它看起来像这样:

public function indexAction(Request $request)
{
    $session = $request->getSession();

    // store an attribute for reuse during a later user request
    $session->set('foo', 'bar');

    // get the attribute set by another controller in another request
    $foobar = $session->get('foobar');

    // use a default value if the attribute doesn't exist
    $filters = $session->get('filters', array());
}

这些变量在渲染模板时很容易传递,例如:

return $this->redirect($this->generateUrl('home', array('foobar' => $foobar)));

【讨论】:

    【解决方案2】:

    如果您不希望所有控制器都处理这些“全局”变量的注入,您可以实现一个所有其他控制器都继承自的基本控制器类,并在内部执行以下操作:

    public function render($view, array $parameters = array(), Response $response = null)
    {
        if(!isset($parameters['timezone'])) {
             // fill the parameter with some value
            $parameters['timezone'] = $this->getSession()->get('timezone');
        }
        return parent::render($view, $parameters, $response);
    }
    

    这允许您进行“全局”注入,而无需完全脱离控制器。

    不要忘记让你的基本控制器扩展 Symfony\Bundle\FrameworkBundle\Controller\Controller。

    【讨论】:

    • 这看起来是一种聪明、干净的方式来完成它;不过,我还不太确定我是否希望所有控制器都扩展一个基础......
    • 当你从 Symfony\Bundle\FrameworkBundle\Controller\Controller 继承时,它们无论如何都会这样做。
    • @janwschaefer- 我们还没有使用完整的 symfony 堆栈——只是插入了一些组件。到目前为止,控制器还没有扩展任何东西
    • 我明白了。你也许可以更进一步。查看 symfony 提供的基本控制器中 render() 的实现。他们调用 return $this->container->get('template')->renderResponse($view, $parameters, $response);因此,您可以扩展该服务,执行我在 renderResponse 中提出的 hack,并使用您自己的服务代替模板。
    • 如何在控制器中填充 twig 字段?使用服务容器?
    【解决方案3】:

    最好的方法是添加一个 Twig 扩展,这样您就不必在控制器中包含任何内容。使用扩展程序,您可以添加一个已经建议的全局 (http://twig.sensiolabs.org/doc/advanced.html#globals) 或可以直接使用的函数 (http://twig.sensiolabs.org/doc/advanced.html#functions)(例如 {{ user_timezone() }} )。

    【讨论】:

      猜你喜欢
      • 2012-12-06
      • 2014-06-10
      • 1970-01-01
      • 1970-01-01
      • 2012-02-09
      • 1970-01-01
      • 2023-04-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多