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

时间:2016-06-22 14:48:24

标签: templates fosuserbundle symfony

在SF3中,我想知道如何执行我网站中任何页面常见的逻辑。

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

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

以下是它的外观(我试图尽可能地做出最小的例子):

我的基本控制器类:

<?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 ];
    }
}

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

<?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内的每个控制器显然都不会从我的自定义中继承 控制器类。因此,即使重新定义FOSUserBundle模板,我的共同逻辑也会如此 无法从登录/注册/ ...页面访问。

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

  • 在模板中包含一个带有{% render %}(继承自我的自定义类)的整个控制器,其中 共同的逻辑是可以访问的;但是内部仍然没有共同的逻辑 主模板(即login.html.twig ...);
  • 通过替换其标准继承(Controller)重新定义所有FOSUserBundle控制器 通过我自己的自定义控制器类;但我确定这是一年中最糟糕的想法(我愿意 松散了作曲家升级系统提供的所有灵活性。

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

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

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

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

那么即使对于像FOSUserBundle这样的外部捆绑包,如何才能使一些常见的逻辑可访问?

1 个答案:

答案 0 :(得分:1)

我总是对你真正需要每个页面的通用参数的想法持怀疑态度。随着应用程序设计的完善,这一要求经常消失。

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

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可以访问这些变量而根本不涉及控制器。插入您自己的FOSUserBundle模板,然后离开。

当然,您也可以将这些内容注入其他可能需要的服务中。想想服务。不是全局的。

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