Grails: entendendo o SiteMesh

Ao aprender Grails um dos componentes que mais me confundiu foi o SiteMesh. Intuitivamente eu sabia o que estava acontecendo, mas toda vez que buscava escrever a respeito acabava me enrolando.

E acredite: você só conhece de fato algo se consegue descrevê-lo em palavras, por escrito. Trabalhando na última parte da minha série “Grails: do Groovy à Web” que está sendo publicada na Java Magazine tive a certeza de finalmente compreender de fato o que é o SiteMesh e como funciona. E a razão pela qual tinha tanta dificuldade é simples: estava viciado no Tiles.

Enquanto o Tiles é baseado no padrão composição (composite), o SiteMesh é baseado no padrão decorador (decorator).  A diferença entre os dois  é: no composite temos um layout central que contém uma série de espaços a serem preenchidos por  templates.

Já o padrão decorator possui um layout central que também possui espaços a serem preenchidos: a diferença é que apenas os elementos ausentes serão preenchidos. Eu não preciso adicionar todos os componentes tal como estava acostumado na época do Struts 1/Tiles.

Bla bla bla demais, é hora de irmos à prática. No Grails, todos os layouts do SiteMesh ficam armazenados no diretório grails-app/views/layouts. Por padrão já há um layout pré-definido, cujo nome é main.gsp armazenado neste diretório. É importante lembrar que se trata de um arquivo GSP convencional, cujo código exponho abaixo:

<html>
<head>
<title><strong><g:layoutTitle default="Grails" /></strong></title>
<link rel="stylesheet" href="${resource(dir:’css’,file:’main.css’)}" />
<link rel="shortcut icon" href="${resource(dir:’images’,file:’favicon.ico’)}" type="image/x-icon" />
<strong><g:layoutHead /></strong>
<g:javascript library="application" />
</head>
<body>
<div id="spinner" style="display:none;">
<img src="${resource(dir:’images’,file:’spinner.gif’)}" alt="Spinner" />
</div>
<div id="grailsLogo"><a href="http://grails.org"><img src="${resource(dir:’images’,file:’grails_logo.png’)}" alt="Grails" border="0" /></a></div>
<strong><g:layoutBody /></strong>
</body>
</html>

A única diferença entre o arquvo GSP e uma view convencional é a presença de três tags: g:layoutTitle, g:layoutHead, g:layoutBody. Falarei delas logo a seguir, porém antes de continuar, vou expor a view mais idiota possível: algo que não exponha basicamente nada, e cujo código fonte é o seguinte:


<html>
 <head>
 <meta name="layout" content="main"/>
 </head>
 <body>

 </body>
</html>

Colocando a aplicação para executar, e acessando-a, no entanto, é renderizado algo inicialmente inexperado:

De onde saiu este logotipo do Grails? Do layout main que defini anteriormente. No caso, eu instrui o Grails a usar o SiteMesh ao inserir a seguinte tag na minha view:


<meta name="layout" content="main"/>

Esta tag basicamente diz: “aplique o layout definido no arquivo grails-app/views/layouts/main.gsp a esta view”. E aqui entra a jusitificativa do mesh no nome SiteMesh: ao invés de incluir o conteúdo de um arquivo em outro, o que é feito na realidade é a fusão do conteúdo da view no corpo do layout!

Isto fica claro com a descrição das 3 tags que descrevi acima (consulte a primeira listagem para que fique claro):

g:layoutTitle – define qual será o conteúdo da tag title embutido na tag head. Repare qeu esta tag possui um atributo chamado “default”. Caso na view a tag title já esteja preenchida, será incluido no arquivo HTML final o conteúdo da tag title da view. Caso contrário, o conteúdo será aquele especificado no parâmetro default

g:layoutHead – o conteúdo da tag <head> da view será inserido no local do layout aonde a tag g:layoutHead se encontra.

g:layoutBody – o conteúdo da tag <body> da view será inserido no local do layout aonde a tag se encontra.

Resumindo: no SiteMesh não temos inclusão, mas sim fusão.

Espero que com esta descrição o recurso fique tão claro para vocês quanto pra mim.

Grande abraço e até a próxima!

13 Comments

Add Yours →

Valew show de bola… é o mesmo conceito de facelets

Responda

admin Reply:

OI Gustavo. Fico feliz que tenha gostado. Mas convém mencionar que não é exatamente a mesma coisa.

No Facelets você tem basicamente substituição de valores. No Sitemesh você tem fusão. Lembre-se disto.

Responda

Olá Kico, estou tentando aplicar um css no main.gsp, mas não estou conseguindo.
Sou iniciante em grails também. Estou qrendo customizar minha aplicação.

Responda

admin Reply:

Oi Amanda, faz o seguinte. Posta o seu problema com detalhes no Grails Brasil (porque tem mais espaço e gente pra ver o seu problema) e eu te ajudo ok?

Grande abraço!

Responda

Nós passamos por um problema causado pelo Sitemesh: o filter dele remove a funcionalidade de flush de uma respons text/html.

Explicando melhor: vamos supor que você queira fazer renderização parcial de páginas (como por exemplo faz o Facebook com a implementação de BigPipe) a medida que elas vão sendo processadas. É natural imaginar que o response.writer.flush faria o flush da resposta escrita até o momento. No entanto, o Sitemesh substitui o Writer da response por um que não realiza o flush até o fim do processamento (para poder fazer a fusão dos layouts)

Em resumo: caso você tenha alguma página que precisa fazer flush parcial, você vai querer configurar o sitemesh para excluí-la.

Solução: http://jira.grails.org/browse/GRAILS-5770

Responda

Rafael Augusto Reply:

Um link melhor descrevendo a solução do problema:

http://jira.grails.org/browse/GRAILS-5773

Responda

Olá Kico,

Não entendi a diferença entre composição e decoração. Poderia explicar melhor esta frase? “a diferença é que apenas os elementos ausentes serão preenchidos”

Obrigado!
André

Responda

E se no meu body, eu tiver vários blocos para inserção de código?
No meu caso, meu body tem side bar com um menu e o content.
Como faço nesse caso? Já que no meu layout, só coloco um
Poderia ter algo como e na outra parte do meu body, eu colocasse
E na minha pagina gsp, eu pudesse informar qual parte vai para o sidebar e qual vai para o content.
Existe alguma uma maneira de fazer isso?
Abs

Responda

Kico (Henrique Lobo Weissmann) Reply:

oi Leonardo, tem como postar esta sua duvida no Grails Brasil? é que costumo resolver este tipo dd duvida por la. assim ajudamos ao mesmo tempo pessoas que possuam a nesna duvida.

Responda

Nao sei porque, mas quando exemplifico com codigo html nao aparece nada no post

Responda

Kico (Henrique Lobo Weissmann) Reply:

Motor recente do blog. To melhorando isto aos poucos, valeu pelo toque.

Responda

Deixe um comentário

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.