我想了解有关自定义grails Controller generationg的更多信息,但是我找不到任何文档。

具体来说,我的动机是我正在使用旧数据库,并且这是只读的。因此,我想自定义代码生成,以便如果域类位于某个包中,例如:toppackage.readonly,则仅生成只读代码,仅生成 Controller 上的list和show方法。

我已经玩了一些,但我不确定它们是如何解析模板的。它们包含标签,并且似乎对语义空白敏感。

我知道脚手架的设计意图是为您提供一个起点,但是通常情况是稍后重新访问某些东西并进行更改,然后重新生成东西似乎是浪费的。在代码生成阶段,也必定存在特定于项目的约定。在我们的例子中,在代码生成阶段存在一些安全要求。

如何将变量注入(inject)代码模板?

标签如何评估?它是OGNL的一种形式吗?

我现在通过将域类放在名称为readonly且在 Controller 模板中为this的包中,以某种可怕的丑陋方式来执行此操作:

<%=!(packageName=~/\readonly/) ? """    def save = {\n
        def ${propertyName} = new ${className}(params)\n
        if (${propertyName}.save(flush: true)) {\n
            flash.message = \"\${message(code: 'default.created.message', args: [message(code: '${domainClass.propertyName}.label', default: '${className}'), ${propertyName}.id])}\"\n
            redirect(action: \"show\", id: ${propertyName}.id)\n
        }\n
        else {\n
            render(view: \"create\", model: [${propertyName}: ${propertyName}])\n
        }
    }""" : ''%>

最佳答案

以下应该工作:

执行grails install-templates以安装模板并对其进行修改(http://grails.org/doc/1.3.7/ref/Command%20Line/install-templates.html)

<% if (!packageName.contains("readonly")) { %>
    def save = {
        def ${propertyName} = new ${className}(params)
        if (${propertyName}.save(flush: true)) {
            flash.message = "\${message(code: 'default.created.message', args: [message(code: '${domainClass.propertyName}.label', default: '${className}'), ${propertyName}.id])}"
            redirect(action: "show", id: ${propertyName}.id)
        }
        else {
            render(view: "create", model: [${propertyName}: ${propertyName}])
        }
    }
<% } %>

您无需添加\n或转义"${..},除非您想在结果中生成这些内容(如消息)。

简而言之:
  • <% .. %>之外的所有内容都会打印到结果
  • 在脚手架
  • 期间会评估<% .. %>内的所有内容
  • ${..}之外的所有<% .. %>变量都将得到解析
  • <% .. %>内时,所有变量都得到解析,不需要${..}
  • 当您想让它们作为变量而不是作为解析值(\${..})生成时,需要转义变量

    关于grails - 为grails Controller 使用自定义脚手架?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8477344/

  • 10-10 21:29