web-dev-qa-db-fra.com

Comment puis-je réduire les espaces par Velocity

J'ai une méthode appelée render_sething qui peut créer beaucoup d'espaces, par exemple:

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

Le résultat peut être:

<a href="#">     

           something that generate from redner_something


              </a> 

En fait, je veux que ce soit comme ça:

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

Est-ce que la vélocité a quelque chose comme ça?

#trim(#render_something('xxx'))
17
Surasin Tancharoen

Je viens de lire cet article sur Velocity Whitespace Gobbling qui suggère quelques solutions de contournement, notamment Velocity Whitespace tronqué par un commentaire de ligne .

Cela suggère essentiellement de commenter les sauts de ligne en plaçant des commentaires à la fin de chaque ligne. Cela suggère également de ne pas indenter le code dans vos macros pour éviter que des espaces superflus (un de mes mots préférés) ne se produisent.

TBH n'est pas une bonne solution mais peut répondre à vos besoins. Mettez simplement ## à la fin de chaque ligne de votre macro et cela rendra les choses un peu plus agréables… en quelque sorte

12
Edd

Il semble que le trim () natif de Java fonctionne.

$someValue.trim() travaille pour moi

6
Deckard

Solution

Dans la classe où vous créez VelocityEngine, ajoutez une méthode comme suit

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

ajoutez ensuite les éléments suivants au VelocityContext que vous créez:

    context.put("trimmer", this);

et enfin dans le modèle de vitesse faire ce qui suit

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

Pourquoi ça marche?

Bien que le comportement de Velocity soit clairement défini, il peut être un peu difficile de voir comment cela fonctionne parfois. La méthode trim () - distincte est nécessaire pour extraire la séquence de caractères du modèle en une méthode Java dans laquelle vous pouvez appeler le trim () réel sur la chaîne. Autant que je sache, Velocity n’a pas de finesse, mais vous pouvez toujours faire appel à Java avec des astuces comme celle-ci.

Les guillemets doubles sont nécessaires car #render_something n'est qu'une macro et non un appel de fonction. Cela signifie que les résultats des instructions de la macro sont mis textuellement dans le point où la macro est "exécutée".

2
centic

J'ai eu du mal à trouver une solution simple au problème de l'encombrement des espaces, alors voici celle que j'ai finalement trouvée. Il est inspiré de et de la réponse de Vadzim et de cette page http://wiki.Apache.org/velocity/StructuredGlobbingResourceLoader

Le StructuredGlobbingResourceLoader que nous pouvons trouver sur le site Web a un comportement complexe et ne supprime aucun type d’espace. Nous l’avons donc modifié pour obtenir le comportement simple: "Supprimez tout espace au début des lignes et ajoutez un commentaire à la fin de chaque ligne "(ce qui empêche l’évaluation de saut de ligne). Le filtre est appliqué au flux d'entrée au moment du chargement.

Ce genre de gabarit de vélocité

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

est transformé en

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

Ensuite, si vous voulez avoir des sauts de ligne ou des espaces blancs de début de ligne, vous devez mettre ($ br, "\ n") et mettre ($ sp, "") dans votre contexte, comme expliqué par Vadzim, et les utiliser explicitement dans votre modèle. . Cette façon de faire vous permettra de conserver les modèles en retrait, avec un contrôle maximal.

prenez la classe de cette page http://wiki.Apache.org/velocity/StructuredGlobbingResourceLoader changez la classe étendue en fonction du type de chargeur dont vous avez besoin (celui-ci utilise le chargeur d'application Web) remplace la méthode read () par le code que je fournis utilise la classe comme chargeur de ressources dans vos propriétés. Exemple pour le chargeur d'applications 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;
    }
}

Tous les commentaires sur ma mise en œuvre sont les bienvenus

2
Geoffrey

Voici ma solution alternative à vitesse engloutissant qui permet de tabuler la structure du modèle.

Chaque texte de modèle est prétraité lors du premier chargement dans la variable personnalisée ResourceLoader:

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;
}

Ceci remplace toutes les nouvelles lignes et les espaces de réglage par un seul nouvelle ligne commentée .

Les sauts de ligne et les espaces de fin peuvent être insérés explicitement avec les variables $ br et $ sp du contexte par défaut:

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

Dans certains cas, j'ai dû essentiellement minimiser mon script comme je le ferais js ou css. Cela fonctionne bien, bien que ce ne soit pas aussi facile à lire pour les humains. Juste une autre option pour éliminer l'espace excédentaire:

<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>
1
Sarah L.

Inspiré par Velocity Whitespace tronqué par un commentaire de ligne on peut utiliser des commentaires de blocage au lieu de commentaires de ligne pour un résultat plus esthétique:

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

Avec une syntaxe décente, les commentaires ne sont pas très gênants.

0
Dzmitry