レイアウトはgspビューでもあり、定義上、動的ビューのコンテンツを処理します。
ただし、gspファイルを直接編集して、実行時にコンパイルすることはお勧めできません。
代わりに、カスタマイズされたコンテンツが永続化され、事前定義されたgspレイアウトからロードされるドメインクラスを定義できます。
具体的には、次のドメインクラスのようなものを定義して、カスタムWeb要素を保存できます。
class Module {
Integer positionLeft
Integer positionTop
Integer width
Integer height
String className //CSS class
String border
String borderColor
Integer borderSize
Integer seq
String content
String type
static hasMany = [components: Component] //inner elements within a module
Module parentModule //support nested module structure to ensure flexibility
User owner
}
class Component {
String title
String content
String methodName
String url
String type //I-image,A-attachment,L-external link,T-text,G-graph report,D-data table,R RSS FEED...
String font
String fontFamily
String fontBold
String fontUnderline
String color
String textAlign
String source //uri -- enables ajax call to some method to get dynamic data
Integer seq
}
クライアント側のJavaScriptを使用すると、ユーザーはドラッグ、サイズ変更、一部のメニューからさまざまな要素タイプの選択、これらの要素のCRUD操作を実行するバックエンドコントローラーへの送信によって、カスタマイズされたビューを簡単に生成できます。
次に、レイアウトで、これらのカスタマイズされた要素を1つずつレンダリングします。
<%@ page import="com.app.Module" %>
<g:each in="${Module.findAllByOwnerAndParentModuleIsNull(session.user,[fetch:[components:'join']]).collect {[
id:it.id,
posLeft:it.posLeft,
posTop:it. posTop,
width:it.width,
height:it.height,
className:it.className,
border:it.border,
borderColor:it.borderColor,
borderSize:it.borderSize,
seq:it.seq,
content:it.content,
type:it.type,
components:it.components,
innerModules:Module.findAllByParentModule(it)
]}}" var="module" status="i">
<div class="${module.className?module.className:''}" style="position: absolute; left: ${module.posLeft}px; top: ${module.posTop}px; width: ${module.width}px; height: ${module.height}px; border: ${module.borderColor} ${module.borderSize?(module.borderSize+'px'):''} ${module.border};">
<g:each in="${module.innerModules}" var="inner">
<div class="${inner.className?inner.className:''}" style="position: absolute; left: ${inner.posLeft-module.posLeft}px; top: ${inner.posTop-module.posTop}px; width: ${inner.width}px; height: ${inner.height}px; border: blue 1px solid;">
<g:render template="/home/module" model="[
module: inner
]"/>
</div>
</g:each>
<g:render template="/home/module" model="[
module: module
]"/>
</div>
</g:each>
このようにして、各ユーザーはパーソナライズされたレイアウトを管理できます。