如何在Twig基础模板中设置基于会话的变量?

3

I want to plug twig into an application that would need some session-based data incorporated in the base. For example, the client's current timezone shows in the footer. It doesn't make sense for the individual controllers to know about this, since it has nothing to do with them; but on the other hand, they select and populate the view:

class MyController 
{

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

Is there some well-formed way to pass a data object to twig before you select a view, and make that available to the base template? Something that you would do upon firing up the Twig_Environment and passing it in?


你可以使用{{ session.name }}。 - DarkBee
如果它起作用,那似乎会从超级全局变量中提取。 - Bryan Agee
3
app.session.get('Name'),抱歉 :)您也可以通过 $twig->addGlobal('session', $_SESSION) 将其注册为全局变量。 - DarkBee
1
你可以创建一个自定义的Twig函数,并在需要的地方调用它,例如 {{ your_function() }} - qooplmao
3个回答

1

1

会话变量需要在控制器中设置。如文档中所示, 具体代码如下:

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)));

1

如果你不想让所有的控制器处理那些“全局”的变量注入,你可以实现一个基础控制器类,让所有其他控制器继承它,并在其中执行以下操作:

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。

这看起来是一个聪明、干净的完成方式;不过我还不确定是否想让所有的控制器都扩展一个基类... - Bryan Agee
当您从Symfony\Bundle\FrameworkBundle\Controller\Controller继承时,它们会自动执行。 - janwschaefer
@janwschaefer- 我们还没有使用完整的Symfony堆栈,只是插入了一些组件。目前为止,控制器没有扩展任何东西。 - Bryan Agee
我明白了。你可以进一步尝试一下。看看Symfony提供的基础控制器中render()方法的实现。他们调用return $this->container->get('templating')->renderResponse($view, $parameters, $response); 所以你可以扩展该服务,对renderResponse进行所提出的hack,并使用自己的服务替代模板引擎。 - janwschaefer
你如何在控制器中填充twig字段?使用服务容器吗? - janwschaefer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接