如何扩展/覆盖插件的控制器操作?

Posted

技术标签:

【中文标题】如何扩展/覆盖插件的控制器操作?【英文标题】:How to extend/override controller actions of plugins? 【发布时间】:2011-01-11 12:59:22 【问题描述】:

我在 grails 应用程序中使用的插件 (Nimble 0.3) 包括一些控制器和相关操作。 我想(稍微)改变一些操作行为,我想知道如何才能做到这一点。

我可以创建一个从我的插件控制器继承的子控制器并覆盖一些操作实现吗?

或者,我可以创建另一个控制器与插件控制器同名,但位于不同的包中?

其实我真正需要了解的是:当存在名称冲突时,Grails 如何确定调用哪个控制器操作

【问题讨论】:

【参考方案1】:

使用 Grails 1.3.7 和 Nimble 插件 0.4,我发现 Burt 的 UrlMapping 解决方案对我不起作用。然而,根据 Burt 的other answer

class AuthController extends grails.plugins.nimble.core.AuthController

    private static String TARGET = 'grails.plugins.nimble.controller.AuthController.TARGET'

    def login = 
        // custom logic here    
    

【讨论】:

【参考方案2】:

假设您有一个名为 PluginController 的插件控制器和一个要覆盖的操作“foo”,您可以对控制器进行子类化:

class MyController extends PluginController 

   def foo = 
      ...
   

但你需要在 UrlMappings 中做一些工作:

class UrlMappings 

   static mappings = 
      "/$controller/$action?/$id?" 
         constraints 
      

      "/myController/foo/$id?"(controller: "myController", action: "foo")
      "/myController/$action?/$id?"(controller: "pluginController")
      "/pluginController/$action?/$id?"(controller: "errors", action: "urlMapping")

      "/"(view:"/index")
      "500"(view:'/error')
      "404"(controller: "errors", action: "notFound")
   

这取决于 ErrorsController:

class ErrorsController 

   def notFound = 
      log.debug "could not find $request.forwardURI"
   

   def urlMapping = 
      log.warn "unexpected call to URL-Mapped $request.forwardURI"
      render view: 'notFound'
   

如果您调用旧的“未映射”控制器操作,则会呈现 404 页面。您需要创建 grails-app/views/errors/notFound.gsp 以显示适当的 404 页面。

第一个 url 映射可确保调用您的覆盖操作。第二个将其他所有内容路由到原始控制器。第三个发送 404s 直接访问。

【讨论】:

Burt,如果插件定义了"404"(view:'/error'),我可以用我自己的“404”映射覆盖它,而是改用自定义控制器中的一个动作吗?【参考方案3】:

我将继承原始类并覆盖您需要的行为。我用另一个插件做了很多这样的事情,而且效果很好。

另一种方法当然是使用内联插件并仅修改原始源代码,但这更糟,因为您会遇到升级问题。

我也是 Nimble 的用户,如果您认为您的扩展程序可以被其他人使用,那么您可以做出贡献 - Nimble 肯定会尝试确保它非常可扩展。

【讨论】:

Jean,我实际上是对原始控制器进行子类化并覆盖一些操作,但 Grails 仍将我的请求路由到旧操作(而不是子类控制器操作)。为了使其工作,我需要更改内联插件中的操作名称。你知道如何强制 Grails 使用一个控制器动作而不是另一个吗?

以上是关于如何扩展/覆盖插件的控制器操作?的主要内容,如果未能解决你的问题,请参考以下文章

如何扩展 Shopware 6 控制器操作

从 Grails 插件覆盖控制器

Pimcore:如何覆盖内置控制器

这个回调如何对 cakePHP 组件起作用?

在 Redmine 核心视图中添加额外的 SQL 查询(插件中的覆盖视图)

关于扩展插件