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 thoughts on “Grails: entendendo o SiteMesh

  1. 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.

  2. 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.

  3. 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!

  4. 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

  5. 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é

  6. 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

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

  8. 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.

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

Leave a Reply

Your email address will not be published. Required fields are marked *