Symfony 4 - глобальные данные для шаблонов и контроллеров

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

Пример:

<?php

namespace App\Controller;

use App\Entity\Settings;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

class BaseController extends AbstractController {  
    public function getMenu() {
    $settings = $this->getDoctrine()
        ->getRepository(Settings::class)
        ->findAll();

    return $settings;
}

У меня есть файл базового шаблона, в который я помещаю такие переменные, как

<meta name="description" content="{{ description }}">
<meta name="keywords" content="{{ keywords }}">
<meta name="author" content="{{ author }}">
{% block body %}

{% endblock %}

Затем я визуализирую файл шаблона страницы в PageController

<?php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;

class PageController extends AbstractController {  
    public function view() {
        $content = 'blabla';
        return $this->render('pages.html.twig', ['content' => $content]);
    }

И, например, у меня есть файл шаблона страницы, в котором я расширяю файл базового шаблона

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

{% block body %}
    {{ content }}
{% endblock %}

Какое лучшее решение для ввода переменных из BaseController во все контроллеры без жесткого кодирования глобальных переменных в файле twig?

Думаю, вам стоит переосмыслить структуру своих проектов. Нет смысла помещать эту логику в ваш baseController. Похоже, что услуга сделает что-то. Затем вы можете внедрить свою службу в контроллеры, которые в ней нуждаются, и все готово. Если это статические значения, которые вам очень нужны, вы также можете подумать о том, чтобы добавить их в свой файл config.yml и прочитать его оттуда через свои пакеты DependencyInjection. Но использовать контроллер таким образом - неправильный путь.

Dirk Scholten 10.08.2018 17:19

@DirkScholten Я хочу получить этот контент из базы данных, чтобы он мог измениться. Итак, мне нужно создать контейнер службы, который будет получать данные из базы данных, верно?

Philip Harkov 10.08.2018 17:20

Тогда я бы подумал о создании службы / репозитория, который будет общаться с базой данных за вас. Затем вы можете просто использовать автоматическое подключение от Symfony, чтобы внедрить эту службу в контроллеры, которые в ней нуждаются, и таким образом взаимодействовать с базой данных. Во-первых, в контроллере не должно быть много логики.

Dirk Scholten 10.08.2018 17:22
0
3
1 186
2

Ответы 2

Вы можете заставить его работать с глобальными переменными twig. Это описано здесь в документации: http://symfony.com/doc/current/templating/global_variables.html#referencing-services

Вы должны создать службу для извлечения значений из базы данных и сделать ее доступной для всех шаблонов twig через конфигурацию «глобальная переменная».

Вместо глобальной переменной вы можете определить функцию Twig для доставки контента.

class ContentExtension extends \Twig_Extension
{
    public function getFunctions()
    {
        return [
            new \Twig_SimpleFunction('getContent', [$this, 'getContent'])
        ];
    }

    public function getContent($name)
    {
        return "content";
    }
}

Не забудьте зарегистрировать расширение Twig как службу в конфигурации вашего приложения:

services:
    Your\Namespace\ContentExtension:
        tags: [{ name: twig.extension }]

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

Теперь вы можете использовать функцию getContent() в любом из ваших шаблонов Twig:

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

{% block body %}
    {{ getContent() }}
{% endblock %}

Другие вопросы по теме