如何利用Bundle的继承来重写Bundle局部

3.4 版本
维护中的版本

当使用第三方bundle时,你可能要面对这样一个局面,你需要覆写三方bundle的一个文件,用你自己的某个bundle中的文件来替代它。Symofny给了你一个非常简便的方式来覆写诸如控制器、模板以及其他一些存放在三方bundle Resource/目录下的文件。

例如,假定你要安装FOSUserBundle,但你需要覆写它的基础模板layout.html.twig,同时还要覆写它的某个控制器。同时假定你有自己的UserBundle,并希望把覆写的文件放在那里。首先,注册FOSUserBundle为你自己bundle的“parent”(父bundle):

1
2
3
4
5
6
7
8
9
10
11
12
// src/UserBundle/UserBundle.php
namespace UserBundle;
 
use Symfony\Component\HttpKernel\Bundle\Bundle;
 
class UserBundle extends Bundle
{
    public function getParent()
    {
        return 'FOSUserBundle';
    }
}

通过这个简单的改变,你现在可以覆写FOSUserBundle的某些部分了,只需创建同名文件即可。

尽管方法名(里面有parent字样),但并没有真实的父/子关系存在于两个bundle中,它仅仅是一个“扩展和覆写”既存bundle的方式。

覆写Controller 

假设你要添加一些功能到FOSUserBundle里面RegistrationController中的registerAction。要覆写它,只需创建你自己的RegistrationController.php,来覆写bundle的原始方法,并改变其功能:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// src/UserBundle/Controller/RegistrationController.php
namespace UserBundle\Controller;
 
use FOS\UserBundle\Controller\RegistrationController as BaseController;
 
class RegistrationController extends BaseController
{
    public function registerAction()
    {
        $response = parent::registerAction();
 
        // ... do custom stuff 进行一些操作
        return $response;
    }
}

根据你要改变其行为的力度,你可能要调用parent::registerAction(),或者用你自己的逻辑完全取代之。

用这种方式覆写控制器,仅在当前bundle所引用的是“在路由和模板中遵守了标准FOSUserBundle:Registration:register语法的bundle”时才有效。

覆写资源:模板,路由等 

多数资源都可以被覆写,直接在与parent bundle相同的位置创建文件即可。

例如,覆写FOSUserBundle的layout.html.twig模板是极为常见的,以便使用你自己的布局。由于文件存放在FOSUserBundleResources/views/layout.html.twig,你可以在UserBundle的相同位置创建你自己的文件。Symofny将完全忽略留在FOSUserBundle中的文件,而是使用你的。

路由和其他资源也是同理。

资源的覆写,仅在你引用的是“使用了@FOSUserBundle/Resources/config/routing/security.xml方法的资源”时才有效。如果你引用的资源没有使用@BundleName快捷方法,它们不会被以这种方式覆写。

翻译(Translation)和验证(Validation)文件,皆不在“用以上方法进行覆写”之列。如果你需要覆写translation文件,请参考“bundle覆写”中的“翻译”相关小节,同时参考“Validation Metadata”小节来了关于验证的覆写技巧。

本文,包括例程代码在内,采用的是 Creative Commons BY-SA 3.0 创作共用授权。

登录symfonychina 发表评论或留下问题(我们会尽量回复)