¡La versión 2.0 de Play ya está lista! Ayúdanos a traducir la documentación de la útlima versión y sigue nuestro progreso.

Manuales, tutoriales & referencias

Consulte

Contenidos

Elija la versión

Buscar

Busque con google

Libros

El motor de templates

Play cuenta con un eficiente motor de templates que le permite generar HTML, XML, JSON o cualquier documento de texto de manera dinámica. El motor de templates utiliza Groovy como lenguaje de expresiones. Un sistema de tags le permite crear funciones reutilizables.

Los templates son almacenados en la carpeta app/views.

Sintaxis de los templates

Un template es un archivo de texto en el cual algunas de sus partes serán remplazadas por contenido generado dinámicamente. Los elementos dinámicos de los templates son escritos utilizando el lenguaje Groovy language. Groovy es un lenguaje cuya sintaxis es muy similar a la de Java.

Expresiones: ${…}

La manera más simple de crear un elemento dinámico es declarando una expresión. La sintaxis utilizada es ${…}. De esta manera, el resultado de evaluar dicha expresión será insertado en lugar de la expresión misma.

Por ejemplo:

<h1>Client ${client.name}</h1>

Si no puede asegurar que el nombre del cliente no será null, Groovy provee un práctico atajo para estos casos:

<h1>Client ${client?.name}</h1>

De forma tal que sólo mostrará el nombre del cliente si el mismo no es null.

Decoradores: #{extends /} and #{doLayout /}

Los decoradores proveen una simple y elegante solución para compartir el diseño de una página ente múltiples templates.

Utilice los tags #{get} y #{set} para compartir variables entre el template y el decorador.

De esta manera, puede incluir una página en un decorador con una línea de código:

#{extends 'simpledesign.html' /}
 
#{set title:'A decorated page' /}
This content will be decorated.

El decorador : simpledesign.html

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <title>#{get 'title' /}</title>
  <link rel="stylesheet" type="text/css" href="@{'/public/stylesheets/main.css'}" />
</head>
<body>
  <h1>#{get 'title' /}</h1>
  #{doLayout /}
  <div class="footer">Built with the play! framework</div>
</body>
</html>

Tags: #{nombreDeTag /}

Un tag es un framento de un template que puede ser llamado con parametros, como si se tratara de una función. Si el tag cuenta con un único parámetro, por convención dicho parámetros se llamará “arg” y su nombre puede ser omitido.

Por ejemplo, este tag inserta un tag SCRIPT para cargar un archivo JavaScript:

#{script 'jquery.js' /}

Un tag necesariamente tiene que ser cerrado, ya sea directamente o mediante un tag de cierre:

#{script 'jquery.js' /}

o

#{script 'jquery.js'}#{/script}

Por ejemplo, el tag list le permite iterar sobre los elementos de cualquier colección. Requiere dos parámetros obligatorios:

<h1>Client ${client.name}</h1>
<ul>
    #{list items:client.accounts, as:'account' }
        <li>${account}</li>
    #{/list}
</ul>

Todas las expresiones dinámicas son automáticamente escapadas por el motor de templates para evitar ataques XSS en su aplicación. De forma tal que la variable title que contiene <h1>Title</h1> será escapada de la siguiente manera:

${title} --> &lt;h1&gt;Title&lt;/h1&gt;

Si desea evitar que Play escape el contenido de la expresión, debe llamar al método raw():

${title.raw()} --> <h1>Title</h1>

Si desea evitar que una porción grande de código HTML sea escapada, puede utilizar el tag #{verbatim /}:

#{verbatim}
    ${title} --> <h1>Title</h1>
#{/verbatim}

Acciones: @{…} o @@{…}

Puede utilizar el Router para generar (o incluso generar de manera inversa) el URL correspondiente a una ruta especificada. Desde un template puede utilizar la sintaxis @{…} para alcanzar el mismo efecto.

Por ejemplo:

<h1>Client ${client.name}</h1>
<p>
   <a href="@{Clients.showAccounts(client.id)}">All accounts</a>
</p>
<hr />
<a href="@{Clients.index()}">Back</a>

La sintaxis @@{…} hace lo mismo pero genera un URL absoluto (lo cual es particulamente útil para general e-mails)

Mensajes: &{…}

Si su aplicación requiere poder ser internacionalizada, puede utilizar la sintaxis &{…} para desplegar un mensaje internacionalizado:

Por ejemplo en el archivo conf/messages especificamos:

clientName=The client name is %s

Para mostrar este mensaje en un template simplemente use:

<h1>&{'clientName', client.name}</h1>

Comentarios: *{…}*

Los cometarios no son evaluados por el motor de template. Simplemente son comentarios…

*{**** Display the user name ****}*
<div class="name">
    ${user.name}
</div>

Scripts: %{…}%

Un script es un conjunto de expresiones con una lógica más compleja. Un script puede declarar algunas variables y definir varios comandos. Utilice la sintaxis %{…}% para insertar scripts.

%{
   fullName = client.name.toUpperCase()+' '+client.forname;
}%
 
<h1>Client ${fullName}</h1>

Mediante un script puede escribir contenido dinámico directamente usando el objeto out:

%{
   fullName = client.name.toUpperCase()+' '+client.forname;
   out.print('<h1>'+fullName+'</h1>');
}%

Puede utilizar un script para crear una estructura que le permita interar sobre los elementos de una colección:

<h1>Client ${client.name}</h1>
<ul>
%{
     for(account in client.accounts) { 
}%
     <li>${account}</li>
%{
     }
}%
</ul>

Tenga en cuenta que los templates no es el mejor lugar para introducir lógica completa. En tal caso es aconsejable crear un tag, o mover esa lógica hace el controlador o el modelo de objetos.

Herencia de templates

Un template puede heredar el contenido de otro template, es decir que puede ser incluido como parte de otro template.

Para heredar de otro template, utilice el tag extends:

#{extends 'main.html' /}
 
<h1>Some code</h1>

El template main.html es un template común y corriente, pero utiliza el tag doLayout para incluir el contenido de aquél template que lo herede:

<h1>Main template</h1>
 
<div id="content">
    #{doLayout /}
</div>

Tags personalizados

Puede crear sus propios tags de manera muy simple. Un tag no es más que un archivo de template, almacenado en la carpeta app/views/tags. El nombre del archivo del tag es utilizado como nombre del tag.

Para crear un tag hello, simplemente cree el archivo app/views/tags/hello.html.

Hello from tag!

No hay necesidad de configurar nada. Puede usar el tag directamente de la siguiente manera:

#{hello /}

Definiendo tags con parámetros

Los parámetros de los tags son expuestos como variables de un tempalte. Los nombres de variables con construido con el prefijo ‘_’.

Por ejemplo, dado el siguiente tag:

Hello ${_name} !

Puede pasar el nombre como un parámetro al tag:

#{hello name:'Bob' /}

Si el tag cuenta con tan sólo un parámetro, puede acceder al mismo de manera implícita mediante el nombre arg.

Por ejemplo:

Hello ${_arg}!

Y puede llamarlo fácilmente usando:

#{hello 'Bob' /}

Invocando el body (cuerpo) de un tag

Si su tag acepta un body (cuerpo), puede incluirlo en el código de su tag usando el tag doBody.

Por ejemplo:

Hello #{doBody /}!

Y luego puede pasar el nombre en el cuerpo del tag:

#{hello}
   Bob
#{/hello}

Tags para formatos específicos

Puede tener varias versiones de un tag para diferentes content types, dejando que Play seleccione el que resulte apropiado. Por ejemplo, Play utilzará el tag app/views/tags/hello.html cuando el request.format sea html, y app/views/tags/hello.xml cuando el formato requerido sea xml.

Cualquiera sea el content type, Play utilizará el tag con extension .tag si no encuentra un tag para el formato específico, por ejemplo: app/views/tags/hello.tag.

Tags personalizados en Java (FastTags)

También puede definir los tags en código Java. De la misma manera en que puede definir sus propias extensiones de Java extendiendo la clase play.templates.JavaExtensions, para crear un FastTag necesita crear un método en una clase que extienda play.templates.FastTags. Cada método que desea que sea ejecutado como un tag, debe tener los siguientes parámetros:

public static void _tagName(Map<?, ?> args, Closure body, PrintWriter out, 
   ExecutableTemplate template, int fromLine)

Preste atención al guión bajo ‘_’ delante del nombre del tag.

Para comprender como construir un tag real, echemos una mirada a dos de los tags que vienen incluidos con Play.

Por ejemplo, el tag verbatim está implementado mediante un método de tan sólo una línea, que simplemente llama al método toString de JavaExtensions, pasando como parámetro el body del tag.

public static void _verbatim(Map<?, ?> args, Closure body, PrintWriter out, 
   ExecutableTemplate template, int fromLine) {
   
   out.println(JavaExtensions.toString(body));
}

El body del tag es cualquier cosa que se encuentre entre el tag de apertura y cierre, de forma tal que en el siguiente caso:

<verbatim>My verbatim</verbatim>

El body sería:

My verbatim

El segundo ejemplo es el tag option, que es un poco más complejo porque precisa de un tag padre o contenedor para funcionar.

public static void _option(Map<?, ?> args, Closure body, PrintWriter out, 
      ExecutableTemplate template, int fromLine) {
 
   Object value = args.get("arg");
   Object selection = TagContext.parent("select").data.get("selected");
   boolean selected = selection != null && value != null 
      && selection.equals(value);
 
   out.print("<option value=\"" + (value == null ? "" : value) + "\" " 
      + (selected ? "selected=\"selected\"" : "") 
      + "" + serialize(args, "selected", "value") + ">");
   out.println(JavaExtensions.toString(body));
   out.print("</option>");
}

Este tag despliega un tag HTML de tipo option, y establece el valor selected verificando cuál es el valor seleccionado en el tag padre. Las primeras tres líneas preparan las variables que serán utilizadas en la salida html. Luego, las últimas tres líneas despliegan la salida del tag.

Puede encontrar muchos ejemplos en el código fuente de los tags provistos por Play, con diversos grados de complejidad. Vea el archivo FastTags.java en github.

Tag namespaces

Para asegurarse de que sus tags no entren en conflicto con otros tags de otros proyectos, o con los propios tags de Play, puede establecer namespaces, utilizando la anotación de clase @FastTags.Namespace.

De forma tal que, para un tag llamado hello, en el namespace my.tags, debería anotarlo de la siguiente manera:

@FastTags.Namespace("my.tags") 
public class MyFastTag extends FastTags {
   public static void _hello (Map<?, ?> args, Closure body, PrintWriter out, 
      ExecutableTemplate template, int fromLine) {
      ...
   }
}

y luego, en sus templates, lo llamaría de la siguiente manera:

#{my.tags.hello/}

Extensiones de objetos de Java en los templates

Cuando utiliza sus objetos de Java dentro del motor de templates, nuevos métodos son agregados a los mismos. Estos métodos no existen en la clase Java original, y son agregados dinámicamente por el motor de templates.

Por ejemplo, para facilitar el formateo de número, el método format es agregado dinámicamente a la clase java.lang.Number.

De esta manera, es muy fácil formatear un número:

<ul>
#{list items:products, as:'product'}
    <li>${product.name}. Price: ${product.price.format('## ###,00')} €</li>
#{/list}
</ul>

Lo mismo sucede con la clase java.util.Date.

La documentación sobre las extensiones de java contiene la lista de los métodos disponibles, por tipo de dato.

Creando extensiones personalizadas

Su proyecto puede tener necesidades de formateo específicas, en tal caso puede crear sus propias extensiones personalizadas.

Tan sólo precisa crear una clase de Java que extienda play.templates.JavaExtensions.

Por ejemplo, para proveer un formateador personalizado de tipo moneda para los valores númericos:

package ext;
 
import play.templates.JavaExtensions;
 
public class CurrencyExtensions extends JavaExtensions {
 
  public static String ccyAmount(Number number, String currencySymbol) {
     String format = "'"+currencySymbol + "'#####.##";
     return new DecimalFormat(format).format(number);
  }
 
}

Cada método de extensión es un método estático que debe retornar un java.lang.String que será escrito en la página de salida. El primer parámetro contendrá el objeto a ser enriquecido con el nuevo método.

Puede entonces utilizar su formateador de la siguiente manera:

<em>Price: ${123456.324234.ccyAmount()}</em>

Las clases con extensiones para los templates son detectadas automáticamente por Play al inicial la aplicación. Tan sólo tiene que reiniciar su aplicación para que estén disponibles.

Objetos implícitos disponibles en los templates

Todos los objetos agregados a la colección renderArgs son automáticamente inyectadas como variables de los templates.

Por ejemplo, para inyectar un bean ‘user’ en el template desde un controlador:

renderArgs.put("user", user );

Cuando despliega un template desde una acción, el framework también agrega los siguientes objetos implícitos:

Variable Descripción Documentación de la API Vea también
errors Errores de validación play.data.validation.Validation.errors() Validando información HTTP
flash El contexto Flash play.mvc.Scope.Flash Controladores - El contexto de la Session y el Flash
lang El idioma actual play.i18n.Lang Configurando I18N - Definiendo idiomas
messages El mapa de mensajes play.i18n.Messages Configurando I18N - Internacionalización de mensajes
out El stream de salida de datos java.io.PrintWriter
params Parámetros actuales play.mvc.Scope.Params Controladores - parámetros HTTP
play La clase principal del framework play.Play
request El pedido HTTP actual play.mvc.Http.Request
session El contexto Session play.mvc.Scope.Session Controladores - El contexto de la Session y el Flash

Además de estos objetos, los nombres owner, delegate e it son palabras reservadas de Groovy y no deberían ser utilizadas como nombres de variables en los templates.

Próximos pasos: Validando los datos de los formularios HTTP