Mustache.java ist nicht dafür konzipiert, nicht vertrauenswürdigen Parteien die Bereitstellung von Vorlagen zu ermöglichen. Es kann möglich sein, es zu sperren, um dies sicher zu gewährleisten, aber standardmäßig ist es UNSICHER. Verwenden Sie die SafeMustacheFactory und setzen Sie alle Vorlagen und Partials auf die Whitelist.
Ab Version 0.9.0 ist mustache.java nur noch Java 8. Für die Unterstützung von Java 6/7 verwenden Sie 0.8.x.
Es gibt keine externen Abhängigkeiten und die Compilerbibliothek ist ca. 100 KB groß.
Mustache.java ist eine Ableitung von mustache.js.
Für Support und Fragen gibt es eine Google-Gruppe: http://groups.google.com/group/mustachejava
Github CI: https://github.com/spullara/mustache.java/actions/workflows/maven.yml
API-Dokumentation: http://spullara.github.io/mustache/apidocs/
Größter Produktionseinsatz von Mustache.java:
Vielen Dank an YourKit für viele Leistungsverbesserungen:
YourKit unterstützt freundlicherweise das Open-Source-Projekt mustache.java mit seinem voll ausgestatteten Java Profiler. YourKit, LLC ist der Entwickler innovativer und intelligenter Tools zur Profilierung von Java- und .NET-Anwendungen. Werfen Sie einen Blick auf die führenden Softwareprodukte von YourKit:
Bitte um Beiträge:
Dokumentation:
mustache
-SpezifikationstestsIterable
kann für listenartiges Verhalten verwendet werdenCallable
ermöglicht eine gleichzeitige Auswertung, wenn ein ExecutorService
konfiguriert ist{{<super}}{{$content}}...{{/content}}{{/super}}
){{#func1}}...{{/func1}}
) werden mithilfe von Function
aus Java 8 (nach der Substitution) implementiert.TemplateFunction
, wenn Sie möchten, dass mustache.java die Ergebnisse Ihrer Funktion/Lambda erneut analysiert (vor der Substitution).handlebar
rendert Vorlagen und JSON-Daten für schnelle Vorlagenmodelle durch DesignerCapturingMustacheVisitor
für Mocks und Tests verwendeninvert
Aufruf kann Text und eine Vorlage annehmen und nach den Daten auflösenLeistung:
com.github.mustachejavabenchmarks
im compiler
Modulindy
-Modul verwendet das Codegen-Modul und invokedynamic, um Vorlagen bis hin zum Bytecode zu kompilierenBauvorschläge:
Informationen zur Maven-Abhängigkeit (d. h. in den meisten Fällen benötigen Sie nur das compiler
Modul):
Java 8+:
< dependency >
< groupId >com.github.spullara.mustache.java</ groupId >
< artifactId >compiler</ artifactId >
< version >0.9.10</ version >
</ dependency >
Java 6/7:
< dependency >
< groupId >com.github.spullara.mustache.java</ groupId >
< artifactId >compiler</ artifactId >
< version >0.8.18</ version >
</ dependency >
Beispiel-Vorlagendatei:
{{#items}}
Name: {{name}}
Price: {{price}}
{{#features}}
Feature: {{description}}
{{/features}}
{{/items}}
Könnte durch einen Backing-Code unterstützt werden:
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 ;
}
}
Und würde Folgendes zur Folge haben:
Name: Item 1
Price: $19.99
Feature: New!
Feature: Awesome!
Name: Item 2
Price: $29.99
Feature: Old.
Feature: Ugly.
Die Auswertung der Vorlage erfolgt seriell. Wenn Sie beispielsweise einen Blockierungscode in einem Ihrer Rückrufe haben, pausiert das System bei der Ausführung:
static class Feature {
Feature ( String description ) {
this . description = description ;
}
String description () throws InterruptedException {
Thread . sleep ( 1000 );
return description ;
}
}
Wenn Sie die Beschreibung ändern, um stattdessen ein Callable
zurückzugeben, wird es automatisch in einem separaten Thread ausgeführt, wenn Sie beim Erstellen Ihrer MustacheFactory
einen ExecutorService
bereitgestellt haben.
Callable < String > description () throws InterruptedException {
return new Callable < String >() {
@ Override
public String call () throws Exception {
Thread . sleep ( 1000 );
return description ;
}
};
}
Dies ermöglicht geplante Aufgaben, Streaming-Verhalten und asynchrone E/A. Schauen Sie sich das example
an, um ein vollständiges End-to-End-Beispiel zu sehen:
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 ();
}
}
Ein alternativer Ansatz zur Bereitstellung von Variablen wäre die Verwendung eines Map-Objekts wie:
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 ();
}