Moustache.java n'est pas conçu pour permettre à des parties non fiables de fournir des modèles. Il peut être possible de le verrouiller pour fournir cela en toute sécurité, mais par défaut, il est DANGEREUX. Utilisez SafeMustacheFactory et ajoutez tous les modèles et partiels à la liste blanche.
Depuis la version 0.9.0, moustache.java est désormais uniquement Java 8. Pour la prise en charge de Java 6/7, utilisez 0.8.x.
Il n'y a pas de dépendances externes et la bibliothèque du compilateur fait environ 100 000 $.
Moustache.java est un dérivé de moustache.js.
Il existe un groupe Google pour l'assistance et les questions : http://groups.google.com/group/mustachejava
Github CI : https://github.com/spullara/mustache.java/actions/workflows/maven.yml
Documentation API : http://spullara.github.io/mustache/apidocs/
Le plus grand déploiement de production de Moustache.java :
Merci à YourKit pour de nombreuses améliorations de performances :
YourKit soutient aimablement le projet open source moustache.java avec son profileur Java complet. YourKit, LLC est le créateur d'outils innovants et intelligents pour le profilage des applications Java et .NET. Jetez un œil aux principaux produits logiciels de YourKit :
Demande de contributions :
Documentation:
mustache
modulo les différences d'espacesIterable
peut être utilisé pour des comportements de type listeCallable
permet une évaluation simultanée si un ExecutorService
est configuré{{<super}}{{$content}}...{{/content}}{{/super}}
){{#func1}}...{{/func1}}
) sont implémentées à l'aide de Function
de Java 8 (post-substitution)TemplateFunction
si vous souhaitez que moustache.java analyse les résultats de votre fonction/lambda (pré-substitution)handlebar
restituera les modèles + les données JSON pour des maquettes rapides de modèles par les concepteursCapturingMustacheVisitor
pour des simulations et des tests.invert
peut prendre du texte et un modèle et résoudre les donnéesPerformance:
com.github.mustachejavabenchmarks
dans le module compiler
indy
utilise le module codegen et invoquerdynamic pour compiler les modèles en bytecodeSuggestions de création :
Informations sur les dépendances Maven (c'est-à-dire que pour les cas les plus courants, vous aurez juste besoin du module compiler
) :
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 >
Exemple de fichier modèle :
{{#items}}
Name: {{name}}
Price: {{price}}
{{#features}}
Feature: {{description}}
{{/features}}
{{/items}}
Peut être alimenté par un code de support :
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 ;
}
}
Et cela donnerait :
Name: Item 1
Price: $19.99
Feature: New!
Feature: Awesome!
Name: Item 2
Price: $29.99
Feature: Old.
Feature: Ugly.
L'évaluation du modèle se déroule en série. Par exemple, si vous avez du code bloquant dans l'un de vos rappels, le système fera une pause lors de leur exécution :
static class Feature {
Feature ( String description ) {
this . description = description ;
}
String description () throws InterruptedException {
Thread . sleep ( 1000 );
return description ;
}
}
Si vous modifiez la description pour renvoyer un Callable
à la place, elle sera automatiquement exécutée dans un thread séparé si vous avez fourni un ExecutorService
lors de la création de votre MustacheFactory
.
Callable < String > description () throws InterruptedException {
return new Callable < String >() {
@ Override
public String call () throws Exception {
Thread . sleep ( 1000 );
return description ;
}
};
}
Cela permet les tâches planifiées, le comportement de streaming et les E/S asynchrones. Consultez le module example
afin de voir un exemple complet de bout en bout :
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 ();
}
}
Une approche alternative pour fournir des variables consisterait à utiliser un objet Map, comme :
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 ();
}