Как переопределить любую часть пакета

Дата обновления перевода 2023-01-20

Как переопределить любую часть пакета

При использовании сторонних пакетов вы можете захотеть настроить или переопределить некоторые из их функций. Этот документ описывает способы переопределения наиболее распространённых функций пакета.

Tip

Механизм переопределения пакета означает, что вы не можете использовать физические пути для ссылания на источники пакета (например, __DIR__/config/services.xml). Всегда используйте логические пути в ваших пакетах (например, @FooBundle/Resources/config/services.xml) и вызывайте метод locateResource() , чтобы преобразовывать их в физические пути при необходимости.

Шаблоны

Шаблоны сторонних бандлов могут быть переопределены в каталоге <your-project>/templates/bundles/<bundle-name>/. Новые шаблоны должны использовать то же имя и путь (относительно <bundle>/Resources/views/) как и оригинальные шаблоны.

Например, для переопределения шаблона Resources/views/Registration/confirmed.html.twig из FOSUserBundle, создайте этот шаблон: <your-project>/templates/bundles/FOSUserBundle/Registration/confirmed.html.twig

Caution

После добавления шаблона в новое место, возможно, вам необходимо будет очистить кеш (php bin/console cache:clear), даже если вы в debug-режиме.

Вместо переопределения всего шаблона, вы можете хотеть переопределить только один или несколько блоков. Однако, так как вы переопределяете шаблон из которого вы хотите расширять, вы получите бесконечный цикл ошибки. Решением будет использовать специальный префикс ! в имени шаблона, чтобы сообщить Symfony, что вы хотите расширить из исходного шаблона, а не из переопределённого:

1
2
3
4
5
6
7
{# templates/bundles/AcmeUserBundle/registration/confirmed.html.twig #}
{# специальный префикс '!' избегает ошибок при расширении из переопределённого шаблона #}
{% extends "@!AcmeUser/registration/confirmed.html.twig" %}

{% block some_block %}
    ...
{% endblock %}

Tip

Сама Symfony тоже использует некоторые бандлы, поэтому вы можете использовать этот же подход для переопределения шаблонов ядра Symfony. Например, вы можете настроить страницы ошибок переопределяя шаблоны TwigBundle.

Маршрутизация

Маршрутизация в Symfony никогда не импортируется автоматически. Если вы хотите включить маршруты из любого пакета, то они должны быть импортированы вручную откуда-то из вашего приложения (например, config/routes.yaml).

Самый простой способ "переопределить" маршрутизацию пакета - не импортировать её в принципе. Вместо импортирования маршрутизации стороннего пакета, просто скопируйте файл маршрутизации в ваше приложение, измените его и импортируйте.

Контроллеры

Если контроллер является сервисом, смотрите следующий раздел о том, как пеоепределить его. В обратном случае, определите новый маршрут + контроллер с одним путём, связанным с контроллером, который вы хотите переопределить (и убедитесь, что новый маршрут загружается до маршрута пакета).

Сервисы и конфигурация

Если вы хотите изменить сервисы, созданные пакетом, вы можете использовать декорирование сервисов.

Если вы хотите провести более продвинутые манипуляции, вроде удаления сервисов, созданных другими пакетами, вы должны работать с определениями сервиса внутри передачи компилятора.

Сущности и их отображение

В связи с особенностями работы Doctrine, невозможно переопределить отображение сущностей пакета. Однако, если пакет предоставляет отображённый суперкласс (как, например, сущность User в FOSUserBundle), то можно переопределить атрибуты и ассоциации. Узнайте больше об этой функции и её ограничениях в документации Doctrine.

Формы

Существующие типы форм могут быть изменены путём определения расширений типа формы.

Метаданные валидации

Symfony загружает все файлы конфигурации валидации из каждого пакета и комбинирует их в одно древо метаданных валидации. Это означает, что вы можете добавить новые ограничения к свойству, но не можете переопределить их.

Чтобы обойти это, сторонний пает должен иметь конфигурацию для групп валидации. Например, FOSUserBundle имеет такую конфигурацию. Чтобы создать вашу собственную валидацию, добавьте ограничения к новой группе валидации:

  • YAML
  • XML
1
2
3
4
5
6
7
8
9
10
# config/validator/validation.yaml
FOS\UserBundle\Model\User:
    properties:
        plainPassword:
            - NotBlank:
                groups: [AcmeValidation]
            - Length:
                min: 6
                minMessage: fos_user.password.short
                groups: [AcmeValidation]

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

Переводы

Переводы не связаны с пакетами, но связаны с доменами переводов. For this reason, you can override any bundle translation file from the main translations/ directory, as long as the new file uses the same domain.

Например, для переопределения переводов, определённых в файле Resources/translations/FOSUserBundle.es.yml из FOSUserBundle, создайте файл <your-project>/translations/FOSUserBundle.es.yml.