如何覆寫 Bundle 的任何部分
當使用第三方 Bundle 時,您可能想要自訂或覆寫它的某些功能。本文檔描述了覆寫 Bundle 最常見功能的方法。
模板
第三方 Bundle 模板可以在 <your-project>/templates/bundles/<bundle-name>/
目錄中覆寫。新的模板必須使用與原始模板相同的名稱和路徑(相對於 <bundle>/templates/
)。
例如,要覆寫 AcmeUserBundle 中的 templates/registration/confirmed.html.twig
模板,請建立此模板: <your-project>/templates/bundles/AcmeUserBundle/registration/confirmed.html.twig
警告
如果您在新的位置新增模板,即使您處於偵錯模式,您*可能*需要清除快取 (php bin/console cache:clear
)。
與其覆寫整個模板,您可能只想覆寫一個或多個區塊。但是,由於您要覆寫您想要擴充的模板,因此最終會陷入無限迴圈錯誤。解決方案是在模板名稱中使用特殊的 !
前綴,以告知 Symfony 您想要從原始模板擴充,而不是從覆寫的模板擴充
1 2 3 4 5 6 7
{# templates/bundles/AcmeUserBundle/registration/confirmed.html.twig #}
{# the special '!' prefix avoids errors when extending from an overridden template #}
{% extends "@!AcmeUser/registration/confirmed.html.twig" %}
{% block some_block %}
...
{% endblock %}
提示
Symfony 內部也使用了一些 Bundle,因此您可以應用相同的技術來覆寫核心 Symfony 模板。例如,您可以透過覆寫 TwigBundle 模板來自訂錯誤頁面。
路由
路由永遠不會在 Symfony 中自動匯入。如果您想要包含任何 Bundle 的路由,則必須從應用程式中的某個位置手動匯入它們(例如 config/routes.yaml
)。
「覆寫」Bundle 路由最簡單的方法是完全不要匯入它。與其匯入第三方 Bundle 的路由,不如將該路由檔案複製到您的應用程式中,修改它,然後改為匯入它。
控制器
如果控制器是一個服務,請參閱下一節關於如何覆寫它的內容。否則,請定義一個新的路由 + 控制器,其路徑與您想要覆寫的控制器相關聯(並確保新的路由在 Bundle 路由之前載入)。
實體 & 實體對應
只有當 Bundle 提供對應的父類別(例如 FOSUserBundle 中的 User
實體)時,才能覆寫實體對應。可以透過這種方式覆寫屬性和關聯。在Doctrine 文件中瞭解更多關於此功能及其限制的資訊。
驗證元數據
Symfony 從每個 Bundle 載入所有驗證設定檔,並將它們組合成一個驗證元數據樹。這表示您可以為屬性新增新的約束,但您無法覆寫它們。
為了克服這個問題,第三方 Bundle 需要針對驗證群組進行設定。例如,FOSUserBundle 就有此設定。要建立您自己的驗證,請將約束新增到新的驗證群組
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 設定,使其使用您的驗證群組而不是原始群組。
翻譯
翻譯與 Bundle 無關,而是與翻譯域有關。因此,只要新檔案使用相同的域,您就可以從主要的 translations/
目錄覆寫任何 Bundle 翻譯檔案。
例如,要覆寫 AcmeUserBundle 的 translations/AcmeUserBundle.es.yaml
檔案中定義的翻譯,請建立 <your-project>/translations/AcmeUserBundle.es.yaml
檔案。