web-dev-qa-db-de.com

Wie kann ich Whitespace nach Velocity schneiden?

Ich habe eine Methode namens render_something, die viel Leerraum erzeugen kann, zum Beispiel:

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

Das Ergebnis kann sein:

<a href="#">     

           something that generate from redner_something


              </a> 

Was ich eigentlich will, dass es so ist:

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

Hat die Geschwindigkeit so etwas?

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

Ich habe gerade diesen Artikel zu Velocity Whitespace Gobbling gelesen, das einige Umgehungsmöglichkeiten vorschlägt, darunter Velocity Whitespace abgeschnitten von Zeile Kommentar .

Dies empfiehlt im Grunde das Auskommentieren von Zeilenumbrüchen, indem am Ende jeder Zeile Kommentare eingefügt werden. Außerdem wird empfohlen, den Code in Ihren Makros nicht einzuziehen, um zu verhindern, dass überflüssige Leerzeichen (eines meiner Lieblingswörter) auftreten.

TBH ist keine großartige Lösung, kann jedoch Ihren Bedürfnissen entsprechen. Setzen Sie einfach ## an das Ende jeder Zeile in Ihrem Makro, und das macht die Sache ein bisschen schöner ... irgendwie

12
Edd

Es scheint, dass nur Java native trim () funktioniert.

$someValue.trim() arbeitet für mich

6
Deckard

Lösung

Fügen Sie in der Klasse, in der Sie die VelocityEngine erstellen, eine Methode wie folgt hinzu

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

fügen Sie dann dem von Ihnen erstellten VelocityContext Folgendes hinzu:

    context.put("trimmer", this);

und schließlich in der Geschwindigkeitsvorlage folgendes tun

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

Warum funktioniert es?

Obwohl das Verhalten von Velocity klar definiert ist, kann es etwas schwierig sein, zu sehen, wie es manchmal funktioniert. Die separate trim () - Methode ist notwendig, um die Zeichenfolge aus der Vorlage in eine Java-Methode zu bringen, in der Sie das eigentliche trim () für den String aufrufen können. Soweit ich weiß, gibt es in Velocity keinen Trimm, aber Sie können mit Tricks wie diesem immer nach Java zurückrufen.

Die Anführungszeichen sind notwendig, da #render_something nur ein Makro und kein Funktionsaufruf ist. Dies bedeutet, dass die Ergebnisse der Anweisungen im Makro wörtlich in den Punkt gebracht werden, an dem das Makro "ausgeführt" wird.

2
centic

Ich bemühte mich eine Weile, um eine geradlinige Lösung für den Whitespace-Gobbling zu finden, also hier die, die ich mir schließlich ausgedacht hatte. Es ist inspiriert von und Vadzims Antwort und dieser Seite http://wiki.Apache.org/velocity/StructuredGlobbingResourceLoader

Der StructuredGlobbingResourceLoader, den wir auf der Website finden können, weist ein komplexes Verhalten auf und entfernt keinerlei Arten von Leerzeichen. Daher habe ich es geändert, um das einfache Verhalten zu erhalten: "Löschen Sie alle Leerzeichen am Anfang der Zeilen und fügen Sie einen Kommentar bei ein das Ende jeder Zeile "(verhindert die Linebreak-Auswertung). Der Filter wird beim Laden auf den Eingabestrom angewendet.

Diese Art von Geschwindigkeitsvorlage

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

wird in umgewandelt

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

Wenn Sie dann Zeilenumbrüche oder Zeilenumbrüche haben möchten, müssen Sie ($ br, "\ n") und ($ sp, "") in Ihren Kontext einfügen, wie Vadzim's erklärt, und diese explizit in Ihrer Vorlage verwenden . Auf diese Weise können Sie eingerückte Vorlagen mit maximaler Kontrolle beibehalten.

nehmen Sie die Klasse von dieser Seite http://wiki.Apache.org/velocity/StructuredGlobbingResourceLoader ändern Sie die erweiterte Klasse in die Art des Laders, den Sie benötigen (dieser verwendet den webapp-Loader). Ersetzen Sie die read () - Methode durch die Von mir zur Verfügung gestellter Code verwenden Sie die Klasse als Ressourcenlader in Ihren Eigenschaften. Beispiel für den Webapp-Loader: 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;
    }
}

Jedes Feedback zu meiner Implementierung ist willkommen

2
Geoffrey

Hier ist meine alternative Lösung zu Geschwindigkeits-Whitespace-Gobbling , die die Struktur der Tab-Vorlagen ermöglicht.

Jeder Vorlagentext wird beim ersten Laden in der benutzerdefinierten ResourceLoader vorverarbeitet:

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

Dies ersetzt alle neuen Zeilen und angepassten Leerzeichen durch nur eine kommentierte Zeile .

Zeilenumbrüche und Leerzeichen können explizit mit den Variablen $ br und $ sp aus dem Standardkontext eingefügt werden:

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

In einigen Fällen musste ich mein Skript im Wesentlichen minimieren, wie ich es von js oder css gewohnt bin. Es funktioniert gut, obwohl es für Menschen nicht so einfach zu lesen ist. Eine weitere Option, um den Platzüberschuss zu beseitigen:

<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.

Inspiriert durch Velocity Whitespace abgeschnitten durch Zeilenkommentar Für ein besseres Ergebnis könnte man Blockkommentare anstelle von Zeilenkommentaren verwenden:

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

Mit einer anständigen Syntax-Hervorhebung sind die Kommentare nicht sehr aufdringlich.

0
Dzmitry