لم يتم تصميم Moustache.java للسماح للأطراف غير الموثوقة بتقديم النماذج. قد يكون من الممكن قفله لتوفير ذلك بشكل آمن، ولكنه غير آمن بشكل افتراضي. استخدم SafeMustacheFactory وأضف جميع القوالب والأجزاء إلى القائمة البيضاء.
اعتبارًا من الإصدار 0.9.0، أصبح mustache.java الآن Java 8 فقط. لدعم Java 6/7، استخدم 0.8.x.
لا توجد تبعيات خارجية ومكتبة المترجم هي ~ 100 كيلو.
Moustache.java هو مشتق من mustache.js.
توجد مجموعة Google للدعم والأسئلة: http://groups.google.com/group/mustachejava
جيثب سي: https://github.com/spullara/mustache.java/actions/workflows/maven.yml
وثائق واجهة برمجة التطبيقات: http://spullara.github.io/mustache/apidocs/
أكبر عملية نشر إنتاجية لـ Moustache.java:
بفضل YourKit للعديد من تحسينات الأداء:
يتفضل YourKit بدعم مشروع mustache.java مفتوح المصدر من خلال ملف تعريف Java كامل الميزات. إن شركة YourKit, LLC هي منشئة الأدوات المبتكرة والذكية لتوصيف تطبيقات Java و.NET. قم بإلقاء نظرة على منتجات البرامج الرائدة الخاصة بـ YourKit:
طلب المساهمة:
التوثيق:
mustache
، واختلافات المسافات البيضاءIterable
للسلوكيات الشبيهة بالقائمةCallable
بالتقييم المتزامن إذا تم تكوين ExecutorService
{{<super}}{{$content}}...{{/content}}{{/super}}
){{#func1}}...{{/func1}}
) باستخدام Function
من Java 8 (ما بعد الاستبدال)TemplateFunction
إذا كنت تريد mustache.java أن يعيد تحليل نتائج وظيفتك/lambda (الاستبدال المسبق)handlebar
القوالب + بيانات json لنماذج بالحجم الطبيعي السريعة للقوالب بواسطة المصممينCapturingMustacheVisitor
للنماذج والاختباراتinvert
نصًا وقالبًا وتحل البياناتأداء:
com.github.mustachejavabenchmarks
في وحدة compiler
indy
وحدة Codegen و Invocdynamic لتجميع القوالب وصولاً إلى الرمز الثانويبناء الاقتراحات:
معلومات تبعية Maven (على سبيل المثال، في معظم الحالات الشائعة، ستحتاج فقط إلى وحدة compiler
):
جافا 8+:
< dependency >
< groupId >com.github.spullara.mustache.java</ groupId >
< artifactId >compiler</ artifactId >
< version >0.9.10</ version >
</ dependency >
جافا 6/7:
< dependency >
< groupId >com.github.spullara.mustache.java</ groupId >
< artifactId >compiler</ artifactId >
< version >0.8.18</ version >
</ dependency >
مثال لملف القالب:
{{#items}}
Name: {{name}}
Price: {{price}}
{{#features}}
Feature: {{description}}
{{/features}}
{{/items}}
قد يتم تشغيله بواسطة بعض رموز الدعم:
public class Context {
List < Item > items () {
return Arrays . asList (
new Item ( "Item 1" , "$19.99" , Arrays . asList ( new Feature ( "New!" ), new Feature ( "Awesome!" ))),
new Item ( "Item 2" , "$29.99" , Arrays . asList ( new Feature ( "Old." ), new Feature ( "Ugly." )))
);
}
static class Item {
Item ( String name , String price , List < Feature > features ) {
this . name = name ;
this . price = price ;
this . features = features ;
}
String name , price ;
List < Feature > features ;
}
static class Feature {
Feature ( String description ) {
this . description = description ;
}
String description ;
}
}
وسيؤدي إلى:
Name: Item 1
Price: $19.99
Feature: New!
Feature: Awesome!
Name: Item 2
Price: $29.99
Feature: Old.
Feature: Ugly.
يتم تقييم القالب بشكل تسلسلي. على سبيل المثال، إذا كان لديك رمز حظر ضمن إحدى عمليات رد الاتصال الخاصة بك، فسيتوقف النظام مؤقتًا أثناء تنفيذها:
static class Feature {
Feature ( String description ) {
this . description = description ;
}
String description () throws InterruptedException {
Thread . sleep ( 1000 );
return description ;
}
}
إذا قمت بتغيير الوصف لإرجاع Callable
بدلاً من ذلك، فسيتم تنفيذه تلقائيًا في سلسلة رسائل منفصلة إذا كنت قد قدمت ExecutorService
عندما قمت بإنشاء MustacheFactory
.
Callable < String > description () throws InterruptedException {
return new Callable < String >() {
@ Override
public String call () throws Exception {
Thread . sleep ( 1000 );
return description ;
}
};
}
يؤدي ذلك إلى تمكين المهام المجدولة وسلوك البث والإدخال/الإخراج غير المتزامن. تحقق من وحدة example
لرؤية مثال كامل وشامل:
package mustachejava ;
import com . github . mustachejava . DefaultMustacheFactory ;
import com . github . mustachejava . Mustache ;
import com . github . mustachejava . MustacheFactory ;
import java . io . IOException ;
import java . io . PrintWriter ;
import java . io . Writer ;
import java . util . Arrays ;
import java . util . List ;
public class Example {
List < Item > items () {
return Arrays . asList (
new Item ( "Item 1" , "$19.99" , Arrays . asList ( new Feature ( "New!" ), new Feature ( "Awesome!" ))),
new Item ( "Item 2" , "$29.99" , Arrays . asList ( new Feature ( "Old." ), new Feature ( "Ugly." )))
);
}
static class Item {
Item ( String name , String price , List < Feature > features ) {
this . name = name ;
this . price = price ;
this . features = features ;
}
String name , price ;
List < Feature > features ;
}
static class Feature {
Feature ( String description ) {
this . description = description ;
}
String description ;
}
public static void main ( String [] args ) throws IOException {
MustacheFactory mf = new DefaultMustacheFactory ();
Mustache mustache = mf . compile ( "template.mustache" );
mustache . execute ( new PrintWriter ( System . out ), new Example ()). flush ();
}
}
تتمثل الطريقة البديلة لتوفير المتغيرات في استخدام كائن Map، مثل:
public static void main ( String [] args ) throws IOException {
HashMap < String , Object > scopes = new HashMap < String , Object >();
scopes . put ( "name" , "Mustache" );
scopes . put ( "feature" , new Feature ( "Perfect!" ));
Writer writer = new OutputStreamWriter ( System . out );
MustacheFactory mf = new DefaultMustacheFactory ();
Mustache mustache = mf . compile ( new StringReader ( "{{name}}, {{feature.description}}!" ), "example" );
mustache . execute ( writer , scopes );
writer . flush ();
}