私はたくさんの空白を作成できる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 を含むいくつかの回避策を提案しています。
これは基本的に、各行の終わりにコメントを置くことによって改行をコメントアウトすることを提案します。また、マクロ内のコードをインデントしないで、余分な(私のお気に入りの単語の1つ)スペースが発生しないようにすることもお勧めします。
TBHそれは素晴らしい解決策ではありませんが、あなたのニーズに合うかもしれません。簡単に言えば ##
マクロの各行の終わりに置くと、状況が少し良くなります...
Javaネイティブのtrim()が機能するようです。
$someValue.trim()
は私のために働きます
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の動作は明確に定義されていますが、時々どのように動作するかを確認するのは少し難しいかもしれません。テンプレートからchar-sequenceをJavaメソッドに文字列で実際のtrim()を呼び出すことができるメソッドに)取得するには、個別のtrim()メソッドが必要です。 Velocity内ではトリムはありませんが、このようなトリックでJavaにいつでもコールバックできます。
#render_somethingは単なるマクロであり、関数呼び出しではないため、二重引用符が必要です。これは、マクロ内のステートメントの結果が、マクロが「実行される」ポイントに逐語的に挿入されることを意味します。
私はしばらくの間、空白文字の乱れの簡単な解決策を見つけるのに苦労しました。これは、Vadzimの回答とこのページに触発されたものです http://wiki.Apache.org/velocity/StructuredGlobbingResourceLoader
Webサイトで見つけられる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 gobbling に対する私の代替ソリューションです。
各テンプレートテキストは、カスタム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;
}
これは、すべての改行と調整可能なスペースを1つだけに置き換えます コメント付き改行 。
改行と末尾スペースは、デフォルトのコンテキストから$ brおよび$ sp変数を使用して明示的に挿入できます。
private static final VelocityContext DEFAULT_CONTEXT = new VelocityContext(new HashMap<String, String>() {{
put("sp", " ");
put("br", "\n");
}});
場合によっては、jsやcssのように、スクリプトを本質的に最小化する必要がありました。人間が読むのは簡単ではありませんが、うまく機能します。余分なスペースを排除するためのもう1つのオプション:
<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>
Velocity Whitespace Truncated By Line Comment からインスピレーションを得て、より見栄えの良い結果を得るために、行コメントの代わりにブロックコメントを使用できます。
#foreach( $record in $records )#**
*##if( $record.id == 0 )#**
*##end
#end
構文を適切に強調表示すると、コメントが目立たなくなります。