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!


por

Tags:

Comentários

13 respostas para “Grails: entendendo o SiteMesh”

  1. Avatar de Wanderson Santos
    Wanderson Santos

    Aeee entendeu o SiteMesh! Ele é muito bom! =)

  2. Avatar de Gustavo Lopes
    Gustavo Lopes

    Valew show de bola… é o mesmo conceito de facelets

    1. Avatar de admin
      admin

      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.

  3. Avatar de Amanda Gabriela Alves
    Amanda Gabriela Alves

    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.

    1. Avatar de admin
      admin

      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. Avatar de Rafael Augusto

    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

    1. Avatar de Rafael Augusto

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

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

  5. […] O SiteMesh cuida de aplicar o layout nas páginas GSPs como bem explica esse post do DevKiko. […]

  6. Avatar de André Valenti

    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é

  7. Avatar de Leonardo Rodrigo
    Leonardo Rodrigo

    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

    1. Avatar de Kico (Henrique Lobo Weissmann)
      Kico (Henrique Lobo Weissmann)

      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.

  8. Avatar de Leonardo Rodrigo
    Leonardo Rodrigo

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

    1. Avatar de Kico (Henrique Lobo Weissmann)
      Kico (Henrique Lobo Weissmann)

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

Deixe uma resposta

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