簡體   English   中英

如何通過速度修剪空白

[英]How can I trim whitespace by Velocity

我有一個名為 render_something 的方法,它可以創建很多空白,例如:

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

結果可以是:

<a href="#">     

           something that generate from redner_something


              </a> 

實際上我希望它是這樣的:

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

速度有這樣的東西嗎?

#trim(#render_something('xxx'))

我剛剛閱讀了這篇關於Velocity Whitespace Gobbling 的文章,其中提出了一些解決方法,包括Velocity Whitespace Truncated By Line Comment

這基本上建議通過在每行末尾添加注釋來注釋換行符。 它還建議不要在宏中縮進代碼以防止出現多余的(我最喜歡的詞之一)空格。

TBH 這不是一個很好的解決方案,但可能適合您的需求。 只需將##放在宏中每一行的末尾,這將使事情變得更好......有點

似乎只有 java native trim() 有效。

$someValue.trim()對我$someValue.trim()

我掙扎了一段時間才找到解決空白吞噬的簡單解決方案,所以我終於想出了一個解決方案。 它的靈感來自 Vadzim 的回答和這個頁面http://wiki.apache.org/velocity/StructuredGlobbingResourceLoader

我們可以在網站上找到的 StructuredGlobbingResourceLoader 具有復雜的行為,並且沒有去除任何類型的空格,因此我對其進行了修改以獲得簡單的行為:“刪除行開頭的任何空格,並在每行的結尾”(這可以防止換行評估)。 過濾器在加載時應用於輸入流。

這種速度模板

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

轉化為

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

然后,如果你想有換行符或行首空格,你必須像 Vadzim 解釋的那樣在你的上下文中 put($br,"\\n") 和 put($sp," ") 並在你的模板中明確使用它們. 這種做法將允許您保留縮進模板,並最大限度地控制。

從此頁面http://wiki.apache.org/velocity/StructuredGlobbingResourceLoader 中獲取類將擴展類更改為您需要的加載器類型(這個使用 webapp 加載器)將 read() 方法替換為我提供的代碼使用類作為您屬性中的資源加載器。 webapp 加載器示例: 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;
    }
}

歡迎對我的實施提供任何反饋

行注釋截斷Velocity Whitespace 的啟發,可以使用塊注釋代替行注釋以獲得更好看的結果:

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

使用體面的語法突出顯示注釋並不是很突兀。

解決方案

在創建 VelocityEngine 的類中,添加如下方法

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

然后將以下內容添加到您創建的 VelocityContext 中:

    context.put("trimmer", this);

最后在速度模板中執行以下操作

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

為什么有效?

盡管 Velocity 的行為是明確定義的,但有時查看它的工作原理可能有點棘手。 單獨的trim() 方法對於將字符序列從模板獲取到Java 方法中是必要的,您可以在該方法中調用字符串上的實際trim()。 據我所知,Velocity 內部沒有修剪,但你總是可以用這樣的技巧回調 Java。

雙引號是必要的,因為 #render_something 只是一個宏,而不是函數調用,這意味着宏中語句的結果被逐字放入宏“執行”點。

這是我對速度空白吞噬的替代解決方案,它允許制表模板結構。

每個模板文本在自定義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;
}

這將僅用一個注釋換行符替換所有新行和調整空格。

可以使用默認上下文中的 $br 和 $sp 變量顯式插入換行符和尾隨空格:

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

在某些情況下,我必須像使用 js 或 css 一樣從本質上最小化我的腳本。 它運行良好,盡管人類閱讀它並不那么容易。 消除多余空間的另一種選擇:

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

您可以使用標准的 java 修剪,注意您的變量是否是對象而不是字符串。

$string.trim()  //work fine
$object.trim()  //exception

祝你有美好的一天!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM