Fala, galera

Continuando a falar sobre a view engine Razor, nest post o assunto será “Layout Pages”, um conceito que já existe desde o ASP.NET 2.0 com as “Master Pages”.

Como sabemos, as master pages permitem que tenhamos um layout consistente por todas as páginas de nossa aplicação. No Razor, veremos como é bem simples a utilização das mesmas e com o nome bem mais apropriado de Layout Pages.

Quando criamos um novo projeto ASP.NET MVC 3, temos por padrão a layout page _Layout.cshtml (ou vbhtml no VB.NET) criada em \Views\Shared. O conteúdo da mesma será algo como:

Notem acima que a layout page chama o helper RenderBody. É ali que “entrará” o conteúdo das views que utilizarem esta layout page, de forma idêntica ao já conhecido <asp:ContentPlaceHolder> do WebForms.

Lembrando que você pode criar várias outras layout pages e até renomear a layout page default, retirando inclusive o “_” do início do nome.

Pois bem. Resta-nos criar uma view que utilize a layout page acima. Começamos criando um controller qualquer, por exemplo, HomeController. O controller será criado com, pelo menos, a action Index. Clicando com o botão direito dentro dessa action e indo em “Add View…” teremos a seguinte dialog:

Para escolhermos uma layout page para essa view, marcamos o checkbox “Use a layout or master page” e digitamos no campo logo abaixo o caminho da layout page ou a escolhemos pelo botão “…” ao lado do campo. (Mais abaixo falarei sobre a observação “Leave empty…” situada abaixo do campo que define a layout page.)

Clicamos em “Add” e criamos a view, que apresentará o seguinte conteúdo:

Observe na terceira linha do arquivo que a view define qual layout page está usando “setando” a propriedade Layout.

ViewStart

Como eu já havia dito <aqui>, podemos usar a view start para definirmos a layout page de forma global. Para isso, no arquivo _ViewStart.cshtml, definimos a nossa layout page (Layout = “~/Views/Shared/_Layout.cshtml”) e removemos a configuração da propriedade Layout das views que forem utilizar a layout page definida na view start.

Sendo assim, quando formos criar uma view (veja a dialog “Add View” mostrada acima) e quisermos usar a layout page “default” definida na view start, marcamos o check box “Use a layout or master page” e deixamos em branco o campo onde deveria estar o nome da layout page. É o que explica a observação “Leave empty if it is set in a Razor _viewstart file”.

Adicionando seções às layout pages

É possível deixar o layout das páginas ainda mais flexível por meio da adição de seções nas layout pages. As seções são áreas que também são preenchidas por conteúdo das views e são definidas usando-se o helper RenderSection.

Ao contrário de RenderBody, RenderSection pode ser definido mais de uma vez na layout page e seu conteúdo pode ser opcional, ou seja, nem toda view é obrigada a gerar conteúdo para uma seção opcional.

Veremos como isso funciona definindo duas seções na nossa layout page:

Notem que criamos 2 seções, com os nomes “cabecalho” e “rodape” respectivamente. Percebam também que o 2º parâmetro em ambos os helpers, definido como “false”, informa que essas seções NÃO são obrigatórias.

Vamos agora alterar a view Index para exibir algo nessas duas seções:

Relembrando: definimos o conteúdo das DUAS seções, mas poderíamos ter deixado de lado qualquer uma delas, uma vez que na layout page dissemos que ambas não são obrigatórias.

Detalhe que o nome de cada seção – após o @section – deve ser o mesmo nome dado no RenderSection na layout page.

Outro detalhe é que ambas as seções são definidas no início da view, ou seja, antes do corpo da view (<h2>Index</h2>) e não obrigatoriamente na mesma posição dos equivalentes RenderSection na layout page. Em outras palavras, elas podem estar definidas em qualquer lugar da view, que o conteúdo sempre será renderizado exatamente no local que você definiu na layout page.

Sendo assim, a view Index será renderizada assim:

conteudo da seção "cabecalho"
Index
conteudo da seção "rodape"

Com isso vimos como utilizar layout pages no Razor, utilizando os helpers RenderBody e RenderSection.

Simples, não é?

Até a próxima!