0

Currently migrating an application from Grails 2.4.5 to Grails 3.2.6. We need the ability to modify the template path before rendering and have done this in Grails 2 BootStrap.groovy:

def init = { servletContext ->
    log.debug "Executing BootStrap init"
    //Modify all controllers to work for multiple tenants.
    grailsApplication.controllerClasses.each() { controllerClass ->
        log.debug "Modifying render method on controller ${controllerClass.name}"

        def oldRender = controllerClass.metaClass.pickMethod("render", [Map] as Class[])
        controllerClass.metaClass.render = { Map params ->
            log.debug "In bootstrap overridden method: "

            if (params.template && params.template.startsWith("/common")) {
                params.template = "/tenants" + params.template
                log.debug "Common template found " + params.template
            }
            else if (params.view && params.view.startsWith("/common")) {
                params.view = "/tenants" + params.view
                log.debug "Common view found " + params.view
            }
            else if (session.tenant) {
                if (params.template && params.template[0] == '/') {
                    log.debug "Template was " + params.template
                    params.template = "/tenants/" + session.tenant + params.template
                    log.debug "Template is " + params.template
                }
                if (params.view && params.view[0] == '/') {
                    log.debug "View was " + params.view
                    params.view = "/tenants/" + session.tenant + params.view
                    log.debug "View is " + params.view
                }
            }

            oldRender.invoke(delegate, [params] as Object[])
        }
    }

}

However, the modified render method never seems to be called in Grails 3.2.6. Any suggestions? I'm open to overriding the render method some other way if there is a better solution . . .

  • I think you could accomplish your goal with an interceptor. See the Web Layer chapter of the Grails Guide http://docs.grails.org/latest/guide/theWebLayer.html#interceptors – npskirk Feb 25 '17 at 13:16
  • I have an interceptor in place already. It doesn't fire on template rendering though . . . – John_OI Feb 25 '17 at 17:18
  • Have you tried overriding the render() methods in the interceptor? (Interceptor inherits from the trait ResponseRenderer) – npskirk Feb 26 '17 at 16:04
  • 1
    I would try to put this into a trait that extends ResponseRender and use the super functionality of traits to call the original method – James Kleeh Feb 27 '17 at 06:22
  • James - Duh! Just did exactly that, works perfectly. Loving the new traits . . . – John_OI Feb 27 '17 at 19:27

0 Answers0