2016-06-22 4 views
0

В 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 ...);
  • переопределить все контроллеры FOSUserBundle, заменив их стандартное наследование (Controller) моим собственным классом контроллера; но я уверен, что это худшая идея года (я бы потерял всю гибкость, предлагаемую системой обновления композитора).

Там может быть идеальным решением, если был волшебный прутик тег, который будет импортировать переменные из метода PHP, что-то вроде этого:

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

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

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

Так как это можно сделать некоторые общие логики доступный даже для внешних пакетов, таких как FOSUserBundle?

ответ

1

Я всегда скептически отношусь к понятию, что вам действительно нужны общие параметры для каждой отдельной страницы. Требование часто уходит, поскольку дизайн приложения уточняется.

Но если вы действительно нуждаетесь в этом, тогда переместите общие параметры в свою собственную службу.

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

Wire его в качестве услуги: 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. Вы можете ввести службу параметров в расширение ветки, а веточка будет иметь доступ к этим переменным без привлечения контроллеров вообще. Подключите свои собственные шаблоны FOSUserBundle и отпустите.

И, конечно, вы также можете вводить этот материал в любые другие службы, которые могут ему понадобиться. Думайте об услугах. Не глобалы.

Заключительное примечание: Symfony - это светский каркас. Магическое мышление не заберет вас далеко.

+0

Действительно полезный ответ, tx; я уверен, что вы правы в необходимости (или нет) общих параметров; но мне действительно нужно было четко ответить на этот вопрос Q, чтобы глубже понять мое понимание SF. Я использовал слово «магический», чтобы помочь читателям увидеть, что я новичок, поэтому они дают мне простые сведения, как и ваши! tx снова – yolenoyer