Moustache.java ไม่ได้ออกแบบมาเพื่อให้บุคคลที่ไม่น่าเชื่อถือจัดทำเทมเพลตได้ อาจเป็นไปได้ที่จะล็อคมันลงเพื่อความปลอดภัย แต่โดยค่าเริ่มต้นแล้วจะไม่ปลอดภัย ใช้ SafeMustacheFactory และไวท์ลิสต์เทมเพลตและบางส่วนทั้งหมด
ตั้งแต่รีลีส 0.9.0 mustache.java ตอนนี้เป็น Java 8 เท่านั้น สำหรับการรองรับ Java 6/7 ให้ใช้ 0.8.x
ไม่มีการพึ่งพาภายนอกและไลบรารีคอมไพเลอร์อยู่ที่ ~100k
Mustache.java เป็นอนุพันธ์ของ mustache.js
มี Google Group สำหรับการสนับสนุนและคำถาม: http://groups.google.com/group/mustachejava
Github CI: https://github.com/spullara/mustache.java/actions/workflows/maven.yml
เอกสาร API: http://spullara.github.io/mustache/apidocs/
การใช้งานการผลิตที่ใหญ่ที่สุดของ Moustache.java:
ขอบคุณ YourKit สำหรับการปรับปรุงประสิทธิภาพมากมาย:
YourKit ขอสนับสนุนโปรเจ็กต์โอเพ่นซอร์ส mustache.java ด้วย Java Profiler ที่มีคุณสมบัติครบถ้วน YourKit, LLC คือผู้สร้างเครื่องมือที่เป็นนวัตกรรมและชาญฉลาดสำหรับการสร้างโปรไฟล์แอปพลิเคชัน Java และ .NET ดูผลิตภัณฑ์ซอฟต์แวร์ชั้นนำของ YourKit:
คำขอรับการสนับสนุน:
เอกสารประกอบ:
mustache
ทั้งหมด ความแตกต่างของช่องว่างแบบโมดูโลIterable
ใดๆ สามารถใช้กับพฤติกรรมที่คล้ายกับรายการได้Callable
ช่วยให้สามารถประเมินผลพร้อมกันได้หากมีการกำหนดค่า ExecutorService
{{<super}}{{$content}}...{{/content}}{{/super}}
){{#func1}}...{{/func1}}
) ได้รับการปรับใช้โดยใช้ Function
จาก Java 8 (หลังการทดแทน)TemplateFunction
หากคุณต้องการให้ mustache.java แยกวิเคราะห์ผลลัพธ์ของฟังก์ชัน/แลมบ์ดาของคุณใหม่ (การทดแทนล่วงหน้า)handlebar
จะเรนเดอร์เทมเพลต + ข้อมูล json เพื่อการจำลองเทมเพลตอย่างรวดเร็วโดยนักออกแบบCapturingMustacheVisitor
สำหรับการเยาะเย้ยและการทดสอบinvert
สามารถรับข้อความและเทมเพลตและแก้ไขข้อมูลได้ผลงาน:
com.github.mustachejavabenchmarks
ในโมดูล compiler
indy
ใช้โมดูล codegen และ intakedynamic เพื่อคอมไพล์เทมเพลตจนถึง bytecodeคำแนะนำในการสร้าง:
ข้อมูลการพึ่งพา 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 ;
}
};
}
ซึ่งเปิดใช้งานงานที่กำหนดเวลาไว้ พฤติกรรมการสตรีม และ i/o แบบอะซิงโครนัส ตรวจสอบโมดูล 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 ();
}