Criando um layout consistente em sites de Páginas da Web do ASP.NET (Razor)
por Tom FitzMacken
Este artigo explica como você pode usar páginas de layout em um site do Páginas da Web do ASP.NET (Razor) para criar blocos reutilizáveis de conteúdo (como cabeçalhos e rodapés) e criar uma aparência consistente para todas as páginas do site.
O que você aprenderá:
- Como criar blocos reutilizáveis de conteúdo, como cabeçalhos e rodapés.
- Como criar uma aparência consistente para todas as páginas em seu site usando um layout.
- Como passar dados em tempo de execução para uma página de layout.
Estes são os ASP.NET recursos introduzidos no artigo:
- Blocos de conteúdo, que são arquivos que contêm conteúdo formatado em HTML a ser inserido em várias páginas.
- Páginas de layout, que são páginas que contêm conteúdo formatado em HTML que podem ser compartilhadas por páginas no site.
- Os
RenderPage
métodos ,RenderBody
eRenderSection
, que informam ASP.NET onde inserir elementos de página.- O
PageData
dicionário que permite compartilhar dados entre blocos de conteúdo e páginas de layout.Versões de software usadas no tutorial
- Páginas da Web do ASP.NET (Razor) 3
Este tutorial também funciona com Páginas da Web do ASP.NET 2.
Sobre páginas de layout
Muitos sites têm conteúdo exibido em cada página, como um cabeçalho e rodapé, ou uma caixa que informa aos usuários que eles estão conectados. ASP.NET permite criar um arquivo separado com um bloco de conteúdo que pode conter texto, marcação e código, assim como uma página da Web normal. Em seguida, você pode inserir o bloco de conteúdo em outras páginas no site em que deseja que as informações apareçam. Dessa forma, você não precisa copiar e colar o mesmo conteúdo em todas as páginas. A criação de conteúdo comum como esse também facilita a atualização do seu site. Se você precisar alterar o conteúdo, basta atualizar um único arquivo e as alterações serão refletidas em todos os lugares em que o conteúdo foi inserido.
O diagrama a seguir mostra como os blocos de conteúdo funcionam. Quando um navegador solicita uma página do servidor Web, ASP.NET insere os blocos de conteúdo no ponto em que o RenderPage
método é chamado na página main. A página concluída (mesclada) é enviada para o navegador.
Neste procedimento, você criará uma página que faz referência a dois blocos de conteúdo (um cabeçalho e um rodapé) localizados em arquivos separados. Você pode usar esses mesmos blocos de conteúdo em qualquer página do seu site. Quando terminar, você receberá uma página como esta:
Na pasta raiz do seu site, crie um arquivo chamado Index.cshtml.
Substitua a marcação existente pelo seguinte:
<!DOCTYPE html> <html> <head> <title>Main Page</title> </head> <body> <h1>Index Page Content</h1> <p>This is the content of the main page.</p> </body> </html>
Na pasta raiz, crie uma pasta chamada Compartilhado.
Observação
É uma prática comum armazenar arquivos que são compartilhados entre páginas da Web em uma pasta chamada Compartilhado.
Na pasta Compartilhado , crie um arquivo chamado _Header.cshtml.
Substitua qualquer conteúdo existente pelo seguinte:
<div class="header">This is header text.</div>
Observe que o nome do arquivo é _Header.cshtml, com um sublinhado (_) como prefixo. ASP.NET não enviará uma página para o navegador se seu nome começar com um sublinhado. Isso impede que as pessoas solicitem (inadvertidamente ou não) essas páginas diretamente. É uma boa ideia usar um sublinhado para nomear páginas que têm blocos de conteúdo, porque você realmente não quer que os usuários possam solicitar essas páginas — elas existem estritamente para serem inseridas em outras páginas.
Na pasta Compartilhado , crie um arquivo chamado _Footer.cshtml e substitua o conteúdo pelo seguinte:
<div class="footer">© 2012 Contoso Pharmaceuticals. All rights reserved. </div>
Na página Index.cshtml , adicione duas chamadas ao
RenderPage
método , conforme mostrado aqui:<!DOCTYPE html> <html> <head> <title>Main Page</title> </head> <body> @RenderPage("~/Shared/_Header.cshtml") <h1>Index Page Content</h1> <p>This is the content of the main page.</p> @RenderPage("~/Shared/_Footer.cshtml") </body> </html>
Isso mostra como inserir um bloco de conteúdo em uma página da Web. Chame o
RenderPage
método e passe o nome do arquivo cujo conteúdo você deseja inserir nesse ponto. Aqui, você está inserindo o conteúdo dos arquivos _Header.cshtml e _Footer.cshtml no arquivo Index.cshtml .Execute a página Index.cshtml em um navegador. (No WebMatrix, no workspace Arquivos , clique com o botão direito do mouse no arquivo e selecione Iniciar no navegador.)
No navegador, exiba a origem da página. (Por exemplo, na Internet Explorer, clique com o botão direito do mouse na página e clique em Exibir Fonte.)
Isso permite que você veja a marcação de página da Web enviada para o navegador, que combina a marcação de página de índice com os blocos de conteúdo. O exemplo a seguir mostra a origem da página renderizada para Index.cshtml. As chamadas para
RenderPage
que você inseriu em Index.cshtml foram substituídas pelo conteúdo real dos arquivos de cabeçalho e rodapé.<!DOCTYPE html> <html> <head> <title>Main Page</title> </head> <body> <div class="header"> This is header text. </div> <h1>Index Page Content</h1> <p>This is the content of the main page.</p> <div class="footer"> © 2012 Contoso Pharmaceuticals. All rights reserved. </div> </body> </html>
Criando uma aparência consistente usando páginas de layout
Até agora, você viu que é fácil incluir o mesmo conteúdo em várias páginas. Uma abordagem mais estruturada para criar uma aparência consistente para um site é usar páginas de layout. Uma página de layout define a estrutura de uma página da Web, mas não contém nenhum conteúdo real. Depois de criar uma página de layout, você pode criar páginas da Web que contêm o conteúdo e vinculá-las à página de layout. Quando essas páginas forem exibidas, elas serão formatadas de acordo com a página de layout. (Nesse sentido, uma página de layout atua como um tipo de modelo para conteúdo definido em outras páginas.)
A página de layout é como qualquer página HTML, exceto que ela contém uma chamada para o RenderBody
método . A posição do RenderBody
método na página de layout determina onde as informações da página de conteúdo serão incluídas.
O diagrama a seguir mostra como páginas de conteúdo e páginas de layout são combinadas em tempo de execução para produzir a página da Web concluída. O navegador solicita uma página de conteúdo. A página de conteúdo tem código que especifica a página de layout a ser usada para a estrutura da página. Na página de layout, o conteúdo é inserido no ponto em que o RenderBody
método é chamado. Os blocos de conteúdo também podem ser inseridos na página de layout chamando o RenderPage
método , como você fez na seção anterior. Quando a página da Web é concluída, ela é enviada para o navegador.
O procedimento a seguir mostra como criar uma página de layout e vincular páginas de conteúdo a ela.
Na pasta Compartilhado do seu site, crie um arquivo chamado _Layout1.cshtml.
Substitua qualquer conteúdo existente pelo seguinte:
<!DOCTYPE html> <html> <head> <title>Structured Content </title> <link href="~/Styles/Site.css" rel="stylesheet" type="text/css" /> </head> <body> @RenderPage("~/Shared/_Header2.cshtml") <div id="main"> @RenderBody() </div> <div id="footer"> © 2012 Contoso Pharmaceuticals. All rights reserved. </div> </body> </html>
Use o
RenderPage
método em uma página de layout para inserir blocos de conteúdo. Uma página de layout pode conter apenas uma chamada para oRenderBody
método .Na pasta Compartilhado , crie um arquivo chamado _Header2.cshtml e substitua qualquer conteúdo existente pelo seguinte:
<div id="header">Creating a Consistent Look</div>
Na pasta raiz, crie uma nova pasta e nomeie-a como Estilos.
Na pasta Estilos , crie um arquivo chamado Site.css e adicione as seguintes definições de estilo:
h1 { border-bottom: 3px solid #cc9900; font: 2.75em/1.75em Georgia, serif; color: #996600; } ul { list-style-type: none; } body { margin: 0; padding: 1em; background-color: #ffffff; font: 75%/1.75em "Trebuchet MS", Verdana, sans-serif; color: #006600; } #list { margin: 1em 0 7em -3em; padding: 1em 0 0 0; background-color: #ffffff; color: #996600; width: 25%; float: left; } #header, #footer { margin: 0; padding: 0; color: #996600; }
Essas definições de estilo estão aqui apenas para mostrar como as folhas de estilos podem ser usadas com páginas de layout. Se desejar, você pode definir seus próprios estilos para esses elementos.
Na pasta raiz, crie um arquivo chamado Content1.cshtml e substitua qualquer conteúdo existente pelo seguinte:
@{ Layout = "~/Shared/_Layout1.cshtml"; } <h1> Structured Content </h1> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
Esta é uma página que usará uma página de layout. O bloco de código na parte superior da página indica qual página de layout usar para formatar esse conteúdo.
Execute Content1.cshtml em um navegador. A página renderizada usa o formato e a folha de estilos definidos em _Layout1.cshtml e o texto (conteúdo) definido em Content1.cshtml.
Você pode repetir a etapa 6 para criar páginas de conteúdo adicionais que podem compartilhar a mesma página de layout.
Observação
Você pode configurar seu site para que possa usar automaticamente a mesma página de layout para todas as páginas de conteúdo em uma pasta. Para obter detalhes, consulte Personalizando o comportamento de Site-Wide para Páginas da Web do ASP.NET.
Criando páginas de layout que têm várias seções de conteúdo
Uma página de conteúdo pode ter várias seções, o que é útil se você quiser usar layouts que tenham várias áreas com conteúdo substituível. Na página de conteúdo, você atribui um nome exclusivo a cada seção. (A seção padrão é deixada sem nome.) Na página de layout, você adiciona um RenderBody
método para especificar onde a seção sem nome (padrão) deve aparecer. Em seguida, você adiciona métodos separados RenderSection
para renderizar seções nomeadas individualmente.
O diagrama a seguir mostra como ASP.NET lida com o conteúdo dividido em várias seções. Cada seção nomeada está contida em um bloco de seção na página de conteúdo. (Eles são nomeados Header
e List
no exemplo.) A estrutura insere a seção de conteúdo na página de layout no ponto em que o RenderSection
método é chamado. A seção sem nome (padrão) é inserida no ponto em que o RenderBody
método é chamado, como você viu anteriormente.
Este procedimento mostra como criar uma página de conteúdo que tem várias seções de conteúdo e como renderizá-la usando uma página de layout que dá suporte a várias seções de conteúdo.
Na pasta Compartilhado , crie um arquivo chamado _Layout2.cshtml.
Substitua qualquer conteúdo existente pelo seguinte:
<!DOCTYPE html> <html> <head> <title>Multisection Content</title> <link href="~/Styles/Site.css" rel="stylesheet" type="text/css" /> </head> <body> <div id="header"> @RenderSection("header") </div> <div id="list"> @RenderSection("list") </div> <div id="main"> @RenderBody() </div> <div id="footer"> © 2012 Contoso Pharmaceuticals. All rights reserved. </div> </body> </html>
Use o
RenderSection
método para renderizar as seções de cabeçalho e lista.Na pasta raiz, crie um arquivo chamado Content2.cshtml e substitua qualquer conteúdo existente pelo seguinte:
@{ Layout = "~/Shared/_Layout2.cshtml"; } @section header { <div id="header"> Creating a Consistent Look </div> } @section list { <ul> <li>Lorem</li> <li>Ipsum</li> <li>Dolor</li> <li>Consecte</li> <li>Eiusmod</li> <li>Tempor</li> <li>Incididu</li> </ul> } <h1>Multisection Content</h1> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
Esta página de conteúdo contém um bloco de código na parte superior da página. Cada seção nomeada está contida em um bloco de seção. O restante da página contém a seção de conteúdo padrão (sem nome).
Execute Content2.cshtml em um navegador.
Tornando as seções de conteúdo opcionais
Normalmente, as seções criadas em uma página de conteúdo precisam corresponder às seções definidas na página de layout. Você poderá receber erros se qualquer um dos seguintes itens ocorrer:
- A página de conteúdo contém uma seção que não tem nenhuma seção correspondente na página de layout.
- A página de layout contém uma seção para a qual não há conteúdo.
- A página de layout inclui chamadas de método que tentam renderizar a mesma seção mais de uma vez.
No entanto, você pode substituir esse comportamento para uma seção nomeada declarando a seção como opcional na página de layout. Isso permite definir várias páginas de conteúdo que podem compartilhar uma página de layout, mas que podem ou não ter conteúdo para uma seção específica.
Abra Content2.cshtml e remova a seguinte seção:
@section header { <div id="header"> Creating a Consistent Look </div> }
Salve a página e execute-a em um navegador. Uma mensagem de erro é exibida porque a página de conteúdo não fornece conteúdo para uma seção definida na página de layout, ou seja, a seção de cabeçalho.
Na pasta Compartilhado , abra a página _Layout2.cshtml e substitua esta linha:
@RenderSection("header")
pelo código a seguir:
@RenderSection("header", required: false)
Como alternativa, você pode substituir a linha de código anterior pelo seguinte bloco de código, que produz os mesmos resultados:
@if (IsSectionDefined("header")) { @RenderSection("header") }
Execute a página Content2.cshtml em um navegador novamente. (Se você ainda tiver essa página aberta no navegador, basta atualizá-la.) Desta vez, a página é exibida sem erro, mesmo que não tenha cabeçalho.
Passando dados para páginas de layout
Você pode ter dados definidos na página de conteúdo que você precisa consultar em uma página de layout. Nesse caso, você precisa passar os dados da página de conteúdo para a página de layout. Por exemplo, talvez você queira exibir o status de logon de um usuário ou pode querer mostrar ou ocultar áreas de conteúdo com base na entrada do usuário.
Para passar dados de uma página de conteúdo para uma página de layout, você pode colocar valores na PageData
propriedade da página de conteúdo. A PageData
propriedade é uma coleção de pares nome/valor que contém os dados que você deseja passar entre páginas. Na página de layout, você pode ler valores fora da PageData
propriedade .
Aqui está outro diagrama. Este mostra como ASP.NET pode usar a PageData
propriedade para passar valores de uma página de conteúdo para a página de layout. Quando ASP.NET começa a criar a página da Web, ela cria a PageData
coleção. Na página de conteúdo, você escreve código para colocar dados na PageData
coleção. Os valores na PageData
coleção também podem ser acessados por outras seções na página de conteúdo ou por blocos de conteúdo adicionais.
O procedimento a seguir mostra como passar dados de uma página de conteúdo para uma página de layout. Quando a página é executada, ela exibe um botão que permite que o usuário oculte ou mostre uma lista definida na página de layout. Quando os usuários clicam no botão, ele define um valor verdadeiro/falso (booliano) na PageData
propriedade . A página de layout lê esse valor e, se for falso, oculta a lista. O valor também é usado na página de conteúdo para determinar se o botão Ocultar Lista ou Mostrar Lista deve ser exibido.
Na pasta raiz, crie um arquivo chamado Content3.cshtml e substitua qualquer conteúdo existente pelo seguinte:
@{ Layout = "~/Shared/_Layout3.cshtml"; PageData["Title"] = "Passing Data"; PageData["ShowList"] = true; if (IsPost) { if (Request.Form["list"] == "off") { PageData["ShowList"] = false; } } } @section header { <div id="header"> Creating a Consistent Look </div> } <h1>@PageData["Title"]</h1> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> @if (PageData["ShowList"] == true) { <form method="post" action=""> <input type="hidden" name="list" value="off" /> <input type="submit" value="Hide List" /> </form> } else { <form method="post" action=""> <input type="hidden" name="list" value="on" /> <input type="submit" value="Show List" /> </form> }
O código armazena duas partes de dados na
PageData
propriedade : o título da página da Web e true ou false para especificar se uma lista deve ser exibida.Observe que ASP.NET permite colocar a marcação HTML na página condicionalmente usando um bloco de código. Por exemplo, o
if/else
bloco no corpo da página determina qual formulário exibir dependendo se está definido comoPageData["ShowList"]
true.Na pasta Compartilhado , crie um arquivo chamado _Layout3.cshtml e substitua qualquer conteúdo existente pelo seguinte:
<!DOCTYPE html> <html> <head> <title>@PageData["Title"]</title> <link href="~/Styles/Site.css" rel="stylesheet" type="text/css" /> </head> <body> <div id="header"> @RenderSection("header") </div> @if (PageData["ShowList"] == true) { <div id="list"> @RenderPage("~/Shared/_List.cshtml") </div> } <div id="main"> @RenderBody() </div> <div id="footer"> <p>© 2012 Contoso Pharmaceuticals. All rights reserved.</p> </div> </body> </html>
A página de layout inclui uma expressão no
<title>
elemento que obtém o valor do título daPageData
propriedade . Ele também usa oShowList
valor daPageData
propriedade para determinar se o bloco de conteúdo da lista deve ser exibido.Na pasta Compartilhado , crie um arquivo chamado _List.cshtml e substitua qualquer conteúdo existente pelo seguinte:
<ul> <li>Lorem</li> <li>Ipsum</li> <li>Dolor</li> <li>Consecte</li> <li>Eiusmod</li> <li>Tempor</li> <li>Incididu</li> </ul>
Execute a página Content3.cshtml em um navegador. A página é exibida com a lista visível no lado esquerdo da página e um botão Ocultar Lista na parte inferior.
Clique em Ocultar Lista. A lista desaparece e o botão é alterado para Mostrar Lista.
Clique no botão Mostrar Lista e a lista será exibida novamente.
Recursos adicionais
Personalizando o comportamento de Site-Wide para Páginas da Web do ASP.NET