我有一个使用grails Multi-Tenancy 核心插件来托管站点的多个版本的应用程序。我希望能够为每个站点创建自定义的GSP,而不仅仅是简单的外观设置。本质上,我希望能够使grails-app/views
文件夹如下所示:
views
|
|__template1
| |
| |__layouts
| | |
| | |__main.gsp
| |
| |__controller1
| |
| |__index.gsp
|
|__template 2
|
|__layouts
| |
| |__main.gsp
|
|__controller1
|
|__index.gsp
然后配置特定的租户以使用一组特定的GSP。我使用的是持久化在我的数据库中的DNS解析器,因此我大概可以向
DomainTenantMap
域类添加一个属性,该属性将templateDir
属性分配给特定的租户,并在我的GSP和 Controller 中的各处散布条件逻辑。 (紧接着是“不能...得到...干净”的感觉)找到现有的可提供此功能的插件并没有取得任何成功。我考虑过的其他选项似乎涉及自定义相当核心的grails(渲染标签,模板引擎等),这让我感到紧张。
我意识到这是一个相当广泛的问题;无论是具体的解决方案还是一般性建议,都应得到赞赏。
编辑:
通过在新方法上创建插件和元编程,我找到了另一种可能的方法:
def configureTemplateRenderer(application, applicationContext) {
for (controllerClass in application.controllerClasses) {
controllerClass.metaClass.newRender = { args ->
println 'something'
if(args.view) {
args.view = "/somedir/${args.view}"
}
if(args.template) {
args.template = "/somedir/${args.template}"
}
delegate.render(args)
}
}
}
这只是一个概念证明,看看我是否可以通过我的新方法调用标准
render
方法(可以)。理想情况下,我可以完全重写render
方法,以基于某种类型的租户/模板映射(未显示)来修改args.view
和args.template
属性。但是,我无法成功覆盖render
方法,因此,此解决方案实际上仅比在某些路径变量上撒些对render
的调用要好。解决方案!
我最终创建了一个单独的插件,该插件实质上可以归结为使用可检查租户/模板映射的render方法。仍在测试中,但到目前为止看起来很有希望,这是要点:
def overrideRender = { application ->
for (controllerClass in application.controllerClasses) {
def original = controllerClass.metaClass.getMetaMethod("render", [Map] as Class[])
def originalRender = original.getClosure()
controllerClass.metaClass.originalRender = originalRender
controllerClass.metaClass.render = { Map atts ->
def templatePath = // some code to lookup against a TenantTenantMap
if(templatePath) {
if(atts.view) {
atts.view = "${templatePath}${atts?.view}"
}
if(atts.template) {
atts.template = "${templatePath}${atts?.template}"
}
}
delegate.originalRender(atts)
}
}
}
唯一的缺点是我必须使用比我想要的稍微难看的目录结构:
views/controller/$template/action
,而不是在views/$template/controller/action
下将所有模板gsps组合在一起。我想我现在可以忍受。 最佳答案
我使用的解决方案:
def overrideRender = { application ->
for (controllerClass in application.controllerClasses) {
def original = controllerClass.metaClass.getMetaMethod("render", [Map] as Class[])
def originalRender = original.getClosure()
controllerClass.metaClass.originalRender = originalRender
controllerClass.metaClass.render = { Map atts ->
def templatePath = // some code to lookup against a TenantTenantMap
if(templatePath) {
if(atts.view) {
atts.view = "${templatePath}${atts?.view}"
}
if(atts.template) {
atts.template = "${templatePath}${atts?.template}"
}
}
delegate.originalRender(atts)
}
}
}
关于grails - 通过Grails Multi-Tenancy 核心插件使用多个GSP模板/皮肤?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7417251/