Por padrão, podemos criar dois tipos de arquivos de layouts no Rails:
- Layout para controllers
- Layout para a aplicação inteira
nome_do_controller.html.erb
Por exemplo:
albums.html.erb
Um exemplo simples do conteúdo desse arquivo seria o seguinte:

Aonde invocamos o método yield será exibido o conteúdo da view da página que estará sendo acessada.
Se criarmos um arquivo parecido mas com o nome de application.html.erb, esse layout irá ser exibido em todas as páginas da aplicação, a menos que exista um arquivo de layout para o controller em questão (como mencionado acima) ou tenha sido informado de forma explícita um outro layout a ser exibido (demonstrarei como em breve).
O que acontece é que muitas vezes precisamos de dois ou mais layouts diferentes em nossa aplicação, mas parte desses layouts são iguais entre si. E replicar essas partes iguais em todos os layouts fere o princípio de DRY (Don't Repeat Yourself) e acaba causando uma série de retrabalhos.
Imagine que você altere essa parte repetida do layout em um dos arquivos e esquece de mudar nos demais?
Para isso, vou lhes apresentar uma solução que utilizei esses dias em uma aplicação minha. Na verdade encontrei essa solução no endereço abaixo, e apenas dei uma pequena adaptada para ficar mais fácil de trabalhar:
http://blog.jerodsanto.net/2008/06/rails-nested-layouts
Imagine que o layout de nosso site é parecido com a figura abaixo:
Onde possuímos um espaço para o logotipo, um espaço para o conteúdo e um espaço para uma sidebar que contém o menu.
Agora imagine que em determinada parte do sites precisamos exibir algumas fotografias grandes, e seria preciso retirar o sidebar para poupar espaço.
Para não termos que criar dois layouts praticamente idênticos, faremos eles com apenas as partes que são diferentes, e o que for igual deixaremos em um layout separado, o qual os dois incluirão. Conforme demonstrado na figura:
Podemos chamar isso de layouts aninhados, ou, no termo em inglês, nested layouts. Onde dois layouts simples herdam informações de um layout que trás informações comuns aos dois.
Para nos ajudar a implementar nossa solução utilizaremos um helper do Rails chamado content_for.
Com content_for podemos armazenar o conteúdo de uma determinada parte do nosso site para ser exibida depois em algum lugar específico, por exemplo:

O que é armazenado dentro do bloco do helper content_for é exibido depois em:
<%= yield :list %>Então para solucionar nosso problema nós iremos criar dois layouts:
- application.html.erb (que contém o sidebar e será exibido em todas as páginas da aplicação)
- expanded_content.html.erb (que será exibido apenas nas páginas que precisam de mais espaço para o conteúdo)
- base.html.erb
application.html.erb

expanded_content.html.erb

base.html.erb

Eu coloquei o conteúdo do sidebar dentro de um partial, para melhorar a visualização do exemplo.
Do jeito que está, todas as views serão exibidas utilizando o layout application.html.erb, uma vez que ele é o layout padrão da aplicação e "expanded_content" não é o nome de um controller.
Então como eu faço para utilizar o layout expanded_content.html.erb?
Você tem duas opções:
1) Se você deseja aplicar este layout à todas as views de um determinado controller, basta adicionar a seguinte linha no controller:
layout 'expanded_content'Exemplo:

2) Se você deseja aplicar esse layout apenas a uma determinada action de seu controller, basta informar o layout na hora de renderizar a view, exemplo:

Com isso não duplicamos código e podemos administrar melhor nossa aplicação.
Gostaria de agradecer ao Shairon Toledo que me falou da existência do content_for la no grupo rails-br.
Espero que tenho gostado da dica.
Qualquer dúvida podem entrar em contato (e-mail, comentário, twitter).
Abraços!




2 comentários:
Bem legal o Post Bruno! Eu realmente precisava de um exemplo de como usar o contents_for. Excelente trabalho! Grande Abraço,
Leo
Show de bola!!!
Ajudou muito!
Postar um comentário