Rockerは、プロジェクトの残りの部分とともにコンパイルされた静的にタイプされたプレーンJavaオブジェクトテンプレートを生成する、ゼロコピーレンダリングに近いゼロコピーレンダリング、スピーディなテンプレートエンジンです。生産時の「ウォームアップ」時間、ゆっくりとした反射ベースのロジック、または開発中にキャッチされるべきだった厄介な驚きはもうありません。
ロジック、反復、および値のための標準のJava式を使用して、直感的でタグレス構文を使用してテンプレートを記述します。 Rocker's Specialを使用しますか?
ヌルセーフ評価のプレゼンスオペレーター。すべての重いリフティングは、開発中にロッカーパーサーによって行われます。これにより、ランタイムの依存関係がほんの一握りのクラスに抑えられます。ロッカーはテンプレートを解析し、十分に文書化されたJavaソースファイルを生成します(そのため、その仕組みを簡単に検査して理解できます)。
次の機能が含まれています。
?
プレゼンスオペレーターは、ヌル値を簡素化するために構文を拡張します。Project by Fizzed、Inc。(Twitterでフォロー:@fizzed_inc)
OpenSourceプロジェクトの開発と維持には、かなりの時間が必要です。このプロジェクトが役立つ場合や商業サポートが必要な場合は、チャットしたいと思います。 [email protected]にメールを送ってください
プロジェクトスポンサーには、次の利点が含まれる場合があります。
次のテンプレートベンチマークに基づいて、Rockerは明確な勝者です。また、フリーマーカーよりも〜250%高速であるが、メモリの注文も必要である。
ほとんどのテンプレートはWebサイトに使用されているため、Rockerテンプレートがどのように機能し、レンダリングプロセス中に互いに呼び出すことができるかを示す簡単なサンプルを以下に示します。共通のヘッダーとフッターを含むテンプレートと、ボディコンテンツのプレースホルダーを作成します。テンプレートsrc/main/java/views/main.rocker.html
を作成します
@args (String title, RockerBody content)
< html >
< head >
< title > @title </ title >
</ head >
< body >
@content
</ body >
</ html >
ユーザーに実際に表示する予定のテンプレートは、Common/Headerフッターのコンテキスト内でコンテンツをレンダリングします。 Javaの用語では、別のテンプレート内で実行されるレンダリングコードのブロックを渡しています。テンプレートsrc/main/java/views/index.rocker.html
を作成します
@args (String message)
@views.main.template("Home") - > {
< h1 > Hello @message! </ h1 >
}
ねえ、 RockerBody content
引数はどうですか? Syntax Readmeで詳細に説明しますが、今のところはその唯一の特別なタイプの引数であることを理解し、テンプレートが「ボディ」が渡されることを期待していることをロッカーに指示します。
ロッカーパーサーは、各テンプレートのJavaソースファイルを生成します。それらはtarget/generated-sources/rocker/views/main.java
およびtarget/generated-sources/rocker/views/index.java
になります。アプリケーションでは、そのようなインデックステンプレートをレンダリングできます。
static public void main ( String [] args ) {
String output = views . index . template ( "World" )
. render ()
. toString ();
}
出力は次のとおりです。
< html >
< head >
< title > Home </ title >
</ head >
< body >
< h1 > Hello World! </ h1 >
</ body >
</ html >
Javaソースを生成してコード内を覗くと、これがどのように機能するかを見るのは簡単です。 Views.indexクラスは、Views.main Templateインスタンスを作成し、それをレンダリングします。また、Views.mainが@content
変数を呼び出すときにレンダリングするブロックを渡します。構文は、ラムダがJava 8で定義される方法と同じです(Java 8にはLambdasで実装され、Java 6/7の匿名の内部クラス)。 Rockerは、他のテンプレートを作成するテンプレートが同じレンダリングコンテキスト(出力バッファー、アプリケーション固有のコンテキスト/暗黙の状態)を共有することを確認するために、舞台裏の多くのことを行います。
syntax.mdファイルをチェックアウトしてください。ロッカーの構文に包括的なディープダイビングを行います。
Rockerには、シームレスに統合されているフレームワークのリストが増えています。追加された新しいフレームワークにリンクしたい場合は、問題を提出するか、PRを提出してください。
各ロッカーテンプレートの静的(プレーンテキスト)は、(デフォルトでは)ターゲットチャーセット(UTF-8など)に既に変換されている静的バイト配列として内部で保存されます。テンプレートがレンダリングされると、静的バイト配列がすべてのリクエストで再利用されます。 Rockerは、再使用されたバイト配列と動的コンテンツの複合(リンクリスト)ビューを保存する最適化された出力ストリームをレンダリングします。テンプレートは、主に新しいメモリを割り当て、そのコンテンツをコピーし、各リクエストのターゲットチャーセットに変換するのではなく、同じ炭化する静的コンテンツで構成されているため、ロッカーはそれへのポインターを何度も使用します。また。この手法は、高速でメモリ効率の高いレンダリングを生成します。
9000バイトのプレーン静的テキストと1000バイトの動的コンテンツで構成されるテンプレートがあるとしましょう。この最適化がなければ、10000リクエスト(10000バイトx 10000リクエスト)にサービスを提供するために、100MBのメモリが必要です。この最適化により、10000リクエスト(1000バイトx 10000リクエスト)にサービスを提供するには、約10MBのメモリが必要です。メモリの低いことに加えて、90MBのメモリコピーと90MBのUTF-8文字列 - >バイト変換も切り取ります。かなり便利な最適化。
すべてがプロジェクトのコンパイラと他のJavaソースコードとともにコンパイルされています。テンプレート内の動的コードは、最終的に標準のJavaに変換され、コンパイルされます。反射は使用されていません。
バージョン0.10.0は、開発中にホットリロードテンプレートのサポートを導入しました。ホットリロードを使用すると、テンプレートソースコードを変更し、保存し、JVMを再起動することなく、次のリクエストで変更をアクティブにすることができます。ロッカーは、柔軟性のために2つの異なるフレーバーのホットリロードを提供します。
Rockerテンプレートの主な機能は、テンプレートがJavaコンパイラによる使用、引数、ロジックなどをコンパイルすることです。
バージョン0.10.0では、テンプレートの基礎となる構造が変更され、テンプレートが2つの基礎となるクラスを生成しました。各テンプレートは、モデルクラス(インターフェイス)と実装クラス(レンダラー)を生成します。アプリケーションはモデルと直接対話するため、ロッカーは実装クラスを動的に再コンパイルしてリロードできます。
フレーバー1の主な利点は、アプリケーションコードが同じままであり、Javaコンパイラによってコンパイル時間チェックされることですが、テンプレートコンテンツは実行時に変更され、自動的にリロードできることです。テンプレート引数を実際に変更する場合にのみ、アプリケーションを再起動する必要があります。
完全に動的なテンプレートの利便性を好む場合、フレーバー2は、テンプレートモデルクラス(そのインターフェイス)と実装クラス(そのレンダラー)の両方のホットリロードをサポートします。アプリケーションはコンパイル時間チェックの一部と小さなパフォーマンスヒットを失いますが、すべてが再装備可能であるという利便性を獲得します。アプリケーションがテンプレートを使用する方法も異なります。
import com . fizzed . rocker . Rocker
...
// dynamic interfaces, dynamic implementation
String rendered = Rocker . template ( "views/index.rocker.html" )
. bind ( "val" , "ValueA" )
. render ()
. toString ();
テンプレートパスと引数はランタイムチェックされます。各バインド可能な値は、テンプレートで宣言された名前とタイプと一致する必要があることに注意してください。
バインド可能なマップには、リラックスしたバインドが利用できるものよりも多くの値が含まれている場合があります。リラックスした代替品は、属性が必要なリストに追加された場合、レンダリングに失敗しません。例えば:
@args (String name)
Hello ${name}!
リラックスモードでレンダリングします:
Map map = new HashMap ();
map . put ( "name" , "Joe" );
map . put ( "age" , 42 );
Rocker . template ( "views/hello.rocker.html" )
. relaxedBind ( map )
. render ();
// -> Hello Joe!
ホットリロードのサポートは、バージョン0.10.0のデフォルトで生成されたテンプレートに追加されます。サポートを無効にしたい場合は、構成/システムプロパティrocker.optimize
ビルド中にtrueに設定します。コードはデフォルトでテンプレートに存在するため、実行時に電源を入れるだけです。
rocker-compiler
依存関係をビルドに追加する必要があります。この依存関係は、開発中にのみ存在する必要があり、生産中に削除することができます。 Mavenでは、これは、 provided
範囲に依存関係を追加することを意味します。
< dependency >
< groupId >com.fizzed</ groupId >
< artifactId >rocker-compiler</ artifactId >
< version >2.1.0</ version >
< scope >provided</ scope >
</ dependency >
実行時にホットリロードをアクティブにします。システムプロパティまたはプログラムでホットリロードをアクティブにすることができます。 Mavenのシステムプロパティでホットリロードをアクティブにするため。
mvn -Drocker.reloading=true ...rest of args...
または、プログラムでホットリロードをアクティブにすることもできます。
import com . fizzed . rocker . runtime . RockerRuntime
...
RockerRuntime . getInstance (). setReloading ( true );
ホットリロードが動作していることを示す簡単な例があります。このプロジェクトは、Blazeを使用してスクリプトタスクを支援します。以下を実行します
java -jar blaze.jar hot_reload
ブラウザをhttp:// localhost:8080に向けます
次に、 rocker-test-reload/src/test/java/views/index.rocker.html
変更および保存し、ブラウザを更新します。
Rockerは、パーサー/ジェネレーターとランタイムの2つのコンポーネントで構成されています。プロジェクトでロッカーを使用するには、アプリケーションにランタイム依存関係を追加し、ビルドツールのパーサーを有効にしてから最初のテンプレートを作成します。
RockerはMaven Centralに公開されています。 Mavenの依存関係として追加するには:
< dependency >
< groupId >com.fizzed</ groupId >
< artifactId >rocker-runtime</ artifactId >
< version >2.1.0</ version >
</ dependency >
<!-- for hot-reloading support only during development -->
< dependency >
< groupId >com.fizzed</ groupId >
< artifactId >rocker-compiler</ artifactId >
< version >2.1.0</ version >
< scope >provided</ scope >
</ dependency >
Gradleの依存関係として追加するには:
repositories {
mavenCentral()
}
dependencies {
compile group : ' com.fizzed ' , name : ' rocker-runtime ' , version : ' 2.1.0 '
// add rocker-compiler dependency as needed
}
Rockerは、MavenとGradle Off-Off-Off-Off-Offorをサポートしています。
POMに以下を追加してください
< build >
< plugins >
< plugin >
< groupId >com.fizzed</ groupId >
< artifactId >rocker-maven-plugin</ artifactId >
< version >2.1.0</ version >
< executions >
< execution >
< id >generate-rocker-templates</ id >
< phase >generate-sources</ phase >
< goals >
< goal >generate</ goal >
</ goals >
</ execution >
</ executions >
</ plugin >
</ plugins >
</ build >
デフォルトでは、Rockerは、 src/main/java
の.rocker.html
で終了するテンプレートファイルを再帰的に処理します。ディレクトリテンプレートが保存されます。生成されたJavaクラスが配置される標準のJavaパッケージになります。生成されたJavaソースファイルはtarget/generated-sources/rocker
に保存されます。プラグインは、この生成されたディレクトリをソースルートに追加することになります。
次のプロパティがサポートされています。
templateDirectory
は、テンプレートファイルを見つけて解析するときに再帰的に開始するベースディレクトリです。 Java package
テンプレートは、このディレクトリをベースとして使用するように生成されます。したがって、 ${templateDirectory}/views/mytemplate.rocker.html
がある場合、ロッカーは${outputDirectory}/views/mytemplate.java
を生成します。デフォルトは${project.build.sourceDirectory}
になります。
outputDirectory
は、パーサーがテンプレートのソースを生成するディレクトリです。デフォルトは${project.build.directory}/generated-sources/rocker
になります
classDirectory
は、ホットリロード機能が実行時にクラスをコンパイルするディレクトリです。デフォルトは${project.build.outputDirectory}
になります}
failOnError
解析/生成エラーがMavenを失敗させるかどうかを判断します。デフォルトはtrueです。
skip
、プラグインの実行をスキップするかどうかを判断します。デフォルトはfalseになります。
touchFile
、Javaソースを正常に生成した後、「タッチ」するファイルです。他のワークフローのトリガーに役立ちます。多くのIDEは、リロードするように明示的に指示されたり、Maven POM.XMLファイルが変更されたりしない限り、コード完了のために生成されたソースを自動的にリロードしません。したがって、この値はデフォルトで${basedir}/pom.xml
に設定されます。通常、これを有効にすることは無害です。
skipTouch
TouchFileを無効にします。デフォルトはfalseになります。
addAsSources
コンパイルされるソースとしてMavenにoutputDirectoryを追加します。デフォルトはtrueです。
addAsTestSources
コンパイルするテスト源としてMavenにoutputDirectoryを追加します。デフォルトはfalseになります。 Trueの場合、これはAddAssourcesの前に評価され、Mavenにテストコードとしてテンプレートをコンパイルするように効果的に指示します。
以下のプロパティもサポートされていますが、これらが本質的にパーサーへのパススルーオーバーライドであることを理解することが重要であり、すべてロッカーのデフォルト値にデフォルトです。
javaVersion
は、テンプレートをコンパイルしてランタイム互換が必要なJavaバージョンです。デフォルトは、Mavenを実行するJVMのJavaバージョン( "1.8"など)のデフォルトです。
optimize
生成されたテンプレートからホットリロードサポートが削除されるかどうかを判断します。デフォルトでfalse。
extendsClass
すべてのテンプレートの実装が拡張するクラスです。すべてのテンプレートを拡張したいアプリケーション固有の中間クラスに役立ちます。デフォルトはRockerのデフォルトになります。
extendsModelClass
すべてのテンプレートモデルが拡張するクラスです。すべてのテンプレートモデルを拡張したいアプリケーション固有の中間クラスに役立ちます。デフォルトはRockerのデフォルトになります。
plainTextStrategy
は、テンプレートの一部としてプレーンテキストを埋め込むために使用される戦略です。デフォルトはstatic_byte_arrays_via_unloaded_classですが、graalvm互換性が必要な場合は、static_byte_arraysを試してみます
discardLogicWhitespace
ロジック/コントロールブロックの一部であると判断されたテンプレート内の空白を廃棄する必要があるかどうかを決定します。レンダリングされたコンテンツをよりプロフェッショナルに見えるようにしながら、フォーマットの多くをそのままにしておくことができます。デフォルトはRockerのデフォルトになります。
targetCharset
、テンプレート出力のターゲットcharSetです。デフォルトはRockerのデフォルトになります。
suffixRegex
解析するテンプレートを見つけるために使用する正規表現です。デフォルトはRockerのデフォルトになります。
markAsGenerated
生成されたクラスに@Generated Annotationを追加します。保持はクラスであるため、注釈はソースコードではなくクラスファイルにのみ依存するツールで使用できます。デフォルトはRockerのデフォルトになります。
Gradleプラグインを寄稿してくれた@victory
と@mnlipp
に感謝します。 @etiennestuder
は、考慮したい代替のGradleプラグインもありました。 Rocker's GradleプラグインはGradle.orgに公開されています。ビルドスクリプトに以下を追加するだけです。
plugins {
id " com.fizzed.rocker " version " 2.1.0 "
}
sourceSets {
main {
rocker {
srcDir( ' src/main/java ' )
}
}
}
rocker {
// (All settings are shown with their defaults)
//
// Skips building templates all together
skip false
// Base directory for generated java sources, actual target is sub directory
// with the name of the source set. The value is passed through project.file().
outputBaseDirectory = " $b uildDir /generated-src/rocker "
// Base directory for the directory where the hot reload feature
// will (re)compile classes to at runtime (and where `rocker-compiler.conf`
// is generated, which is used by RockerRuntime.getInstance().setReloading(true)).
// The actual target is a sub directory with the name of the source set.
// The value is passed through project.file().
classBaseDirectory = " $b uildDir /classes "
failOnError true
skipTouch true
// must not be empty when skipTouch is equal to false
touchFile " "
javaVersion ' 1.8 '
extendsClass null
extendsModelClass null
optimize null
discardLogicWhitespace null
targetCharset null
suffixRegex null
postProcessing null
markAsGenerated null
}
テンプレートの構文については以下で詳しく説明しますが、現時点では${templateDirectory}/views/HelloWorld.rocker.html
で新しいファイルを作成します
@*
Example of hello world
*@
@args (String message)
Hello @message!
プロジェクトをコンパイルし、テンプレートの使用を開始する時間です。あなたはそれをJavaからそう呼ぶことができます:
static public void main ( String [] args ) {
String output = views . HelloWorld
. template ( "World" )
. render ()
. toString ();
}
Rockerは、バイト配列として(デフォルトで)出力テンプレートに大きく最適化されています。テンプレートがレンダリングするデフォルトのRockerOutput
は、 com.fizzed.rocker.runtime.ArrayOfByteArraysOutput
のタイプです。これは、バイトアレイまたは非同期IOに最適です。ただし、フレームワークには、文字列(またはその他のカスタム出力)への最適化されたレンダリングの機能があります。
文字列に効率的にレンダリングするには:
import com . fizzed . rocker . runtime . StringBuilderOutput ;
static public void main ( String [] args ) {
StringBuilderOutput output = views . HelloWorld
. template ( "World" )
. render ( StringBuilderOutput . FACTORY );
String text = output . toString ();
}
出力ストリームに効率的にレンダリングするには:
import com . fizzed . rocker . runtime . OutputStreamOutput ;
static public void main ( String [] args ) throws Exception {
final OutputStream os = new FileOutputStream ( new File ( "test" ));
OutputStreamOutput output = views . HelloWorld
. template ( "World" )
. render (( contentType , charsetName ) -> new OutputStreamOutput ( contentType , os , charsetName ));
}
レンダリング中に例外がある場合、outputStreamには部分的なテンプレートがレンダリングされることに注意してください(例外のポイントまで)。ほとんどの場合、デフォルトのcom.fizzed.rocker.runtime.ArrayOfByteArraysOutput
にレンダリングし、バイト配列のバッファーをoutputStreamに直接書き出すことをお勧めします。
動作中のロッカーのデモが数多くあります。テンプレートの解析からモデルへの解析から、HTTPサーバーで結果を非同期的に送信します。このプロジェクトは、Blazeを使用してスクリプトタスクを支援します。完全なリストについては、以下を実行します。
java -jar blaze.jar -l
Copyright(c)2015+ Fizzed、Inc。
この作業は、バージョン2.0のApacheライセンスに基づいてライセンスされています。詳細については、ライセンスを参照してください。