Заменить шаблон пакета из другого пакета в Symfony 4/5

Поскольку наследование пакетов устарело с Symfony 3.4 и будет удалено в 4.0, я нахожу новое решение. У меня есть:

  • Заявление
  • FooBundle
  • BarBundle

И у меня нет проблем с переопределением шаблонов в Application. Но мне нужно переопределить шаблоны из BarBundle в FooBundle. Это было так просто с наследованием пакетов, но теперь я потерялся :)

Я пробовал пространства имен twig - безуспешно, но, возможно, я настроил его неправильно. Моя цель - иметь базовые шаблоны в BarBundle, которые я могу переопределить в FooBundle, Application или в обоих. (это потому, что BarBundle - это сторонний пакет, а FooBundle - мой пакет, используемый во многих проектах).

Возможно ли это без наследования пакетов и как?

Спасибо.

Вы пробовали: symfony.com/doc/current/templating/overriding.html Я сам давно не делал этого, но это кажется достаточно простым. Другой подход - добавить пути веток с пространством имен.

Cerad 30.05.2018 15:41

@Cerad: Для меня это выглядит как конфигурация вашего собственного приложения, но я думаю, что OP ищет решение, инкапсулированное в его пакете

Nico Haase 30.05.2018 15:48

@NicoHaase Вторая ссылка показывает, как FooBundle может добавить пространство имен twig, чтобы в основном переопределить шаблоны BarBundle. А затем вы можете добавить его в приложение, чтобы переопределить то, что есть в FooBundle. Раньше я делал такую ​​ерунду, прежде чем отказался от веточки.

Cerad 30.05.2018 15:59
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
7
3
1 768
3

Ответы 3

Итак, мне недавно понадобилась такая же функциональность, и с помощью комментария @NicoHasse мне удалось сделать рабочий пример

В вашем классе расширения пакета вам необходимо реализовать PrependExtensionInterface, а затем вы можете изменить пути ветки. Затем вам нужно знать исходное пространство имен, которое вам нужно переопределить (php bin/console debug:twig).

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

class YourExtensionClass extends Extension implements PrependExtensionInterface
{
    public function prepend(ContainerBuilder $container)
    {
        $container->loadFromExtension('twig', [
            'paths' => [
                '%kernel.project_dir%/vendor/xx/yy/zzz' => 'OriginalVNamespace',
            ]
        ]);

Вот более наглядный пример

Начнем с некоторых предположений

Название вашего пакета: AcmeBundle

Пакет, который вы хотите переопределить: FOSUserBundle

Запустите команду php bin/console debug:twig и найдите пространство имен пакета, который вы хотите переопределить. В данном случае это @FOSUser.

Расширение вашего пакета должно выглядеть так

<?php // src/AcmeBundle/DependencyInjection/AcmeExtension.php

namespace AcmeBundle\DependencyInjection;

// ...

use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;

class AcmeExtension extends Extension implements PrependExtensionInterface
{
    // ...

    public function prepend(ContainerBuilder $container)
    {
        $container->loadFromExtension('twig', array(
            'paths' => array(
                '%kernel.project_dir%/src/AcmeBundle/Resources/FOSUserBundle/views' => 'FOSUser', // You use the namespace you found earlier here. Discard the `@` symbol.
            ),
        ));
    }
}

Теперь вы можете создать src/AcmeBundle/Resources/FOSUserBundle/views/Security/login.html.twig, чтобы переопределить шаблон входа в FOSUserBundle.

Это просто пример для FOSUserBundle. Вы можете изменить имена пакетов в зависимости от того, что вы пытаетесь переопределить.

Я покажу, как это выглядит в моем случае (Symfony 5.1). Чтобы перезаписать представления для пакетов JMoseCommandSchedulerBudnle и TwigBundle:

1. Создайте свой собственный каталог с пользовательскими шаблонами сторонних пакетов (я поместил их в Resources/views/bundles):

2. Создайте папки для каждого пакета, в котором вы хотите переопределить шаблоны:

3. Создайте собственные шаблоны (например, для создания пользовательских страниц ошибок Twig):

4. Внедрите PrependExtensionInterface и добавьте пользовательские пути в конфигурацию расширения Twig:

class AppngCmsExtension extends Extension implements PrependExtensionInterface {
    public function load(array $configs, ContainerBuilder $container)
    {
        $loader = new YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
        $loader->load('services.yaml');
    }

    public function prepend(ContainerBuilder $container)
    {
        // I recommend using FileLocator here 
        $thirdPartyBundlesViewFileLocator = (new FileLocator(__DIR__ . '/../Resources/views/bundles'));

        $container->loadFromExtension('twig', [
            'paths' => [
                $thirdPartyBundlesViewFileLocator->locate('JMoseCommandSchedulerBundle') => 'JMoseCommandScheduler',
                $thirdPartyBundlesViewFileLocator->locate('TwigBundle') => 'Twig',
            ],
        ]);
    }
}

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