blob: 21476843ddd204eebb16d44a2394ac5254c7e9c1 [file] [log] [blame]
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Apache Velocity -
Guía del Usuario de Velocity</title>
<style type="text/css" media="all">
@import url("../css/maven-base.css");
@import url("../css/maven-theme.css");
@import url("../css/site.css");
</style>
<link rel="stylesheet" href="../css/print.css" type="text/css" media="print" />
<link rel="alternate" href="http://feeds.feedburner.com/ApacheVelocitySiteNews" type="application/rss+xml" title="Apache Velocity -
Guía del Usuario de Velocity News" />
<meta name="author" content="
Velocity Documentation Team" />
<meta name="author" content="
John Castura" />
<meta name="author" content="
Juan Pablo Morales" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body class="composite">
<div id="banner">
<a href="../../../" id="bannerLeft">
<img src="../images/velocity_project_wide.png" alt="" />
</a>
<span id="bannerRight">
<img src="../images/velocity-logo.png" alt="" />
</span>
<div class="clear">
<hr/>
</div>
</div>
<div id="breadcrumbs">
<div class="xleft">
<a href="http://www.apache.org/">Apache</a>
&gt;
<a href="../../../../">Velocity</a>
&gt;
<a href="../">Velocity Engine</a>
</div>
<div class="xright"> <a href="../../../devel/index.html">Engine</a>
|
<a href="../../../../tools/devel/index.html">Tools</a>
|
<a href="../../../../dvsl/devel/index.html">DVSL</a>
</div>
<div class="clear">
<hr/>
</div>
</div>
<div id="leftColumn">
<div id="navcolumn">
<h5>Velocity</h5>
<ul>
<li class="none">
<a href="../index.html">General</a>
</li>
<li class="none">
<a href="../overview.html">Overview</a>
</li>
<li class="none">
<a href="../getting-started.html">Getting Started</a>
</li>
<li class="none">
<a href="../webapps.html">Web Applications</a>
</li>
<li class="none">
<a href="../../../../download.cgi">Download</a>
</li>
<li class="none">
<a href="http://wiki.apache.org/velocity/VelocityFAQ">FAQ (Wiki)</a>
</li>
</ul>
<h5>Docs</h5>
<ul>
<li class="none">
<a href="../user-guide.html">User Guide</a>
</li>
<li class="none">
<a href="../developer-guide.html">Developer Guide</a>
</li>
<li class="none">
<a href="../vtl-reference-guide.html">VTL Reference</a>
</li>
<li class="none">
<a href="../anakia.html">Anakia: XML->doc tool</a>
</li>
<li class="none">
<a href="../texen.html">Texen: text generation</a>
</li>
</ul>
<h5>Developers</h5>
<ul>
<li class="none">
<a href="../license.html">License</a>
</li>
<li class="none">
<a href="../apidocs/index.html">Javadoc</a>
</li>
<li class="none">
<a href="../changes-report.html">Changes in 1.5</a>
</li>
<li class="none">
<a href="../jira-report.html">Resolved Issues in 1.5</a>
</li>
<li class="none">
<a href="../jar-dependencies.html">Dependencies</a>
</li>
<li class="none">
<a href="http://svn.apache.org/viewvc/velocity/engine/branches/Velocity_1.5_BRANCH/">Source Code Repository</a>
</li>
<li class="none">
<a href="../build.html">Building from Source</a>
</li>
</ul>
<h5>Community</h5>
<ul>
<li class="none">
<a href="http://wiki.apache.org/velocity/">Wiki</a>
</li>
<li class="none">
<a href="../../../../news.html">Recent News</a>
</li>
<li class="none">
<a href="http://wiki.apache.org/velocity/PoweredByVelocity">Powered By Velocity</a>
</li>
<li class="none">
<a href="http://wiki.apache.org/velocity/VelocityEditors">IDE/Editor Plugins</a>
</li>
<li class="none">
<a href="http://wiki.apache.org/velocity/PublishedArticlesAndBooks">Articles and Books</a>
</li>
<li class="none">
<a href="http://wiki.apache.org/velocity/GetInvolved">Get Involved</a>
</li>
<li class="none">
<a href="../../../../contact.html">Mailing Lists</a>
</li>
</ul>
<h5>Velocity Development</h5>
<ul>
<li class="none">
<a href="http://wiki.apache.org/velocity/RoadMap">Road Map</a>
</li>
<li class="none">
<a href="http://wiki.apache.org/velocity/CodeStandards">Coding Standards</a>
</li>
<li class="none">
<a href="http://wiki.apache.org/velocity/DocumentationGuidelines">Documentation Guidelines</a>
</li>
<li class="none">
<a href="https://issues.apache.org/jira/browse/VELOCITY">Issues</a>
</li>
<li class="none">
<a href="../../../../who-we-are.html">Who we are</a>
</li>
</ul>
<h5>Translations</h5>
<ul>
<li class="none">
<a href="http://www.jajakarta.org/velocity/">Site (Japanese)</a>
</li>
<li class="none">
<a href="../translations/user-guide_fi.html">User's Guide (Finnish)</a>
</li>
<li class="none">
<a href="../translations/user-guide_fr.html">User's Guide (French)</a>
</li>
<li class="none">
<strong>User's Guide (Spanish)</strong>
</li>
</ul>
<h5>Project Documentation</h5>
<ul>
<li class="collapsed">
<a href="../project-info.html">Project Information</a>
</li>
<li class="collapsed">
<a href="../project-reports.html">Project Reports</a>
</li>
</ul>
<a class="poweredBy" href="../../../../" title="Apache Velocity" ><img class="poweredBy" alt="Apache Velocity" src="../images/pbv90x30.png" /></a>
<a class="poweredBy" href="../../../../rss/news.rss" title="Velocity News Feed" ><img class="poweredBy" alt="Velocity News Feed" src="../images/feed-icon-24x24.jpg" /></a>
</div>
</div>
<div id="bodyColumn">
<div id="contentBox">
<a name="tabla_de_contenidos"></a><div class="section"><h2>Tabla de Contenidos</h2>
<ol type="1">
<li><a href="#Acercadeestaguía">Acerca de esta guía</a></li>
<li><a href="#¿QuéesVelocity?">¿Qué es Velocity?</a></li>
<li><a href="#¿QuépuedehacerVelocitypormi?">¿Qué puede hacer Velocity por mi?</a>
<ol type="1">
<li><a href="#ElEjemplodelatiendadeLodo">El Ejemplo de la tienda de
Lodo</a></li>
</ol>
</li>
<li><a href="#ElLenguajedePlantillasdeVelocity(VTL):UnaIntroducción">El Lenguaje de Plantillas de Velocity (VTL): Una Introducción</a></li>
<li><a href="#¡HolaMundoVelocity!">¡Hola Mundo Velocity!</a></li>
<li><a href="#Comentarios">Comentarios</a></li>
<li><a href="#Referencias">Referencias</a>
<ol type="1">
<li><a href="#Variables">Variables</a></li>
<li><a href="#Propiedades">Propiedades</a></li>
<li><a href="#Métodos">Métodos</a></li>
</ol>
</li>
<li><a href="#NotaciónFormaldeReferencias">Notación Formal de Referencias</a></li>
<li><a href="#NotaciónSileciosadeReferencias">Notación Sileciosa de Referencias</a></li>
<li><a href="#Literalmente">Literalmente</a>
<ol type="1">
<li><a href="#Dinero">Dinero</a></li>
<li><a href="#EscapandoReferenciasVTLVálidas">Escapando Referencias VTL Válidas</a></li>
</ol>
</li>
<li><a href="#SustitucióndeMayúsculasyMinúsculas">Sustitución de Mayúsculas y Minúsculas</a></li>
<li><a href="#Directivas">Directivas</a>
<ol type="1">
<li><a href="#Set">Set</a></li>
<li><a href="#CadenasdeCaracteres">Cadenas de Caracteres</a></li>
<li><a href="#SentenciasIf-Else">Sentencias If-Else</a>
<ol type="1">
<li><a href="#OperadoresLógicosyRelacionales">Operadores Lógicos y Relacionales</a></li>
</ol>
</li>
<li><a href="#CiclosForeach">Ciclos Foreach</a></li>
<li><a href="#Include">Include</a></li>
<li><a href="#Parse">Parse</a></li>
<li><a href="#Stop">Stop</a></li>
<li><a href="#Velocimacros">Velocimacros</a></li>
</ol>
</li>
<li><a href="#EscapandoDirectivasVTL">Escapando Directivas VTL</a></li>
<li><a href="#VTL:AsuntosdeFormato">VTL: Asuntos de Formato</a></li>
<li><a href="#OtrasCaracterísticasyMiscelánea">Otras Características y Miscelánea</a>
<ol type="1">
<li><a href="#Matemáticas">Matemáticas</a></li>
<li><a href="#ElOperadordeRango">El Operador de Rango</a></li>
<li><a href="#TemasAvanzados:Escapandoy!">Temas Avanzados: Escapando y !</a></li>
<li><a href="#MisceláneadeVelocimacro">Miscelánea de Velocimacro</a></li>
<li><a href="#ConcatenacióndeCadenas">Concatenación de Cadenas</a></li>
</ol>
</li>
<li><a href="#Retroalimentación">Retroalimentación</a></li>
</ol>
</div>
<a name="acerca_de_esta_guía"></a><div class="section"><h2>Acerca de esta guía</h2>
<p>
La Guía del usuario de Velocity busca ayudar a los diseñadores de páginas y a
los proveedores de contenido a sentirse a gusto con Velocity y con la sintáxis
de su simple pero poderoso lenguaje de script, el Lenguaje de Plantillas de
Velocity (VTL por sus siglas en inglés). Muchos de los ejemplos de esta guía
muestran como usar Velocity para incluir contenidos dinámicos en sitios web,
pero todos los ejemplos de VTL son igualmente aplicables a otras páginas y
plantillas.
</p>
<p>Gracias por escoger Velocity!</p>
</div>
<a name="aqué_es_velocity"></a><div class="section"><h2>¿Qué es Velocity?</h2>
<p>
Velocity es un motor de plantillas basado en Java. Le permite a los diseñadores
de páginas hacer referencia a métodos definidos dentro del código Java. Los
diseñadores Web pueden trabajar en paralelo con los programadores Java para
desarrollar sitios de acuerdo al modelo de Modelo-Vista-Controlador (MVC),
permitiendo que los diseñadores se concentren únicamente en crear un sitio bien
diseñado y que los programadores se encarguen solamente de escribir código de
primera calidad. Velocity separa el código Java de las páginas Web, haciendo el
sitio más mantenible a largo plazo y presentando una alternativa viable a <a href="http://java.sun.com/products/jsp/" class="externalLink">Java Server Pages</a> (JSP) o <a href="http://www.php.net" class="externalLink">PHP</a>.
</p>
<p>
Velocity se puede utilizar para crear páginas web, SQL, PostScript y cualquier
otro tipo de salida de plantillas. Se puede utilizar como una aplicación
independiente para generar código fuente y reportes, o como un componente
integrado en otros sistemas. Cuando este completo Velocity proveerá servicios
para el conjunto de aplicaciones web de <a href="http://jakarta.apache.org/turbine" class="externalLink">Turbine</a>. Velocity+Turbine
proveerá un servicio de plantillas que facilitará el desarrollo de aplicaciones
web de acuerdo a un verdadero modelo MVC.
</p>
</div>
<a name="aqué_puede_hacer_velocity_por_mi"></a><div class="section"><h2>¿Qué puede hacer Velocity por mi?</h2>
<a name="el_ejemplo_de_la_tienda_de_lodo"></a><div class="section"><h3>El Ejemplo de la tienda de Lodo</h3>
<p>
Suponga que usted es un diseñador para una tienda en línea que se especializa
en vender lodo a la que llamaremos &quot;La Tienda de Lodo en línea&quot;. Los negocios
están muy bien. Sus clientes ordenan diferentes tipos y cantidades de
lodo.
Ellos ingresan en su sitio con su nombre de usuario y su clave secreta, lo que
les permite ver sus órdenes y pedir más lodo. En estos momentos el Lodo
Terracota, que es muy popular, esta en oferta. Una minoría de sus clientes
usualmente compra Lodo Rojo Brillante, que también esta en oferta, pero no es
tan popular y usualmente esta relegado al márgen de su página web. La
información sobre cada cliente esta dentro de su base de datos por lo que surge
la pregunta: ¿Por qué no usar Velocity para enfocar las ofertas especiales para
los clientes que están más interesados en ciertas clases de lodo?
</p>
<p>
Velocity hace fácil el personalizar las páginas para sus visitantes. Como un
diseñador dentro de &quot;El Cuarto de Lodo&quot;, usted quiere crear la página que sus
usuarios verán después de entrar a su sitio.
</p>
<p>
Usted se encuentra con los ingenieros de su compañía, y todos acuerdan que
<em>$cliente</em> contendrá la información pertienente al cliente que está
dentro de la página en un momento dado, que <em>$lodosEnOferta</em> contendrá
todos los tipos de lodo que están en oferta hoy en día. Además, el objeto
<em>$flogger</em> contendrá métodos para ayudar con la promoción. Para la tarea
actual, solo se utilizarán estas tres referencias. Recuerde, usted no necesita
preocuparse por como los ingenieros de software extraen la información
necesaria de la base de datos; sólo tiene que saber que funciona. Esto le
permite a usted continuar con su trabajo a la vez que deja a los ingenieros
hacer el de ellos.
</p>
<p>Usted podría incluir el siguiente código VTL dentro de su página:</p>
<div class="source"><pre>
&lt;HTML&gt;
&lt;BODY&gt;
Hello $cliente.Nombre!
&lt;table&gt;
#foreach( $lodo in $lodosEnOferta )
#if ( $cliente.haComprado($lodo) )
&lt;tr&gt;
&lt;td&gt;
$flogger.obtenerPromocion( $lodo )
&lt;/td&gt;
&lt;/tr&gt;
#end
#end
&lt;/table&gt;
</pre></div>
<p>
Los detalles exactos de la sentencia <i>foreach</i> serán descritos en
profundidad próximamente; lo que es importante es el impacto que este pequeño
script pueda tener en su sitio. Cuando un cliente con una debilidad por el
Lodo Rojo Brillante ingrese, si el Lodo Rojo Brillante esta en oferta, eso
será lo que el cliente verá, de manera prominente. Si otro cliente, con una
historia larga de compras de Lodo Terracota ingresa, entonces para él la
noticia de un rebaja de Lodo Terracota estará en un lugar muy importante. La
flexibilidad de Velocity es enorme y sólo esta limitada por su creatividad.
</p>
<p>
En la referencia de VTL están documentados muchos otros elementos de Velocity
que, colectivamente le dan el poder y la flexibilidad que usted necesita para
hacer de su sitio en la red una <em>presencia</em> en la red. A medida que
usted se familiarice con estos elementos usted comenzará a aprovechar el poder
de Velocity.
</p>
</div>
</div>
<a name="el_lenguaje_de_plantillas_de_velocity_vtl:_una_introducción"></a><div class="section"><h2>El Lenguaje de Plantillas de Velocity (VTL): Una Introducción</h2>
<p>
El Lenguaje de Plantillas de Velocity (VTL) fue creado para prover la
manera mas fácil, simple y limpia de incorporar contenido dinámico
dentro de una página web. Incluso un desarrollador de páginas web con
poca y ninguna experiencia puede rápidamente ser capaz de utilizar VTL
para incluir contenido dinámico en un sitio web.
</p>
<p>
VTL usa <em>referencias</em> para incluir contenido dinámico dentro
de un sitio web. Una variable es un tipo de referencia que puede
referirse a algo definido dentro del código Java o obtener su valor
de un <em>enunciado</em> VTL en la página misma. A continuación hay
un ejemplo de un enunciado VTL que se puede incluir en un documento
HTML:
</p>
<div class="source"><pre>
#set( $a = &quot;Velocity&quot; )
</pre></div>
<p>
Este enunciado VTL, como todos los enunciados VTL comienza con el
caracter <em>#</em> y contiene una directiva: <em>set</em>. Cuando
un visitante solicita su página, el Motor de Plantillas de Velocity
buscará dentro del contenido de su página y encontrará todos los
símbolos <em>#</em>, para luego determinar cuáles marcan el comienzo
de enunciados VTL y cuáles no tienen nada que ver con VTL.
</p>
<p>
El caracter <em>#</em> viene seguido por una directiva <em>set</em>.
La directiva <em>set</em> utiliza una expresión (encerrada entre
paréntesis) -- una ecuación que asigna un <em>valor</em> a una
<em>variable</em>.
La variable se encuentra en el lado derecho y el valor está en el lado
izquierdo; los dos se encuentran separados por un signo igual
(<em>=</em>).
</p>
<p>
En el ejemplo en la parte superior, la variable es <em>$a</em> y el
valor es <em>Velocity</em>. Esta variable, al igual que todas las
referencias, comienza con el caracter <em>$</em>. Los valores siempre
se encuentran ente comillas; con Velocity no hay confusión acerca de
los tipos de datos, ya que solamente cadenas (información basada en
texto) pueden ser pasados a las variables.
</p>
<p>
La siguiente regla puede ser útil para entender mejor como funciona
Velocity: <strong>Las Referencias comienzan con <em>$</em> y se
utilizan para obtener algo. Las directivas comienzan con <em>#</em>
y se utilizan para hacer algo</strong>
</p>
<p>
En el ejemplo anterior <em>#set</em> se utilizó para asignarle un valor
a una variable. La variable, <em>$a</em>, puede utilizarse dentro de la
plantilla para escribir la palabara &quot;Velocity&quot;.
</p>
</div>
<a name="ahola_mundo_velocity"></a><div class="section"><h2>¡Hola Mundo Velocity!</h2>
<p>
Una vez un valor ha sido asignado a una variable, usted puede
referenciar la variable en cualquier lugar dentro del documento
HTML. En el ejemplo siguiente, un valor es asignado a la variable
<em>$foo</em>, que luego es referenciada.
</p>
<div class="source"><pre>
&lt;html&gt;
&lt;body&gt;
#set( $foo = &quot;Velocity&quot; )
¡Hola Mundo $foo!
&lt;/body&gt;
&lt;html&gt;
</pre></div>
<p>
El resultado es una página web que imprime &quot;¡Hola Mundo Velocity!&quot;
</p>
<p>
Para hacer los enunciados con directivas VTL más legibles, nosotros le
recomendamos comenzar cada enunciado VTL en una nueva línea, aunque
usted no esta obligado a hacerlo así. La directiva <em>set</em> ser
verá con mayor detalle más adelante.
</p>
</div>
<a name="comentarios"></a><div class="section"><h2>Comentarios</h2>
<p>
Los comentarios es posible incluir texto que no aparecerá como parte de
la salida del motor de plantillas. Los comentarios sirven para recordar
e indicar a otros que es lo que están haciendo los enunciados VTL, o
para cualquier otro propósito que usted considere útil. A continuación
hay un ejemplo de un comentario de VTL.
</p>
<div class="source"><pre>
## Este es un comentario de una sola línea
</pre></div>
<p>
Un comentario de una sola línea comienza con <em>##</em> y termina
al final de la línea. Si usted desea escribir varias líneas de
comentario no es necesario tener numerosos comentarios de una sóla
línea. Los comentarios de varias líneas, que comienzan con
<em>#*</em> y terminan con <em>*#</em> le permiten manejar
fácilmente esta situación.
</p>
<div class="source"><pre>
Este es un texto que esta fuera de un comentario de múltiples líneas.
Los visitantes de su página lo pueden ver.
#*
He aquí un comentario de varias líneas. Los visitantes
de su sitio no verán esto, ya que el Motor de Plantillas
de Velocity lo ignorará
*#
Aquí hay texto fuera del comentario, este si es visible.
</pre></div>
<p>
A continuación hay algunos ejemplos para aclarar como funcionan
los comentarios de una y varias líneas:
</p>
<div class="source"><pre>
Este texto es visible. ## Este no lo es
Este texto es visible.
Este texto es visible. #* Este texto, como parte de un comentario de
varias líneas, no es visible. Este texto no es visible; tambiés es parte
del comentario. Este texto aún no es visible. *# Este texto esta fuera
del comentario, por lo que es visible.
## Este texto no es visible.
</pre></div>
<p>
Existe un tercer tipo de comentario, el bloque de comentario VTL,
que puede ser utilizado para almacenar datos como el autor y la
información de versiones:
</p>
<div class="source"><pre>
#**
Este es un bloque de comentario VTL y
puede utilizarse para almacenar datos
como el nombre del autor y la
información de versiones:
@author
@version 5
*#
</pre></div>
</div>
<a name="referencias"></a><div class="section"><h2>Referencias</h2>
<p>
Existen tres tipos de referencias en VTL: variables, propiedades y
métodos. Como un diseñador que utilizar VTL, usted y sus ingenieros
deben llegar a un acuerdo respecto a los nombres de las referencias
para que usted pueda utilizarlas correctamente en sus plantillas.
</p>
<p>
Todo lo que entra y sale de una referencia se trata como una cadena
de caracteres (un objeto String). Si existe un objeto que representa
<em>$foo</em> (por ejemplo, un objeto Integer), entonces Velocity
llamará el método <code>.toString()</code> de ese objeto para
convertirlo en una cadena de caracteres.
</p>
<p>
<a name="variables"><strong>Variables</strong></a>
<br></br>
La notación breve de una variable esta compuesta por un signo &quot;$&quot;
inicial seguido de un <em>Identificador</em>. Un identificador VTL
debe comenzar con un caracter alfabético (a .. z ó A .. Z). El resto
de los caracteres deb ser de alguno de los siguiente tipos:
</p>
<p>
<ul>
<li>alfabético (a .. z, A .. Z)</li>
<li>numérico (0 .. 9)</li>
<li>línea (&quot;-&quot;)</li>
<li>underscore (&quot;_&quot;)</li>
</ul>
</p>
<p>
A continuación hay algunos ejemplos de referencias válidas en VTL:
</p>
<div class="source"><pre>
$foo
$lanzaLodo
$lanza-lodo
$lanza_lodo
$lanzaLodo1
</pre></div>
<p>
Cuando VTL hace referencia una variable, po ejemplo, <em>$foo</em>,
la variable puede obtener su valor de una directiva <em>set</em>
dentro de la plantilla, o del código Java. Por ejemplo, si la
variable de Java <em>$foo</em> tiene el valor <em>bar</em> en el
momento en que se solicita la plantilla, entonces <em>bar</em>
reemplaza todas las ocurrencias (o instancias) de <em>$foo</em>
dentro de la página web. De manera alterna, si se incluye el
enunciado
</p>
<div class="source"><pre>
#set( $foo = &quot;bar&quot; )
</pre></div>
<p>
La salida será la misma para todas las instancias de <em>$foo</em>
que se encuentren a continuación es esta directiva.
</p>
<p>
<a name="propiedades"><strong>Propiedades</strong></a>
<br></br>
El segundo sabor de referencias VTL son las propiedades; las
propiedades tienen un formato particular. La versión corta se
compone de un signo <em>$</em> seguido de un identificador VTL,
seguido de un punto y de otro identificador VTL. A continuación hay
ejemplos de referencias de propiedades válidas en VTL:
</p>
<div class="source"><pre>
$cliente.Direccion
$compra.Total
</pre></div>
<p>
Tome el primer ejemplo, <em>$cliente.Direccion</em>. Puede tener dos
significados. Puede significar, Busque en la tabla de hashing
identificada como <em>cliente</em> y devuelva el valor asociado con
la llave <em>Direccion</em>. Pero <em>$customer.Address</em> puede
también referirse a un método (las referencias que se relacionan con
métodos se discutirán en la sección siguiente);
<em>$customer.Address</em> puede ser una manera corta de escribir
<em>$customer.getAddress()</em>. Cuando su página sea solicitada
Velocity determinará cuál de las dos posibilidades tiene sentido, y
luego devolverá el valor apropiado.
</p>
<p>
<a name="métodos"><strong>Methods</strong></a>
<br></br>
Un método esta definido dentro del código de Java y es capaz de
hacer algo útil, como desarrollar un cálculo o llegar a una
decisión. Los métodos son referencias compuestas de un signo &quot;$&quot;
inicial seguido en un identificador VTL, seguido de un <em>Cuerpo de
Método</em> VTL. Un cuerpo de método VTL, a su vez esta formado
por un identificador VTL seguido por un paréntesis izquierdo (&quot;(&quot;),
seguido, opcionalmente, por una lista de parámetros, para terminar
en un paréntesis derecho. A continuación hay ejemplos de referencias
de métodos válidas dentro de VTL:
</p>
<div class="source"><pre>
$cliente.getDireccion()
$compra.getTotal()
$pagina.setTitulo( &quot;My Página Principal&quot; )
$persona.establecerAtributos( [&quot;Extraño&quot;, &quot;Raro&quot;, &quot;Excitado&quot;] )
</pre></div>
<p>
Los primeros dos ejemplos -- <em>$cliente.getDireccion()</em> y
<em>$compra.getTotal()</em> -- pueden parecer similares a aquellos
utilizados en la sección de propiedades, <em>$cliente.Direccion</em>
y <em>$compra.Total</em>. Si usted supuso que estos ejemplos están
relacionados de alguna manera, usted esta en lo cierto.
</p>
<p>
Las Propiedades VTL pueden utilizarse como notación abreviada para
los métodos de VTL. La propiedad <em>$cliente.Direccion</em> tiene
exactamente el mismo efecto que el método
<em>$cliente.getDireccion()</em> (Nótese el uso de la palabra
inglesa <em>get</em> en lugar de la castellana <em>obtener</em>).
Generalmente es preferible utilizar una Propiedad si esta
disponible. La diferencia principal entre las propiedades y los
métodos es que usted le puede dar una lista de parámetros a un
Método.
</p>
<p>
La notación breve se puede utilizar en los Métodos siguientes:
</p>
<div class="source"><pre>
$sol.getPlanetas()
$anhelido.getMugre()
$album.getFoto()
</pre></div>
<p>
Podríamos esperar que estos métodos devolvieran los nombres de los
planetas que giran alrededor del sol, alimentaran un gusano de
tierra y extrajeran una foro de un album. Los siguientes Métodos
solo se pueden referenciar por medio de la notación larga:
</p>
<div class="source"><pre>
$sol.getPlaneta( [&quot;Tierra&quot;, &quot;Marte&quot;, &quot;Neptuno&quot;] )
## No es posible pasar una lista de parámetros con $sun.Planets
$sisifo.empujarPiedra()
## Si dijera $sisifo.piedra Velocity asumiría $sisifo.pushPiedra()
$libro.setTitulo( &quot;Homenaje a Colombia&quot; )
## No se puede pasar un parámetro en la notación abreviada.
</pre></div>
<p>
<a name="notaciónformaldereferencias"><strong>Notación Formal de
Referncias</strong></a>
<br></br>
La notación abreviada para referencias fue utilizada en los ejemplos
anteriores, pero también existe una notación formal para referencias,
que se demuestra a continuación:
</p>
<div class="source"><pre>
${lanzaLodo}
${cliente.Direccion}
${compra.getTotal()}
</pre></div>
<p>
Casi en todos los casos usted utilizará la notación abreviada, pero
existen escenarios en los cuales la notación formal se requiere para
procesar corectamente la plantilla.
</p>
<p>
Suponga que usted estuviera creando una frase en la que <em>$vicio</em>
se utilizará como prefijo para el ajetivo de una clase. La idea es
permitir a alguién escoger la palabra base para producir uno de los dos
siguientes resultados: &quot;Juan es un pirómano.&quot; ó &quot;Juan es un
cleptómano.&quot;. En este caso la notación abreviada no es apropiada;
considere el siguiente ejemplo:
</p>
<div class="source"><pre>
Juan is a $viciomano.
</pre></div>
<p>
Hay ambigüedad aquí, y Velocity asume que <em>$viciomano</em>, no
<em>$vicio</em>, es el Identificador que usted quería utilizar. Al no
encontrar ningún valor para <em>$viciomano</em> Velocity escribirá
simplemente <em>$viciomano</em>. Este problema se resueklve usando
notación formal.
</p>
<div class="source"><pre>
Juan es un ${vicio}mano.
</pre></div>
<p>
Ahora Velocity save que la referencia es <em>$vicio</em> y no
<em>$viciomano</em>. La notación formal es útil cuando las
referencias están ubicadas directamente al lado del texto dentro de
una plantilla.
</p>
<p>
<a name="notaciónsileciosadereferencias"><strong>Notación de Referenias
Silenciosas</strong></a>
<br></br>
Cuando Velocity encuentra una referencia indefinida, su
comportamiento normal es es de escribir el nombre de la referencia.
Por ejemplo, suponga que la siguiente referencia aparece como parte
de una plantilla VTL.
</p>
<div class="source"><pre>
&lt;input type=&quot;text&quot; name=&quot;correo&quot; value=&quot;$correo&quot;/&gt;
</pre></div>
<p>
Cuando el formulario se carga por primera vez la referencia
<em>$correo</em> no tiene valor, pero usted probablemente preferiría
un texto en blanco a uno con el valor de &quot;$correo&quot;. Usando la
notación de referencias silenciosa se pasa por alto el
comportamiento normal de Velocity. Para lograr eso en lugar de
<em>$correo</em> en el VTL usted utilizaría <em>$!correo</em>. Con
esta modificación el ejemplo anterior quedaría así:
</p>
<div class="source"><pre>
&lt;input type=&quot;text&quot; name=&quot;correo&quot; value=&quot;$!correo&quot;/&gt;
</pre></div>
<p>
Ahora cuando el formulario se carga por primera vez y $correo no
tenga valor una cadena vacía se escribirá en lugar de &quot;$correo&quot;.
</p>
<p>
La notación formal y la silenciosa se puede usar juntas como se
muestra en el ejemplo siguiente:
</p>
<div class="source"><pre>
&lt;input type=&quot;text&quot; name=&quot;correo&quot; value=&quot;$!{correo}&quot;/&gt;
</pre></div>
</div>
<a name="literalmente"></a><div class="section"><h2>Literalmente</h2>
<p>
VTL hace uso de caracteres especiales, como <em>$</em> y <em>#</em>,
para hacer su trabajo por lo que se debe tener algo de cuidado en el
momento de utilizar estos caracteres dentro de las plantillas. Esta
sección habla de como escapar el caracter <em>$</em>.
</p>
<p>
<a name="dinero"><strong>Dinero</strong></a>
<br></br>
No hay ningún problema en escribir &quot;Yo compré un saco de maíz de
2 kg. en el mercado de lagranja por sólo $2.50!&quot;. Como se mencionó
anteriormente, un identificador VTL siempre comienza con una letra
mayúscula o minúscula por lo que $2.50 no se confunde con una
referencia.
</p>
<p>
<a name="escapandoreferenciasvtlválidas"><strong>Escapando Referencias
VTL Válidas</strong></a>
<br></br>
Pueden existir casos en donde haya la posibilidad de que Velocity se
confunda. <em>Escapar</em> caracteres especiales es la mejor manera de
manejar los caracteres partículares de VTL dentro de sus plantillas, y
esto se puede hacer utilizando el caracter palote o backslash (
<em>\</em> ).
</p>
<div class="source"><pre>
#set( $correo = &quot;foo&quot; )
$correo
</pre></div>
<p>
Si Velocity encuentra una referencia en su plantilla VTL a
<em>$correo</em>, el buscará el contexto ppor un valor
correspondiente. En este caso el resultado será <em>foo</em> por
qué <em>$correo</em> esta definido. Si <em>$correo</em> no esta
definido el resultado será <em>$correo</em>.
</p>
<p>
Suponga que <em>$correo</em> está definido (por ejemplo, que tiene
el valor <em>foo</em>) y que usted desea escribir <em>$correo</em>.
Existen varias maneras de hacer esto pero la más sencilla es usar el
caracter de escape.
</p>
<div class="source"><pre>
## La siguiente línea define $correo en esta plantilla:
#set( $correo = &quot;foo&quot; )
$correo
\$correo
\\$correo
\\\$correo
</pre></div>
<p>
se muestra como
</p>
<div class="source"><pre>
foo
$correo
\foo
\$correo
</pre></div>
<p>
Note que el caracter <em>\</em> se asocia con <em>$</em> por la
izquierda. La regla de asociación por la izquierda hace que
<em>\\\$correo</em> se muestre como <em>\\$correo</em>. Compare estos
ejemplos con lo siguientes, en los que <em>$correo</em> no esta
definido.
</p>
<div class="source"><pre>
$correo
\$correo
\\$correo
\\\$correo
</pre></div>
<p>
se muestra como
</p>
<div class="source"><pre>
$correo
\$correo
\\$correo
\\\$correo
</pre></div>
<p>
Note que Velocity maneja de manera diferentes las referencias que
están definidas de aquellas que no lo están. A continuación se
encuentra una directiva que da a <em>$foo</em> el valor
<em>verde</em>.
</p>
<div class="source"><pre>
#set( $foo = &quot;verde&quot; )
$luna = $foo
</pre></div>
<p>
La salida será: <em>$luna = verde</em> -- donde <em>$luna</em> se
escribe literalmente porqué esta indefinido y <em>verde</em> se escribe
en lugar de <em>$foo</em>
</p>
<p>
También es posible escapar directivas de VTL; esto se describe con
más detalle en la sección de Directivas.
</p>
</div>
<a name="sustitución_de_mayúsculas_y_minúsculas"></a><div class="section"><h2>Sustitución de Mayúsculas y Minúsculas</h2>
<p>
Ahora que usted esta familiarizado con las referencias, puede comenzar a
aplicarlas de manera efectiva en sus plantillas. Las referencias de
Velocity aprovechan algunos principios de Java que los diseñadores de
plantillas encontraránm fáciles de utilizar. Por ejemplo:
</p>
<div class="source"><pre>
$foo
$foo.getBar()
## el lo mismo que
$foo.Bar
$data.setUser(&quot;jon&quot;)
## es lo mismo que
#set( $data.User = &quot;jon&quot; )
$data.getRequest().getServerName()
## es lo mismo que
$data.Request.ServerName
## que a su vez, es igual a
${data.Request.ServerName}
</pre></div>
<p>
Estos ejemplos ilustran usos alternativos para la mismas referencias.
Velocity se aprovechas de la instrospección y las capacidades de beans
de Java para resolver los nombre de referencias tanto en el Contexto
como en los métodos de los objetos. Es posible incluir y evaluar
referencias casi en cualquier lugar de su plantilla.
</p>
<p>
Velocity, que ha sido modelado con las especificaciones de Bean
definidas por Sun Microsystems, distingue entre mayúsculas y
minúsculas; sin embargo sus desarrolladores se han esforzado para
encontrar y corregir los errores del usuario cuando sea posible.
Cuando el método <em>getFoo()</em> es referenciado dentro de una
plantilla como <code>$bar.foo</code>, Velocity intentará primero
<code>getfoo()</code>. Si esto falla, intentará <code>getFoo()</code>.
De la misma manera, cuando una plantilla se refiera a
<code>$bar.Foo</code>, Velocity intentará <em>$getFoo()</em> primero
y luego <em>getfoo()</em>.
</p>
<p>
Nota: <em>Las Referencias a variables de instancia dentro de una
plantilla no se resuelven.</em> Solo las referencias a los
atributos get y set de los JavaBeans se resuelven (i.e.
<code>$foo.Nombre</code> se resuelve como el método de instancia
<code>getNombre()</code> de la clase Foo, pero no como su variable
de instancia <code>Nombre</code>).
</p>
</div>
<a name="directivas"></a><div class="section"><h2>Directivas</h2>
<p>
Las Referencias le permiten a los diseñadores de plantillas generar
contenido dinámico para sitios web, mientras que las
<em>directivas</em> -- elementos de script fáciles de usar que se
pueden usar para manipular de manera creativa la salida del código
Java -- les permiten a los diseñadores realmente estar a cargo de la
apariencia y en contenido del sitio web.
</p>
<a name="set"><strong>#set</strong></a>
<p>
La directiva <em>#set</em> se utiliza para establecer el valor de una
referencia. El valor se puede asignar a una referencia de variable o
una referencia de propiedad, siempre entre paréntesis, como se muestra
a continuación:
</p>
<div class="source"><pre>
#set( $primate = &quot;mono&quot; )
#set( $cliente.Comportamiento = $primate )
</pre></div>
<p>
El lado izquierdo (LI) de la asignación debe ser una referencia de
variable o una referencia de propiedad. El lado derecho (LD) puede
ser de alguno de los siguientes tipos:
</p>
<p>
<ul>
<li>Referencia de Variable</li>
<li>Constante de Cadena</li>
<li>Referencia de Propiedad</li>
<li>Referencia de Método</li>
<li>Literal Numérico</li>
<li>Lista de elementos como arreglo</li>
</ul>
</p>
<p>
These examples demonstrate each of the aforementioned types:
</p>
<div class="source"><pre>
#set( $mono = $pedro ) ## Referencia de Variable
#set( $mono.Amigo = &quot;monica&quot; ) ## Constante de Cadena
#set( $mono.Culpar = $casablanca.Fuga ) ## referencia de propiedad
#set( $mono.Plan = $doctor.llamar($web) ) ## referencia de método
#set( $mono.Numero = 123 ) ##Literal Numérico
#set( $mono.Decir = [&quot;No&quot;, &quot;es&quot;, $mi, &quot;culpa&quot;] ) ##Arreglo
</pre></div>
<p>
NOTA: En el último ejemplo los elementos definidos con el operador
[..] son accesibles usando los métodos definidos en la clase ArrayList.
Así, por ejemplo, usted podría acceder el primer elemento del arreglo utilizando $mono.Decir.get(0), con lo que obtendría la palabra &quot;No&quot;.
</p>
<p>
El lado derecho también puede ser una expresión aritmética sencilla:
</p>
<div class="source"><pre>
#set( $value = $foo + 1 )
#set( $value = $bar - 1 )
#set( $value = $foo * $bar )
#set( $value = $foo / $bar )
</pre></div>
<p>
Si el Lado Derecho es una propiedad o referencia de método que se
evalúa como <em>null</em>, <b>no</b> será asignada al lado
izquierdo. No es posible remover una referencia existente del
contexto utilizando este mecanismo. Esto puede ser confuso para los
recién llegados a Velocity. Por ejemplo:
</p>
<div class="source"><pre>
#set( $resultado = $consulta.criterio(&quot;nombre&quot;) )
El resultado de la primera consulta en $resultado
#set( $resultado = $consulta.criterio(&quot;direccion&quot;) )
El resultado de la segunda consulta es $resultado
</pre></div>
<p>
Si <em>$consulta.criterio(&quot;nombre&quot;)</em> retorna la cadena &quot;pedro&quot;,
y <em>$consulta.criterio(&quot;direccion&quot;)</em> retorna <em>null</em>, el
VTL anterio se mostraría de la siguiente manera:
</p>
<div class="source"><pre>
El resultado de la primera consulta en pedro
El resultado de la primera consulta en pedro
</pre></div>
<p>
Esto tiende a confundir a quines están comenzando, que construyen
ciclos <em>#foreach</em> que intentan hacer <em>#set</em> de una
referencia por medio de una propiedad o un método e inmediatamente
evalúan la referencia con una directiva <em>#if</em>. Por ejemplo:
</p>
<div class="source"><pre>
#set( $criterios = [&quot;nombre&quot;, &quot;direccion&quot;] )
#foreach( $criterio in $criterios )
#set( $resultado = $consulta.criterios($criterio) )
#if( $result )
La consulta tuvo éxito
#end
#end
</pre></div>
<p>
En el ejemplo anterior, no sería inteligente confiar en la
evaluación de <em>$resultado</em> para determinar si una consulta
tuvo éxito. Después de que <em>$result</em> ha sido agregado al
contexto (por medio de una directiva <em>#set</em>), no puede volver
a establecerse a <em>null</em> (quitarse del contexto). Los detalles
de las directivas <em>#if</em> y <em>#foreach</em> son cubiertos con
mayor detalle posteriormente en esta guía.
</p>
<p>
Una solución para este problema puede ser predefinir
<em>$resultado</em> a <em>false</em>. Luego, si la llamada a
<em>$consulta.criterios()</em> falla, es posible verificar.
</p>
<div class="source"><pre>
#set( $criterios = [&quot;nombre&quot;, &quot;direccion&quot;] )
#foreach( $criterio in $criterios )
#set( $resultado = false )
#set( $resultado = $consulta.criterios($criterio) )
#if( $resultado )
La consulta tuvo éxito
#end
#end
</pre></div>
<p>
A diferencia de algunas de las otras directivas de Velocity, la
directiva <em>#set</em> no tiene un enunciado <em>#end</em>.
</p>
<a name="cadenasdecaracteres"><strong>Cadenas de Caracteres</strong></a>
<p>
Cuando se utiliza la directiva <em>#set</em>, los literales de
cadena que están encerrados en comillas dobles serán evaluados y
mostrados en la plantilla, como se demuestra a continuación:
</p>
<div class="source"><pre>
#set( $directorioRaiz = &quot;www&quot; )
#set( $nombrePlantilla = &quot;indice.vm&quot; )
#set( $plantilla = &quot;$directorioRaiz/$nombrePlantilla&quot; )
$plantilla
</pre></div>
<p>
La salida será:
</p>
<div class="source"><pre>
www/indice.vm
</pre></div>
<p>
Sin embargo, cuando la cadena de caracteres esta encerrada en
comillas sencillas, no será evaluada:
</p>
<div class="source"><pre>
#set( $foo = &quot;bar&quot; )
$foo
#set( $blarg = '$foo' )
$blarg
</pre></div>
<p>Se muestra como:</p>
<div class="source"><pre>
bar
$foo
</pre></div>
<p>
Por defecto, la característica de las comillas sencillas para
mostrar texto sin evaluar esta disponible en Velocity; sin embargo
este valor por defecto se puede cambiar editando el archivo
<code>velocity.properties</code> de tal manera que
<code>stringliterals.interpolate=false</code>.
</p>
</div>
<a name="sentencias_if-else"></a><div class="section"><h2>Sentencias If-Else</h2>
<strong>Condicionales</strong>
<p>
La directiva <em>#if</em> en Velocity permite que se incluya texto
dentro de la plantilla generada, con la condición de que el
enunciado condicional evalue a verdadero. Por ejemplo:
</p>
<div class="source"><pre>
#if( $foo )
&lt;strong&gt;Velocity!&lt;/strong&gt;
#end
</pre></div>
<p>
La variable <em>$foo</em> se evalúa para determinar si es verdadera,
cosa que ocurrirá bajo una de dos circunstancias: (i) <em>$foo</em>
es un valor booleano (verdadero ó falso) que tiene un valor de
verdadero, ó (ii) el valor no es <em>null</em>. Recuerde que el
contexto de Velocity solamente contiene objetos, por lo que cuando
se dice 'booleano' se habla en realidad de la clase Boolean. Esto es
cierto incluso para los métodos que devuelven un valor de tipo
<code>boolean</code> - la infraestructura de introspección devolverá
un <code>Boolean</code> del mismo valor lógico.
</p>
<p>
El contenido que se encuentra entre el enunciado <em>#if</em> y el
enunciado <em>#end</em> es lo que se escribe en la plantilla si la
evaluación resulta en un valor verdadero. En este caso, si
<em>$foo</em> es verdadero, la salida será: &quot;Velocity!&quot;. De manera
análoga, si <em>$foo</em> tiene un valor <em>null</em>, o evalua a
falso, entonces el enunciado completo es falso y no se escribe nada.
</p>
<p>
Un elemento <em>#elseif</em> ó <em>#else</em> puede utilizarse junto
con una sentencia <em>#if</em> para indicar condiciones adicionales
o la labor por defecto. Note que el Motor de Plantillas de Velocity
parará en la primera expresión que evalue a verdadero. En el ejemplo
siguiente suponga que <em>$foo</em> tiene un valor de 15 y
<em>$bar</em> tiene un valor de 6.
</p>
<div class="source"><pre>
#if( $foo &lt; 10 )
&lt;strong&gt;Vaya hacía el Norte&lt;/strong&gt;
#elseif( $foo == 10 )
&lt;strong&gt;Vaya hacía el Este&lt;/strong&gt;
#elseif( $bar == 6 )
&lt;strong&gt;Vaya al Sur&lt;/strong&gt;
#else
&lt;strong&gt;Vaya al Oeste&lt;/strong&gt;
#end
</pre></div>
<p>En este ejemplo, <em>$foo</em> es mayor que diez, por lo que las
dos primeras comparaciones fallan. A continuación se compara
<em>$bar</em> con 6, como son iguales, la salida es <strong>Vaya al
Sur</strong>
</p>
<p>
<a name="operadoreslógicosyrelacionales"><strong>Operadores
Lógicos y Relacionales</strong></a>
</p>
<p>
Velocity usa el operador de equivalencia para determinar las
relaciones entre las variables. A continuación hay un ejemplo
sencillo para ilustrar como se utiliza el operador de igualdad.
</p>
<div class="source"><pre>
#set ($foo = &quot;ácido desoxiribonucleico&quot;)
#set ($bar = &quot;ácido ribonucleico&quot;)
#if ($foo == $bar)
En este caso es claro que no son equivalentes por lo que....
In this case it's clear they aren't equivalent. So...
#else
No son equivalentes y esta será la salida.
#end
</pre></div>
<p>
Velocity tiene también operadores lógicos para el Y, el O y el NO
(AND, OR y NOT). Para mayor información vea la <a href="../vtl-reference-guide.html">Guía de Referencia VTL</a>.
A continuación se encuentran ejemplos que demuestran la utilización
de los operadores lógicos AND, OR y NOT.
</p>
<div class="source"><pre>
## Y lógico
#if( $foo &amp;&amp; $bar )
&lt;strong&gt;Esto Y aquello&lt;/strong&gt;
#end
</pre></div>
<p>
La directiva <em>#if()</em> solamente evaluará a verdadero si tanto
<em>$foo</em> como <em>$bar</em> son ciertos. Si <em>$foo</em> es
falso la expresión evaluará a falso; <em>$bar</em> no será evaluada.
Si <em>$foo</em> es verdadero el Motor de Plantillas de Velocity
verificará el valor de <em>$bar</em>; si <em>$bar</em> es cierto,
entonces toda la expresión es cierto y la salida es <strong>Esto Y
aquello</strong>. Si <em>$bar</em> es falso, entonces no habrá
ninguna salida porque toda la expresión es falsa.
</p>
<p>
El O lógico trabaja de la misma manera, pero sólo una de las
referencias debe evaluar a verdadero para que toda la expresión
evalue a verdadero. Considere el ejemplo siguiente.
</p>
<div class="source"><pre>
## O lógico
#if( $foo || $bar )
&lt;strong&gt;Esto O Aquello&lt;/strong&gt;
#end
</pre></div>
<p>
Si <em>$foo</em> es verdadero, el Motor de Plantillas de Velocity no
necesita consultar <em>$bar,</em>; sin importar si <em>$bar</em> es
cierto o falso, la expresión será cierta, y <strong>Esto O
Aquello</strong> será la salida. Si <em>$foo</em> es falso, en
cambio, es necesario verificar <em>$bar</em>. En este caso, si
<em>$bar</em> es falso, entonces la expresión es falsa y no se
escribe nada. De otro lado, si <em>$bar</em> es verdadero, entonces
toda la expresión es verdadera y el resultado es <strong>Esto O
Aquello</strong>
</p>
<p>
Con el operador lógico NO, solo hay un argumento :
</p>
<div class="source"><pre>
## NO lógico
#if( !$foo )
&lt;strong&gt;eso NO&lt;/strong&gt;
#end
</pre></div>
<p>
Aquí si <em>$foo</em> es cierto, entonces <em>!$foo</em> es falso, y
no se escribe nada. Por el contrario, si <em>$foo</em> es falso,
entonces <em>!$foo</em> será verdadero y <strong>eso NO</strong>
será escrito. Tenga cuidado de no confundir este operador con la
<em>referencia sileciosa $!foo</em>, que es algo completamente
distinto.
</p>
</div>
<a name="ciclos_foreach"></a><div class="section"><h2>Ciclos Foreach</h2>
<strong>Ciclo Foreach</strong>
<p>
El elemento <em>#foreach</em> permite la construcción de ciclos. Por
ejemplo:
</p>
<div class="source"><pre>
&lt;ul&gt;
#foreach( $producto in $todosProductos )
&lt;li&gt;$producto&lt;/li&gt;
#end
&lt;/ul&gt;
</pre></div>
<p>
Este cilco <em>#foreach</em> hace que el objeto correspondiente a la
lista de $todosProductos sea iterado buscando todos los productos de
la lista. En cada iteración del ciclo, el valor de
<em>$todosProductos</em> se asigna a la variable <em>$producto</em>.
</p>
<p>
El contenido de la variable <em>$todosProductos</em> es un Vector,
una tabla de Hashing (Hashtable) o un arreglo (Array). El valor
asignado a la variable <em>$producto</em> es un objeto Java y se
puede referenciar desde una variabkle como tal. Por ejemplo, si
<em>$product</em> fuera realmente un elemento de la clase Producto
en Java, su nombre se podría obtener referenciando el método
<em>$producto.Nombre</em> (ie: <em>$Product.getName()</em>).
</p>
<p>
Ahora supongamos que <em>$todosProductos</em> es una tabla de
Hashing. Si usted quisiera recuperar los valores de las llaves de la
tabla de Hashing, al igual que los objetos dentro de esta, usted
podría utilizar código como el siguiente:
</p>
<div class="source"><pre>
&lt;ul&gt;
#foreach( $llave in $todosProductos.keySet() )
&lt;li&gt;Llave: $llave -&gt; Valor: $todosProductos.get($llave)&lt;/li&gt;
#end
&lt;/ul&gt;
</pre></div>
<p>
Velocity proporciona una manera sencilla de obtener el contador del
ciclo para que usted pueda hacer algo como lo siguiente:
</p>
<div class="source"><pre>
&lt;table&gt;
#foreach( $cliente in $listaClientes )
&lt;tr&gt;&lt;td&gt;$velocityCount&lt;/td&gt;&lt;td&gt;$cliente.Nombre&lt;/td&gt;&lt;/tr&gt;
#end
&lt;/table&gt;
</pre></div>
<p>
El nombre por defecto para la referencia de la variable contador del
ciclo, que se especifica en el archivo
<code>velocity.properties</code>, es
$velocityCount. Por defecto el contador comienza en 1, pero esto se
puede hacer 0 o 1 en el archivo <code>velocity.properties</code>. A
continuación se muestra el fragmento de este archivo que corresponde
al contador de ciclo (en inglés, tal como aparece en el archivo
original):
</p>
<div class="source"><pre>
# Default name of the loop counter
# variable reference.
directive.foreach.counter.nombre = velocityCount
# Default starting value of the loop
# counter variable reference.
directive.foreach.counter.initial.value = 1
</pre></div>
</div>
<a name="include"></a><div class="section"><h2>Include</h2>
<p>
El elemento de script <em>#include</em> le permite al diseñador de
plantillas importar un archivo local, que después es insertado en la
localización donde se encuentra la sentencia <em>#include</em>. Los
contenidos del archivo no se muestran por intermedio del motor de
plantillas por lo que si se hacen referencias dentro del archivo,
estas no serán reemplazadas. Por motivos de seguridad el archivo que
va a ser incluido debe encontrarse en el directorio indicado por la
propiedad TEMPLATE_ROOT.
</p>
<div class="source"><pre>
#include( &quot;uno.txt&quot; )
</pre></div>
<p>
El archivo al que se refiere la directiva <em>#include</em> se
encierra entre comillas. Si mas de un archivo será incluido, los
nombres de los archivos a incluir deben ir separados por comas.
</p>
<div class="source"><pre>
#include( &quot;uno.gif&quot;,&quot;dos.txt&quot;,&quot;tres.htm&quot; )
</pre></div>
<p>
El archivo a incluir no tiene que ser referenciado por nombre, de
hecho, muchas veces es preferible usar una variable, en lugar de un
nombre de archivo. Esto puede ser útil para dirigir la salida de
acuerdo a criterios determinados cuando la solicitud de la página es
enviada, es decir, que dependa de factores como los datos del
usuario que visita la página, el momento del día, etc. A
continuación se muestra un ejemplo en el que se usan tanto un nombre
como una variable.
</p>
<div class="source"><pre>
#include( &quot;greetings.txt&quot;, $seasonalstock )
</pre></div>
</div>
<a name="parse"></a><div class="section"><h2>Parse</h2>
<p>
El elemento de script <em>#parse</em> le permite al diseñadore de
plantillas importar un archivo local que contiene VTL. Velocity
procesará el VTL y mostrará la plantilla especificada.
</p>
<div class="source"><pre>
#parse( &quot;yo.vm&quot; )
</pre></div>
<p>
Al igual que la directiva <em>#include</em>, <em>#parse</em> puede
utilizar una variable, en lugar de una plantilla. Todas las
plantillas a las que <em>#parse</em> se refiera deben incluirse bajo
TEMPLATE_ROOT. A diferencia de la directva <em>#include</em>,
<em>#parse</em> solo recibe un argumento.
</p>
<p>
Las plantillas de VTL puede tener sentencias <em>#parse</em> que se
refieran a plantillas que a su vez tengan sentencias
<em>#parse</em>. La línea <em>parse_directive.maxdepth</em> del
archivo <code>velocity.properties</code>, cuyo valor por defecto es
10, permite a los usuarios configurar el máximo número de
referencias a <em>#parse</em> que pueden ocurrir desde una única
plantilla. (Nota: Si la propiedad <em>parse_directive.maxdepth</em>
no esta dentro del archivo <code>velocity.properties</code>,
Velocity establecerá el valor por defecto en 10.) La recursión esta
permitida, por ejemplo, si la plantilla <code>hacerfoo.vm</code>
contiene las siguientes líneas:
</p>
<div class="source"><pre>
Cuenta Regresiva.
#set( $cuenta = 8 )
#parse( &quot;parsefoo.vm&quot; )
Listo hacerfoo.vm!
</pre></div>
<p>
Hay una referencia a la plantilla <code>parsefoo.vm</code>, que
contiene el siguiente código VTL:
</p>
<div class="source"><pre>
$cuenta
#set( $cuenta = $cuenta - 1 )
#if( $cuenta &gt; 0 )
#parse( &quot;parsefoo.vm&quot; )
#else
Listo parsefoo.vm!
#end
</pre></div>
<p>
Después de que se muestra &quot;Cuenta Regresiva.&quot;, Velocity pasa por
<code>parsefoo.vm</code>, contando hacía abajo desde 8. Cuando el
conteo llegue a 0, mostrará el mensaje &quot;Listo parsefoo.vm!&quot;. En este
punto Velocity volverá a <code>dofoo.vm</code> y escribirá el
mensaje &quot;Listo hacerfoo.vm!&quot;.
</p>
</div>
<a name="stop"></a><div class="section"><h2>Stop</h2>
<p>
El elemento de script <em>#stop</em> permite al diseñador parar la
ejecución del motor de plantillas y volver. Esto es útil para propósitos
de corrección de errores.
</p>
<div class="source"><pre>
#stop
</pre></div>
</div>
<a name="velocimacros"></a><div class="section"><h2>Velocimacros</h2>
<p>
El elemento de script <em>#macro</em> script permite definir un
segmento de plantilla VTL repetitivo. Los Velocimacros son muy
útiles en una amplia gama se situaciones, tanto simples como
complejas. El siguiente Velocimacro, creado con el único propósito
de ahorrar tecleo y minimizar errores tipográficos, provee una
introducción al concepto de Velocimacros
element allows template designers to.
</p>
<div class="source"><pre>
#macro( d )
&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;
#end
</pre></div>
<p>
El Velocimacro que se define en este ejemplo es <em>d</em>, y se
puede llamar de manera similar a cualquier otra directiva VTL:
</p>
<div class="source"><pre>
#d()
</pre></div>
<p>
Cuando esta plantilla sea solicitada, Velocity reemplazará <em>#d()</em>
por una fila conteniendo un única celda vacia.
</p>
<p>
Un Velocimacro puiede tomar cualquier número de argumentos -- no tener
ningún argumento, como se mostró en el primer ejemplo, es una opción --
pero cuando sea invocado el Velocimacro debe ser llamado con el mismo
número de argumentos con el que fue definido. Muchos Velocimacros se
relacionan con el entorno mucho más con su entorno que el ejemplo
demostrado anteriormente. Aquí hay un Velocimacro que recibe dos
argumentos, un color y un arreglo.
</p>
<div class="source"><pre>
#macro( filastabla $color $algunalista )
#foreach( $algo in $algunalista )
&lt;tr&gt;&lt;td bgcolor=$color&gt;$algo&lt;/td&gt;&lt;/tr&gt;
#end
#end
</pre></div>
<p>
El Velocimacro que se define en este ejemplo, <em>filastabla</em>, toma
dos argumentos. El primer argumento toma el lugar de <em>$color</em>, y
el segundo argumento el de <em>$algunalista</em>
</p>
<p>
Cualquier cosa que se pueda incluir dentro de una plantilla VTL puede
formar parte delcuerpo de un Velocimacro. El Velocimacro
<em>filastabla</em> es una sentencia <em>foreach</em>. Hay dos
sentencias <em>#end</em> dentro del Velocimacro; la primera pertenece al
<em>foreach</em> y a segunda termina la definición del Velocimacro.
</p>
<div class="source"><pre>
#set( $grandeslagos = [&quot;Superior&quot;,&quot;Michigan&quot;,&quot;Huron&quot;,&quot;Erie&quot;,&quot;Ontario&quot;] )
#set( $color = &quot;blue&quot; )
&lt;table&gt;
#filastabla( $color $grandeslagos )
&lt;/table&gt;
</pre></div>
<p>
Note que <em>$grandeslagos</em> toma el lugar de
<em>$algunalista</em>. Cuando el Velocimacro es llamado en esta
situación, la siguiente salida es generada:
</p>
<div class="source"><pre>
&lt;table&gt;
&lt;tr&gt;&lt;td bgcolor=&quot;blue&quot;&gt;Superior&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td bgcolor=&quot;blue&quot;&gt;Michigan&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td bgcolor=&quot;blue&quot;&gt;Huron&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td bgcolor=&quot;blue&quot;&gt;Erie&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td bgcolor=&quot;blue&quot;&gt;Ontario&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
</pre></div>
<p>
Los Velocimacro pueden ser definidos <em>inline</em> dentro de una
plantilla. Esto quiere decir que la definición del macro no esta
disponible para otras plantillas dentro del mimso sitio Web. Definir un
Velocimacro de tal forma que sea compartido por todas las plantillas
tiene ventajas obvias: Reduce la necesidad de redefinir el macro en
varias plantillas, ahorrando trabajo y disminuyendo las posiblidades de
error, además de asegurar que un único cambio en un archivo quedará
disponible para todas las plantillas.
</p>
<p>
Si el Velocimacro <em>#filastabla($color $lista)</em> fuera definido en
una librería, se podría utilizar en cualquiera de la plantillas
normales; se podría utilizar muchas veces con propósitos distintos. En
la plantilla <code>vegetal.vm</code> dedicado a todas las plantas, el
Velocimacro <em>#filastabla</em> podría invocarse para listar las partes
de un vegetal típico:
</p>
<div class="source"><pre>
#set( $partes = [&quot;raíz&quot;,&quot;tallo&quot;,&quot;hojas&quot;,&quot;flores&quot;,&quot;frutos&quot;] )
#set( $colorCelda = &quot;#CC00FF&quot; )
&lt;table&gt;
#filastabla( $colorCelda $parts )
&lt;/table&gt;
</pre></div>
<p>
Cuando atendiera ls solicitud de <code>vegetal.vm</code>, Velocity
encontraría el macro <em>#filastabla</em> en la librería de plantillas
(definida en el archivo <code>velocity.properties</code>) y generaría el
siguiente resultado:
</p>
<div class="source"><pre>
&lt;table&gt;
&lt;tr&gt;&lt;td bgcolor=&quot;#CC00FF&quot;&gt;raíz&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td bgcolor=&quot;#CC00FF&quot;&gt;tallo&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td bgcolor=&quot;#CC00FF&quot;&gt;hojas&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td bgcolor=&quot;#CC00FF&quot;&gt;flores&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td bgcolor=&quot;#CC00FF&quot;&gt;frutos&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
</pre></div>
<strong>Argumentos de un Velocimacro</strong>
<p>
Los Velocimacros pueden recibir como argumentos cualquiera de los
siguientes elementos de VTL:
</p>
<ul>
<li>
Referencia : cualquier cosa que comience con '$'
</li>
<li>
Cadena de caracteres : algo como &quot;$foo&quot; u 'hola'
</li>
<li>
Número : 1, 2 etc
</li>
<li>
Rango de enteros : [ 1..2] ó [$foo .. $bar]
</li>
<li>
ObjectArray : [ &quot;a&quot;, &quot;b&quot;, &quot;c&quot;]
</li>
<li>
El valor booleano &quot;verdadero&quot;
</li>
<li>
El valor booleano &quot;falso&quot;
</li>
</ul>
<p>
Cuando pase referencias como argumentos para los Velocimacros tenga
en cuenta que las referencias se pasan 'por nombre'. Esto quiere
decir que su valor es 'generado' cada vez que se usa dentro del
Velocimacros. Esta característica le permite pasar referencias con
las llamadas de método y hacer que el método se llame cada vez. Por
ejemplo, cuando llame el siguiente Velocimacro
</p>
<div class="source"><pre>
#macro( llamame $a )
$a $a $a
#end
#llamame( $foo.bar() )
</pre></div>
<p>
Esa llamada hace que el método bar() de la referencia $foo sea
llamado 3 veces.
</p>
<p>
A primera vista, esta característica parece sorprendente, pero
cuando se tiene en cuenta la motivación original de los Velocimacros
-- eliminar la duplicación de &quot;copiar y pegar&quot; del VTL usado varias
veces -- tiene mucho sentido. Permite pasar al Velocimacro objetos
con estado, como un objeto que genera colores en una secuencia
repetitiva para colorear las filas de una tabla.
</p>
<p>
Si usted no desea utilizar esta característica siempre es posible
simplemente obtener el valor del método como una nueva referencia y
pasar ese valor:
</p>
<div class="source"><pre>
#set( $mivalor = $foo.bar() )
#llamame( $mivalor )
</pre></div>
<strong>Propiedades de un Velocimacro</strong>
<p>
Varias líneas en al archivo <code>velocity.properties</code> permiten
flexibilizar la implementación de los Velocimacro. Tenga en cuenta
que estas propiedades también están documentadas en la <a href="../developer-guide.html">Guía de Desarrolladores</a>.
</p>
<p>
<code>velocimacro.library</code> - Una lista, separada por comas de
todas la librerias de plantillas de Velocimacros. Por defecto,
Velocity busca una sola librería: <em>VM_global_library.vm</em>. El
directorio en el que se buscan las plantillas también se utiliza para
localizar las librerías.
</p>
<p>
<code>velocimacro.permissions.allow.inline</code> - Esta propiedad,
que tiene como valores posibles verdadero y falso (true y false),
determina si los Velocimacros pueden ser definidos dentro de las
plantillas normales.
El valor por defecto, verdadero, le permite a los diseñadores
definir por si mismos macros en las plantillas.
</p>
<p>
<code>velocimacro.permissions.allow.inline.to.replace.global</code> -
Con valores posibles verdadero y falso (true y false), esta
propiedad le permite al usuario decidir si un Velocimacro definido
inline dentro de una plantilla puede reemplazar a la plantilla
global, que fue cargada al comienzo por medio de la propiedad
<code>velocimacro.library</code>. El valor por defecto, falso
(<code>false</code>), evita que los Velocimacros definidos en una
plantilla reemplacen a los que fueron cargados al inicio.
</p>
<p>
<code>velocimacro.permissions.allow.inline.local.scope</code> -
Con valores posibles verdadero y falso (true y false), valor por
defecto falso, esta propiedad dice si los Velocimacros definidos
inline son 'visibles' únicamente para la plantilla que los define.
Usted puede usar esta característica para hacer algunos trucos de
VM - si un VM global llama a otro VM global, con ancance inline, una
plantilla puede definir una implementación privada del segundo VM,
que será llamada por el primer VM cuando sea invocado en esa
plantilla. Ninguna de las otras templates es afectada.
</p>
<p>
<code>velocimacro.context.localscope</code> -
Con valores posibles verdadero y falso (true y false), valor por
defecto falso. Cuando es verdadera cualquier modificación al
contexto por medio de un #set() dentro de un Velocimacro se
considera local a ese Velocimacro y no afecta permanentemente al
contexto.
</p>
<p>
<code>velocimacro.library.autoreload</code> - Esta propiedad
controla el cargado automático de la libreria de Velocimacros. El
valor por defecto es <code>false</code>. Cuando es verdadero
(<code>true</code>) la librería fuente de un Velocimacro que ha sido
invocado será verificada para comprobar que no haya cambiado, y si
lo ha hecho será recargada. Esta característica le permite cambiar y
probar librerías de macros sin necesidad de reiniciar la aplicación
o el contenedor de servlets, de la misma manera que se hace con
plantillas normales.
Este modo solo funciona cuando el caché esta <i>apagado</i>
en los cargadores de recursos( e.g. <code>file.resource.loader.cache
= false</code>).
Esta característica esta pensada para el proceso de desarrollo, no
el de producción.
This property
</p>
<strong>Cosas y Casos de Velocimacros</strong>
<p>
Actualmente los Velocimacros deben ser definidos antes de ser
utilizados por primera vez dentro de una plantilla. Esto significa
que sus declaraciones de #macro() deben aparecerantes de que usted
utilice los Velocimacros.
</p>
<p>
Esto es importante recordarlo cuando usted intenta hacerle #parse()
a una plantilla que contiene directivas #macro(). Como el #parse()
ocurre en tiempo de ejecución, y el parser decide si un elemento que
parece una VM es realmente un VM cuando esta haciendo el #parse(),
entonces probablemente el #parse() de un conjunto de declaraciones
no funciona como se esperaría. Para evitar este problema,
simplemente utilice la propiedad
<code>velocimacro.library</code>para cargar todos sus VM cuando se
inicie la aplicación.
</p>
</div>
<a name="escapando_directivas_vtl"></a><div class="section"><h2>Escapando Directivas VTL</h2>
<p>
Las directivas de VTL se pueden escapar con el palote invertido o
backslash (&quot;\&quot;) de manera similar a como se escapan las referencias de
VTL válidas.
</p>
<div class="source"><pre>
## #include( &quot;a.txt&quot; ) se muestra como &lt;contenidos of de a.txt&gt;
#include( &quot;a.txt&quot; )
## \#include( &quot;a.txt&quot; ) se muestra como #include( &quot;a.txt&quot; )
\#include( &quot;a.txt&quot; )
## \\#include ( &quot;a.txt&quot; ) se muestra como \&lt;contenidos de a.txt&gt;
\\#include ( &quot;a.txt&quot; )
</pre></div>
<p>
Se debe tener especial cuidado cuando se escapan directivas de VTL que
contienen varios elementos de script en una misma directiva (como en las
sentencias if-else-end). A continuación seencuentra un ejemplo de un
condicional típico de VTL:
</p>
<div class="source"><pre>
#if( $jazz )
Vyacheslav Ganelin
#end
</pre></div>
<p>
Si <em>$jazz</em> es cierto la salida es
</p>
<div class="source"><pre>
Vyacheslav Ganelin
</pre></div>
<p>
Si <em>$jazz</em> es fals, no hay salida. Escapar elementos de script
altera la salida. Considere el siguiente caso:
</p>
<div class="source"><pre>
\#if( $jazz )
Vyacheslav Ganelin
\#end
</pre></div>
<p>
Sin importar si <em>$jazz</em> es verdadero o falso, la salida será:
</p>
<div class="source"><pre>
#if($ jazz )
Vyacheslav Ganelin
#end
</pre></div>
<p>
De hecho, como todos los elementos de script están escapados,
<em>$jazz</em> nunca se evalúa por su valor booleano.
Suponga que los palotes invertidos preceden a elementos de script que
están legitimamente escapados:
</p>
<div class="source"><pre>
\\#if( $jazz )
Vyacheslav Ganelin
\\#end
</pre></div>
<p>
En este caso, si <em>$jazz</em> es verdadero, la salida es
</p>
<div class="source"><pre>
\ Vyacheslav Ganelin
\
</pre></div>
<p>
Para entender esto tenga en cuenta que <code>#if( arg )</code>, cuando
es terminado por un caracter de fin de línea (retorno) omitirá ese
caracter de la salida. Por lo tanto, el cuerpo del bloque
<code>#if()</code> va a continuación del primer '\', que se generó a
partir del '\\' que precedía el <code>#if()</code> dentro de la
pantilla. El último \ está en una línea distinta que el texto porqué hay
un retorno después de 'Ganelin', por lo que el \\ final, que precede el
<code>#end</code> hace parte del cuerpo del bloque.
</p>
<p>
Si <em>$jazz</em> es falso, la salida es
</p>
<div class="source"><pre>
\
</pre></div>
<p>
Tenga en cuenta que las
cosas dejan de funcionar si los elementos de script no son escapados
de manera correcta.
</p>
<div class="source"><pre>
\\\#if( $jazz )
Vyacheslave Ganelin
\\#end
</pre></div>
<p>
Aquí el <em>#if</em> esta escapado, pero hay un <em>#end</em> que
sobra; al haber demasiados cierres (end) sin sus correspondientes
aperturas (foreach ó if) se generará un error de procesamiento.
</p>
</div>
<a name="vtl:_asuntos_de_formato"></a><div class="section"><h2>VTL: Asuntos de Formato</h2>
<p>
A pesar de que el VTL mostrado en esta guía del usuario se muestra en la
mayoría de los casos con cambios de línea y espacios en blanco, el VTL
que se muestra a continuación
</p>
<div class="source"><pre>
#set( $imperial = [&quot;Munetaka&quot;,&quot;Koreyasu&quot;,&quot;Hisakira&quot;,&quot;Morikune&quot;] )
#foreach( $shogun in $imperial )
$shogun
#end
</pre></div>
<p>
es tan válido como el siguiente trozo de código que Geir Magnusson Jr.
publicó a la lista de correo de usuarios de Velocity para ilustrar un
punto sin ninguna relación:
</p>
<div class="source"><pre>
Enviame #set($foo = [&quot;$10 y &quot;,&quot;un pastel&quot;])#foreach($a in $foo)$a #end
por favor.
</pre></div>
<p>
El comportamiento de Velocity es el de ingnorar el espacio vacío de
exceso. La directiva descrita anteriormente puede reescribirse como:
</p>
<div class="source"><pre>
Enviame
#set( $foo = [&quot;$10 y &quot;,&quot;un pastel&quot;] )
#foreach( $a in $foo )
$a
#end
por favor.
</pre></div>
<p>
o como
</p>
<div class="source"><pre>
Enviame
#set($foo = [&quot;$10 y &quot;,&quot;un pastel&quot;])
#foreach ($a in $foo )$a
#end por favor.
</pre></div>
<p>
En cada caso la salida será la misma
</p>
</div>
<a name="otras_características_y_miscelánea"></a><div class="section"><h2>Otras Características y Miscelánea</h2>
<a name="matemáticas"></a><div class="section"><h3>Matemáticas</h3>
<p>
Velocity tiene varias funciones matemáticas incluidas que pueden ser
utilizadas en plantillas con la directiva <em>set</em>. Las siguientes
ecuaciones son ejemplos de suma, resta, multiplicación y división
respectivamente:
</p>
<div class="source"><pre>
#set( $foo = $bar + 3 )
#set( $foo = $bar - 4 )
#set( $foo = $bar * 6 )
#set( $foo = $bar / 2 )
</pre></div>
<p>
Cuando se realiza una división el resultado es un entero. El residuo se
puede obtener utilizando el operador módulo (<em>%</em>).
</p>
<div class="source"><pre>
#set( $foo = $bar % 5 )
</pre></div>
</div>
<a name="el_operador_de_rango"></a><div class="section"><h3>El Operador de Rango</h3>
<p>
El operador de rango se puede usar en conjunción con las directivas
<em>#set</em> y <em>#foreach</em>. Es muy útil por su capacidad para
crear arreglos de objetos compuestos por enteros. La construcción del
operador rango es como sigue:
</p>
<div class="source"><pre>
[n..m]
</pre></div>
<p>
Tanto <em>n</em> como <em>m</em> debe ser o producir enteros. El hecho
de que <em>m</em> sea mayor o menor que <em>n</em> no importa; en ese
caso el rango cimplemente contará hacía abajo. A continuación se
muestran varios ejemplos de uso del operador rango:
</p>
<div class="source"><pre>
Primer ejemplo:
#foreach( $foo in [1..5] )
$foo
#end
Segundo ejemplo:
#foreach( $bar in [2..-2] )
$bar
#end
Tercer ejemplo:
#set( $arr = [0..1] )
#foreach( $i in $arr )
$i
#end
Cuarto ejemplo:
[1..3]
</pre></div>
<p>
Produce lo siguiente:
</p>
<div class="source"><pre>
Primer ejemplo:
1 2 3 4 5
Segundo ejemplo:
2 1 0 -1 -2
Tercer ejemplo:
0 1
Cuarto ejemplo:
[1..3]
</pre></div>
<p>
enga en cuenta que el operador de rango solamente produce un arreglo
cuando se utiliza junto con las directivas <em>#set</em> y
<em>#foreach</em>, como se demuestra en el cuarto ejemplo.
</p>
<p>
Los diseñadores de páginas preocupados con hacer los tamaños de las
tablas iguales, pero con información que puede no se suficiente para
llenar la tabla, encontrarán el operador de rango particularmente útil.
</p>
</div>
<a name="temas_avanzados:_escapando_y_"></a><div class="section"><h3>Temas Avanzados: Escapando y !</h3>
<p>
Cuando una referencia se hace silenciona con el caracter <em>!</em> y el
caracter <em>!</em> viene precedido por un caracter de escape
<em>\</em> la referencia se maneja de una manera diferente. Observe las
diferencias entre el escape sencillo y el caso especial en el que
<em>\</em> precede a <em>!</em>:
</p>
<div class="source"><pre>
#set( $foo = &quot;bar&quot; )
$\!foo
$\!{foo}
$\\!foo
$\\\!foo
</pre></div>
<p>
Se muestra como:
</p>
<div class="source"><pre>
$!foo
$!{foo}
$\!foo
$\\!foo
</pre></div>
<p>
A diferencia del escape normal, donde <em>\</em> precede a <em>$</em>:
</p>
<div class="source"><pre>
\$foo
\$!foo
\$!{foo}
\\$!{foo}
</pre></div>
<p>
Se muestra como:
</p>
<div class="source"><pre>
$foo
$!foo
$!{foo}
\bar
</pre></div>
</div>
<a name="miscelánea_de_velocimacro"></a><div class="section"><h3>Miscelánea de Velocimacro</h3>
<p>
Esta sección contiene un conjunto de preguntas frecuentes (FAQ)
relacionadas con Velocimacros. Esta sección cambiará con el tiempo, por
lo que es bueno revisar si hay información nueva de cuando en cuando.
</p>
<p>
Nota : A través de esta sección 'Velocimacro' será abreviado como 'VM'.
</p>
<strong>¿Puedo usar una directiva u otro VM como argumento para un VM?</strong>
<p>
Ejemplo : <code>#center( #bold(&quot;hola&quot;) )</code>
</p>
<p>
No. Una directiva no es un argumento válido para una directiva y, para
la mayoría de los propósitos prácticos, un VM es una directiva.
</p>
<p>
<i>Sin embargo...</i>, hay cosas que usted puede hacer. Una solución
sencilla es aprovechar el hecho de que la doble comilla (&quot;) muestra sus
contenidos, por lo que usted puede hacer algo como
</p>
<div class="source"><pre>
#set($cosas = &quot;#bold('hola')&quot; )
#center( $cosas )
</pre></div>
<p>
Puede tener un paso...
</p>
<div class="source"><pre>
#center( &quot;#bold( 'hola' )&quot; )
</pre></div>
<p>
Tenga en cuenta que en segundo ejemplo el argumentos es evaluado <i>
dentro</i> de la VM, no a nivel del llamador. En otras palabras, el
argumento para el VM es pasado completo y evaluado dentro del VM al que
se le pasa. Esto le permite hacer cosas como :
</p>
<div class="source"><pre>
#macro( interno $foo )
interno : $foo
#end
#macro( externo $foo )
#set($bar = &quot;externolala&quot;)
externo : $foo
#end
#set($bar = 'calltimelala')
#externo( &quot;#interno($bar)&quot; )
</pre></div>
<p>
Donde la salida es
</p>
<div class="source"><pre>
externo : interno : externolala
</pre></div>
<p>
la evaluación de &quot;#interno($bar)&quot; se lleva a cabo dentro de #externo(),
por lo que el valor $bar establecido dentro de #externo() es el que se
utiliza.
</p>
<p>
Estas es una característica intencional y celosamente protegina - los
argumentos se pasan por nombre a los VM para que usted le pueda
'entregar' a los VMs referencias con estado como
</p>
<div class="source"><pre>
#macro( foo $color )
&lt;tr bgcolor=$color&gt;&lt;td&gt;Hola&lt;/td&gt;&lt;/tr&gt;
&lt;tr bgcolor=$color&gt;&lt;td&gt;Todos&lt;/td&gt;&lt;/tr&gt;
#end
#foo( $bar.colorFila() )
</pre></div>
<p>
Y lograr que colorFila() se llame varias veces, en lugar de solo una.
Par evitar que eso ocurra invoque el método fuera del VM y pásele el
valor al VM.
</p>
<div class="source"><pre>
#set($color = $bar.colorFila())
#foo( $color )
</pre></div>
<strong>¿Puedo registrar Velocimacros por medio de #parse() ? </strong>
<p>
Actualmente, los Velocimacros deben ser definidos antes de ser usados
por primera vez dentro de una plantilla. Esto significa que sus
declaraciones de #macro() deben venir antes de que usted use los
Velocimacros.
</p>
<p>
Esto es importante recordarlo cuando usted intenta hacerle #parse()
a una plantilla que contiene directivas #macro(). Como el #parse()
ocurre en tiempo de ejecución, y el parser decide si un elemento que
parece una VM es realmente un VM cuando esta haciendo el #parse(),
entonces probablemente el #parse() de un conjunto de declaraciones
no funciona como se esperaría. Para evitar este problema,
simplemente utilice la propiedad
<code>velocimacro.library</code>para cargar todos sus VM cuando se
inicie la aplicación.
</p>
<strong>¿Qué es la auto recarga de Velocimacros?</strong>
<p>
Existe una propiedad, pensada para usarse en <i>desarrollo</i>, no
en producción :
</p>
<p>
<code>velocimacro.library.autoreload</code>
</p>
<p>
que tiene como valor por defecto falso. Cuando se hace verdadera
<em>junto con</em> <code>&lt;tipo&gt;.resource.loader.cache = false</code>
(where &lt;tipo&gt; es el nombre del cargador de recursos que usted
esta utilizando, como 'file' para archivos) entonces el motor de
Velocity recargará automáticamente los cambios en su librerías en el
momento en que los haga para que usted no tenga que reinicar el motor
de servlets o la aplicación, o hacer otros trucos para lograr que sus
Velocimacros se recarguen.
</p>
<p>
A continuación se muestra un conjunto sencillo de propiedades de
configuración.
</p>
<div class="source"><pre>
file.resource.loader.path = templates
file.resource.loader.cache = false
velocimacro.library.autoreload = true
</pre></div>
<p>No utilice esto en producción</p>
</div>
<a name="concatenación_de_cadenas"></a><div class="section"><h3>Concatenación de Cadenas</h3>
<p>
Una pregunta común que los desarrolladores formulan es <i>¿Cómo
concateno cadenas de caracteres? ¿Existe algún análogo al operador
'+' en Java?</i>
</p>
<p>
Para concatenar referencias en VTL usted solo tiene que 'ponerlos
juntos'. El contenido del contexto en donde usted desee juntar las
referencias es importante, por lo que ilustraremos con algunos
ejemplos.
</p>
<p>
En el código regular de una plantilla (cuando usted lo mezcla con
contenido normal)
</p>
<div class="source"><pre>
#set( $tam = &quot;Big&quot; )
#set( $nombre = &quot;Ben&quot; )
El reloj es $tam$nombre.
</pre></div>
<p>
y la salida será 'El reloj es BigBen'. Para caso más interesantes,
como cuando ested desea concatenar las cadenas que pasará a un
método, o establecer el valor de una nueva referencia use
</p>
<div class="source"><pre>
#set( $tam = &quot;Big&quot; )
#set( $nombre = &quot;Ben&quot; )
#set($reloj = &quot;$tam$nombre&quot; )
El reloj es $reloj.
</pre></div>
<p>
Que resultará en la mismo que el ejemplo anterior. Como un ejemplo
final, cuando usted desea mezclar cadenas 'estáticas' con sus
referencias usted puede necesitar 'referencias formales':
</p>
<div class="source"><pre>
#set( $tam = &quot;Big&quot; )
#set( $nombre = &quot;Ben&quot; )
#set($reloj = &quot;${tam}Alto$nombre&quot; )
El reloj es $reloj.
</pre></div>
<p>
Ahora el resultado es 'El reloj es BigAltoBen'. La notación formal
es necesaria para que el procesador de las plantillas sepa que usted
quiso usar la referencia '$tam', en lugar de '$tamAlto', que sería
lo que entendería si los corchetes '{}' no estuvieran presentes.
</p>
</div>
</div>
<a name="retroalimentación"></a><div class="section"><h2>Retroalimentación</h2>
<p>
Si encuentra algún error en este manual o tiene algún otro comentario o
retroalimentación relacionada con la guía del usuario de Velocity, por
favor envie un correo a <a href="mailto:user@velocity.apache.org">La lista de usuarios
de Velocity</a>.
Gracias!
</p>
</div>
</div>
</div>
<div class="clear">
<hr/>
</div>
<div id="footer">
<div class="xright">&#169;
2000-2007
The Apache Software Foundation
Last Published: 2007-03-06 19:34:54
</div>
<div class="clear">
<hr/>
</div>
</div>
</body>
</html>