可从任何 Twig 模板访问的通用逻辑

Common logic accessible from any twig template

在 SF3 中,我想知道如何执行我网站中任何页面通用的一些逻辑。

FOSUserBundle, global arguments / function before templating 是答案的开头,但它谈论的是 SF2,我不确定 OP 是否真的期待和我一样的东西。

目前,我定义了一个自定义基础 class (BasePageController),我的项目中的任何控制器都继承自该基础。 通用的逻辑写在那里,每个控制器调用一个通用的方法来检索 一些自定义变量发送到树枝模板。

这是它的样子(我尽量制作最小的例子):

我的基地控制器class:

<?php
// src/AppBundle/Controller/BasePageController.php

namespace AppBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class BasePageController extends Controller
{
    public function getCommonParams()
    {
        // This assignement may be replaced by a complex logic,
        // evolving user-specific data, session variables... :
        $val = 1234;

        return [ 'important_val' => $val ];
    }
}

继承自我的基础的控制器示例class:

<?php
// src/AppBundle/Controller/HomeController.php

namespace AppBundle\Controller;

use AppBundle\Controller\BasePageController;

class HomeController extends BasePageController
{
    public function homeAction()
    {
        $params = $this->getCommonParams();
        return $this->render('home.html.twig', $params);
    }
}

一个基本的基础模板:

{# app/Resources/views/base.html.twig #}

<!doctype html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>SO example</title>
    </head>
    <body>
        {% block body %}{% endblock %}
    </body>
</html>

我的控制器示例使用的模板:

{# app/Resources/views/home.html.twig #}

{% extends 'base.html.twig' %}

{% block body %}
<h1>Welcome</h1>
<p>
    Important value : {{ important_val }}
</P>
{% endblock %}

我不太确定这是否是处理 SF 网站中常见逻辑的常用方法(欢迎提出建议)。

但可以肯定的是,当我尝试在这个方案上使用 FOSUserBundle 时,问题开始出现。

确实,FOSUserBundle 中的每个控制器显然都没有继承自我的自定义 控制器 class。所以,即使重新定义 FOSUserBundle 模板,我的通用逻辑也会 无法从 login/register/... 页面访问。

我现在能想到的唯一解决方法是:

如果有一个神奇的树枝标签可以导入变量,可能会有一个完美的解决方案 来自 PHP 方法,像这样:

{# app/Resources/views/base.html.twig #}

{% import_my_variables_from('AppBundle:BasePageController:getCommonParams()') %}

<!doctype html>
<html>
....

那么如何使一些通用逻辑可访问,即使对于像 FOSUserBundle 这样的外部包?

我总是对每个页面都需要通用参数这一概念持怀疑态度。随着应用程序设计的改进,要求通常会消失。

但假设您确实需要它,那么将通用参数功能移到它自己的服务中。

class CommonParameters {
    public function getParams() {
        return [whatever];

将其连接为服务:http://symfony.com/doc/current/book/service_container.html

services:
    common_parameters:
        class: AppBundle\Common\CommonParameters

从控制器内部,通过以下方式访问参数:

$params = $this->get('common_parameters')->getParams();

你甚至可以定义一个特性来将它添加到你的控制器中并摆脱你的自定义基础控制器 类 这恰好是另一个听起来不错但在实践中经常被证明的想法比它们的价值更痛苦。

但是树枝呢?这是树枝扩展可以发挥作用的地方:http://symfony.com/doc/current/cookbook/templating/twig_extension.html。你可以将你的参数服务注入到你的 twig 扩展中,twig 将可以访问这些变量,而根本不需要控制器。插入您自己的 FOSUserBundle 模板,然后就可以开始了。

当然,您也可以将这些东西注入到任何其他可能需要它的服务中。想服务。不是全局变量。

最后说明:Symfony 是一个世俗框架。神奇的思维不会让你走得太远。