ASP.NET MVC 3: Layouts con Razor

Hace dos semaqnas que publicamos ASP.NET MVC 3 Beta. Soporta desarrollos "go live", e incluye un montón de mejoras. Podéis ver un resumen de las características de ASP.NE T MVC 3 en el post que escribir. Leed también el post original de ASP.NET MVC 3 para aprender otras características que mostrarmos al principio.

Este es otro de una serie de "mini-post" que estoy haciendo sobre ASP.NET MVC 3 y sus caracterísitcias:

En el post de hoy veremos las páginas de layout con Razor, y veremos algunas de las mejoras que hemos introducido en ASP.NET MVC.

Razor Basics

ASP.NET MVC 3 viene con la opción de un nuevo motor de vistas llamado “Razor” (Además de soportar y amplicar el motor actual de .aspx).

Podéis aprender más sobre Razor, porqué lo hemos introducido, y la sintaxis que soporta en mi post de Introducción a Razor. Si aún no lo habéis leído, tomaros unos minutos y hacedlo ahora (ya que el resto del post asumirá que lo habéis leido).

Una vez que lo hayais leído, leed también el de ASP.NET MVC 3 Preview y ved el ejemplo con Razor que introduje.

¿Qué son los layouts?

Normalmente queremos mantener un look & feel consistente en todas las páginas de nuestro sitio web. ASP.NET 2.0 introdujo el concepto de "master pages" que nos permite conseguir esto usando páginas .aspx o plantillas. Razor también soporta este concepto con la nueva característica llamada "layout" - que nos permite definir una plantilla común, y hereda el look & feel en todas las vistas/páginas de nuestro sitio.

Uso de layouts con Razor

En mi post anterior vimos un ejemplo en el que implementábamos una URL /Products que renderizaba una lista de categorías de productos:

Aquí tenéis una implementación simple de ProductsController que implementa la url /Products anterior. Obtiene una lista de categorías de productos de la base de datos, y la pasa a la vista para renderizar el HTML al navegador:

Aquí tenéis el archivo de la vista index.cshtml (implementado con Razor):

La vista anterior no usa todavía una página de layout - lo que significa que a medida que añadimos URLs y páginas terminaremos duplicando el layout de nuestro sitio en varias partess. Usar un layout nos permitirá evitar esta duplicación y hara mucho más sencillo administrar el diseño de nuestro sitio. Vamos a actualizar nuestro ejemplo para que use uno.

Refactoring par ausar un Layout.

Razor hace realmente fácil comenzar desde una página existente y refactorizarla para que use un layout. Vamos a hacerlo en el ejemplo anterior. El primer paso será añadir un archivo SiteLayout.cshtml a nuestro proyecto en el directorio ViewsShader (que es el lugar por defecto en el que están todas las vistas y plantillas):

SiteLayout.cshtml

Usaremos el archivo SiteLayout.cshtml para definir el contenido común de nuestro sitio. Aquí tenéis un ejemplo de cómo sería:

Un par de detalles sobre el archivo anterior:

  • No es necesario tener la directiva @inherits al principio del archivo. Podemos tenerla si queremos (por ejemplo: si queremos una clase base personalizada), pero no es necesario. Esto ayuda a mantener el archivo limpio. También hace más sencillo tener diseñadores trabajando en el archivo sin tener que entender conceptos que no entienden.
  • Estamos llamando al método @RenderBody() para indicar que queremos que las vistas basadas en este layour rellenen su contenido en ese lugar del HTML.
  • Estamos sacando la propiedad "View.Title" en el elemento <title> de nuestra sección <head>. Veremos cómo se usa esto en un momento.

Y ahora tenemos una plantilla de layout que podemos usar para mantener un look & feel consistente en el resto del sitio.

Index.cshtml

Ahora vamos a actualizar nuestra vista Index.cshtml para que se base en el archivo SiteLayout.cshtml que acabamos de crear. Aquí teneis una primera aproximación sobre cómo sería:

Un par de cosas sobre este archivo:

  • No necesitamos encapsular el contenido en ningún tag - por defecto Razor tratará el contenido de Index.cshtml como la sección "body" del layout. Podemos definir secciones con nombre si nuestro layout tiene varias regiones. Pero Razor hace que sea mucho más limpio.
  • Estamos estableciendo programáticamente el valor View.Title en el archivo Index.cshtml. El código de Index.cshtml se ejecutará ántes que el código de SiteLayout.cshtml - de manera que podemos escribir el código para que nuestra vista le pasae valores al layout. Esto es particularmente útil para cosas como poner el título de la página, así como elementos <meta> en el <head> para optimizaciones en motores de búsqueda (SEO).
  • Por ahora, estamos estableciendo programáticamente la plantilla Layout para que la use nuestro archivo Index.cshtml. Podemos hacer esto estableciendo la propiedad Layout en nuestra Vista (nota: en la primera preview esta propiedad se llamaba "LayoutPage" - la cambiamos a "Layout" en ASP.NET MVC 3). Veremos algunas formas diferentes (nuevas en ASP.NE TMVC 3 Beta) para establecer esta propeidad.

Y ahora cuando pedimos la URL /Products en nuestro sitio, tendremos el siguiente HTML:

Fijáos que el HTMl contenido es una mezcla de SiteLayout.cshtml y Index.cshtml. El título "Products Categories" al principio se establece correctamente en la vista, y que la lista dinámica de categorías se calcula en el lugar adecuado.

DRY con _ViewStart

Actualmente estamos estableciendo programáticamente el archivo de layout para que se use al principio del archivo Index.cshtml. Esto es adecuado en casos en los que tenemos una lógica de vista específica en el que el archivo de layout varía dependiendo de la vista particular. Pero establecer esto de esta forma puede terminar en algo redundante en muchas aplicaciones web - en el que todas las vistas usen el mismo layout, o si hay varios layout (por ejepmlo: para dispositivos móbiles o sitios localizados) la lógica de obtener el layout es común en todas las vistas.

Las buenas noticias es que Razor incluye una nueva característica que nos permite eliminar la necesidad de establecer esplícitamente el layout de cada Vista - en lugar de eso podemos definir la lógica de layout una vez para todas las ivstas del sitio - haciendo nuestros arhivos de vistas más limpios y mantenibles (y asegurándonos de mantener el principio DRY: Don't Repeat Yourself).

A partir de ASP.NET MVC 3 Beta, podemos añadir un archivo llamado _ViewStart.cshtml (o _ViewStart.vbhtml para VB ) en el directorio View de nuestro proyecto:

Este archivo puede ser usado para definir código de vista común que queremos ejecutar al comienzo de la renderización de cada Vista. Por ejemplo, podríamos escribir el siguiente código en ese archivo para establecer programáticamente la propiedad Layout para cada vista para que use por defecto el layout SiteLayout.cshtml:

Como este código se ejecuta al comienzo de cada vista, no tenemos que establecer el Layout de cada vista ( excepto si queremos sobreescribir el valor por defecto).

Importante: Como podemos escribir código en el archivo _ViewStart.cshtml, podemos hacer que la lógica de selección del Layout sea más rica que establecer la propiedad. Por ejemplo, podríamos cambiar la palntilla a usar dependiendo de qué tipo de dispositivo esté accediendo al sitio - y tener un layout optimizado para teléfonos o tablets, y otros para escritorios para PCs. O si estamos creando un sistema CMS o aplicaciones compartidas que son usadas por varios clientes, podríamos seleccionar diferentes layouts dependiendo del cliente (o su rol) cuando accedan al sitio.

Nota: Podemos especificar layouts en un controlador o en un Action Filter. Así que si quereis mantener la lógica de lselección de layout podéis hacerlo.

Terminando el ejemplo

Aquí tenéis una captura de pantalla del ejemplo que hemos creado:

Aquí está la implementación de la clase ProductsController que implementa la URL /Products:

Aquí tenéis la vista Index.cshtml que estamos usando para renderizar la URL /Products:

Aquí tenéis el arvhico de layout SiteLayout.cshtml que hemos usado para tener un look & feel común:

Aquí tenéis el archivo _ViewStart.cshtml que hemos usado apra especificar que todas las vistas de nuestro sitio usen por defecto el archivo SiteLayout.cshtml:

Y aquí tenéis el HTML generado de la url /Products:

Y como ahora tenemos un archivo común de layout para nuestro sitio, podemos crear más funcionalidad, contorladores y vistas en nuestra aplicación - y tener una interfaz de usuario consistente y muy fácil de mantener.

Cosas más avanzadas.

Dos preguntas comunes que la gente se hace son:

  1. ¿Podemos anidar layouts?
  2. ¿Podemos tener regiones multiples, discontinuas, reemplazables en un archivo de layout - de manera que pueda rellenarlos de forma diferentes en mis vistas?

La respuesta a ambas preguntas es SI. Postearé algunos ejemplos sobre cómo hacer esto más adelante.

Resúmen

Como ya he mencionado, uno de los temas en los que nos hemos centrado para ASP.NET MVC 3 y Razor ha sido hacer que el código que escribimos sea más claro y conciso. Creemos que la nueva funcionalidad de layout en esta release contribuye a hacer que los archivos de vistas sean más fáciles de leer y escribir. Veremos algunas otras mejoras como esta que son nuevas en ASP.NET MVC 3 en futuros post.

Espero que sirva,

Scott.

Traducido por: Juan María Laó Ramos.

Artículo original

11 pensamientos en “ASP.NET MVC 3: Layouts con Razor

  1. Pingback: Anuncio de ASP.NET MVC 3 Release Candidate « Thinking in .NET

  2. Pingback: ASP.NET MVC 3: Comentarios de Servidor con Razor « Thinking in .NET

  3. Eliecer Canales

    Hola Scott, excelente material…
    Estoy mirando las nuevas tecnologías en este sentido y por lo poco que he visto, MVC + Razor es el futuro.

    saludos desde Chile

    Responder
  4. Pingback: ASP.NET MVC 3: Sintaxis de Razor @: y « Thinking in .NET

  5. Pingback: ASP.NET MVC 3: Nuggets de Razor implícitos y explícitios « Thinking in .NET

  6. Pingback: ASP.NET MVC 3: Layouts y Secciones con Razor « Thinking in .NET

  7. Pingback: Releases de ASP.NET MVC 3, IIS Express, SQL CE 4, Web Farm Framework, Orchard, WebMatrix « Thinking in .NET

  8. Guille

    Razor junto con MVC son un gran aporte de parte de MS, recuerdo mis épocas cuando jugaba con un modelo muy parecido en SMALLTALK y me preguntaba, estará tan lejos de llegar a .NET, despues de esperar mucho, ahora lo tenemos. No nos olvidemos de como se gesto todo esto, allá por el año 1978 en Xerox Research nacio el proyecto SMALLTAK ellos fueron los pioneros de MVC y de muchas cosas mas que actualmente nos parecen tan novedosas.

    Saludos gente …

    Responder
  9. Pingback: ASP.NET MVC 3 y la sintaxis @helper en Razor « Thinking in .NET

  10. eduardo

    Buen dia, como estas ?

    Por lo que veo, podria tranquilamente introducir mi cabecera, menu y barra de navegacion en el layout, como lo hacia antes en ASP.NET, verdad ? Estoy de a poco viendo MVC, se me hace medio complicado, pero de a poco, voy entendiendo !!!

    Responder
  11. Pablo Roman

    Buen dia.
    Actualmente me encuentro trabajando con un Layout, logre integrarle menus dinamicos mediante vistas parciales cargadas desde el mismo layout. Sin embargo, al dar clic en alguno de los enlaces del menu para cargar otra vista con el mismo layout, la pagina se pone en blanco por medio segundo o menos y posteriormente carga la nueva vista.
    Funcionalmente trabaja bien, el problema es de tipo visual. Haz tenido alguna experiencia sobre como realizar un refresco del layout de una forma mas estetica?.
    De antemano, agradezco por tus comentarios.
    Saludos.

    Responder

Deja un comentario