java whitespace velocity removing-whitespace

java - ¿Cómo puedo recortar los espacios en blanco por velocidad?



whitespace velocity (7)

Tengo un método llamado render_something que puede crear muchos espacios en blanco, por ejemplo:

<a href="#">#render_something(''xxx'')</a>

El resultado puede ser:

<a href="#"> something that generate from redner_something </a>

Que en realidad quiero que sea así:

<a href="#">something that generate from redner_something</a>

¿Tiene la velocidad algo como esto?

#trim(#render_something(''xxx''))


Solución

En la clase donde crea el VelocityEngine, agregue un método de la siguiente manera

public String trim(String str) { return str.trim()/*.replace("/n", "").replace("/r", "")*/; }

a continuación, agregue lo siguiente a VelocityContext que cree:

context.put("trimmer", this);

y finalmente en la plantilla de velocidad, haga lo siguiente

<a href="#">$trimmer.trim("#render_something(''xxx'')")</a>

¿Por qué funciona?

Aunque el comportamiento de Velocity está claramente definido, puede ser un poco difícil ver cómo funciona a veces. El método trim () separado es necesario para obtener la secuencia de caracteres de la plantilla en un método Java en el que puede llamar al trim () real en la cadena. Por lo que sé, no hay ajustes dentro de Velocity, pero siempre puedes volver a llamar a Java con trucos como este.

Las comillas dobles son necesarias porque #render_something es solo una macro, no una llamada de función, esto significa que los resultados de las declaraciones en la macro se colocan textualmente en el punto donde la macro se "ejecuta".


Acabo de leer este artículo en Velocity Whitespace Acabado, que sugiere algunas soluciones que incluyen Velocity Whitespace Truncated By Line Comment .

Básicamente, esto sugiere comentar saltos de línea al colocar comentarios al final de cada línea. También sugiere no sangrar el código en sus macros para evitar que aparezcan espacios superfluos (una de mis palabras favoritas).

TBH no es una gran solución pero puede satisfacer sus necesidades. Simplemente ponga ## al final de cada línea en su macro y eso hará las cosas un poco más agradables ... más o menos


Aquí está mi solución alternativa a la velocidad de engullimiento de espacios en blanco que permite tabular la estructura de la plantilla.

Cada texto de plantilla se procesa previamente en la primera carga en ResourceLoader personalizado:

private String enhanceTemplate(String body) { if (!body.startsWith("##preserveWhitespace")) { body = body.replaceAll("(##.*)?[ //t//r]*//n+[ //t//r]*", Matcher.quoteReplacement("##/n")); body = body.trim(); } return body; }

Esto reemplaza todas las nuevas líneas y espacios ajustados con solo una nueva línea comentada .

Los saltos de línea y los espacios de cola se pueden insertar explícitamente con las variables $ br y $ sp del contexto predeterminado:

private static final VelocityContext DEFAULT_CONTEXT = new VelocityContext(new HashMap<String, String>() {{ put("sp", " "); put("br", "/n"); }});


En algunos casos, he tenido que minimizar esencialmente mi script como lo haría js o css. Funciona bien, aunque no es tan fácil de leer para los humanos. Solo una opción más para eliminar el exceso de espacio:

<ul class="tabs">#foreach($par in $bodypars)#set( $parLen = ${_MathTool.toInteger($bodypars.size())} )#set( $parLn = $parLen - 1 )#set( $thClass = ''tb''+${parLn} )#set( $thaClass = '''' )#if( $foreach.index == 1 )#set( $thClass = ${thClass}+'' selected'' )#set( $thaClass = '' selected'' )#end#if($foreach.index != 0 && $parLen <= $maxTabs)#set ( $btitle = $_XPathTool.selectSingleNode($par,''item-subtitle'') )<li class="${thClass}">#if($!btitle && $btitle != '''')<a href="#" class="#cleanString($btitle.value.toLowerCase())${thaClass}">$_SerializerTool.serialize($btitle, true)</a>#end</li>#end#end</ul>


Inspirado por Velocity Whitespace truncado por comentario de línea, se podrían usar comentarios de bloque en lugar de comentarios de línea para un resultado mejor

#foreach( $record in $records )#** *##if( $record.id == 0 )#** *##end #end

Con una sintaxis decente resaltando los comentarios no son muy molestos.


Luché un rato para encontrar una solución sencilla para el engullimiento de los espacios en blanco, de modo que aquí se me ocurrió una. Está inspirado en la respuesta de Vadzim y en esta página http://wiki.apache.org/velocity/StructuredGlobbingResourceLoader

El StructuredGlobbingResourceLoader que podemos encontrar en el sitio web tiene un comportamiento complejo y no elimina ningún tipo de espacio en blanco, así que lo modifiqué para obtener el comportamiento simple: "Eliminar cualquier espacio en blanco al principio de las líneas y agregar un comentario en el final de cada línea "(lo que impide la evaluación del salto de línea). El filtro se aplica en el flujo de entrada en el momento de la carga.

Este tipo de plantilla de velocidad.

#if($value) the value is $value #end

se transforma en

#if($value)## the value is $value## #end##

Luego, si desea tener saltos de línea o espacios en blanco al principio de la línea, tendrá que poner ($ br, "/ n") y poner ($ sp, "") en su contexto como los explicados por Vadzim y usarlos explícitamente en su plantilla . Esta forma de hacer le permitirá mantener plantillas con sangría, con el máximo control.

tome la clase de esta página http://wiki.apache.org/velocity/StructuredGlobbingResourceLoader cambie la clase extendida al tipo de cargador que necesita (este usa el cargador de aplicaciones web) reemplace el método read () con el código que proporciono. la clase como su cargador de recursos en sus propiedades. Ejemplo para el cargador de aplicación web: webapp.resource.loader.class = ... StructuredGlobbingResourceLoader

public int read() throws IOException { int ch; switch(state){ case bol: //beginning of line, read until non-indentation character while(true){ ch = in.read(); if (ch!=(int)'' '' && ch!=(int)''/t''){ state = State.content; return processChar(ch); } } case content: ch = in.read(); return processChar(ch); //eol states replace all "/n" by "##/n" case eol1: state = State.eol2; return (int)''#''; case eol2: state = State.bol; return (int)''/n''; case eof: return -1; } return -1; } //Return the normal character if not end of file or /n private int processChar(int ch){ switch(ch){ case -1: state = State.eof; return -1; case (int)''/n'': state = State.eol1; return (int)''#''; default: return ch; } }

Cualquier comentario sobre mi implementación es bienvenido


Parece que solo java nativo trim () funciona.

$someValue.trim() funciona para mí