Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Implementation of mustache.js for Java

License

NotificationsYou must be signed in to change notification settings

spullara/mustache.java

Repository files navigation

Mustache.java is not designed to allow untrusted parties to provide templates. It may be possible to lock it down to provide that safely,but by default it is UNSAFE. Use the SafeMustacheFactory and whitelist all templates and partials.

As of release 0.9.0 mustache.java is now Java 8 only. For Java 6/7 support use 0.8.x.

There are no external dependencies and the compiler library is ~100k.

Mustache.java is a derivative ofmustache.js.

There is a Google Group for support and questions:http://groups.google.com/group/mustachejava

Github CI:https://github.com/spullara/mustache.java/actions/workflows/maven.yml

API documentation:http://spullara.github.io/mustache/apidocs/

Largest production deployment of Mustache.java:

  • Twitter (the web site, email, syndicated widgets, etc)

Thanks to YourKit for many performance improvements:

YourKit is kindly supporting the mustache.java open source project with its full-featured Java Profiler.YourKit, LLC is the creator of innovative and intelligent tools for profilingJava and .NET applications. Take a look at YourKit's leading software products:

Request for contributions:

  • Real world benchmarks that matter - currently benchmarking based on Twitter templates
  • Documentation
  • Bug reports / fixes
  • API feedback
  • Optimizations

Documentation:

  • Javadocs
  • Mustache.js manual
  • Passes all of themustachespecification tests modulo whitespace differences
  • Biggest difference between mustache.js and mustache.java is optional concurrent evaluation
  • Data is provided by objects in an array of scopes and are accessed via non-private fields, methods or maps
  • AnyIterable can be used for list-like behaviors
  • Returning aCallable allows for concurrent evaluation if anExecutorService is configured
  • Template inheritance is supported by this implementation, seemustache/spec#38 (eg.{{<super}}{{$content}}...{{/content}}{{/super}})
  • Additional functions/lambdas (eg.{{#func1}}...{{/func1}}) are implemented usingFunction from Java 8 (post-substitution)
  • UseTemplateFunction if you want mustache.java to reparse the results of your function/lambda (pre-substitution)
  • Both default and manually configured classpath based and file system based template roots are supported
  • A compiled and invokedynamic version is available. Performance improvements are often application specific.
  • Thehandlebar server will render templates + json data for quick mockups of templates by designers
  • Completely pluggable system for overriding almost all the behavior in the compilation and rendering process
  • You can pull out sample data from live systems using theCapturingMustacheVisitor for mocks and tests
  • The DecoratedCollection can provide first / last / index for elements in a collection
  • Theinvert call can take text and a template and solve for the data

Performance:

  • See thecom.github.mustachejavabenchmarks package in thecompiler module
  • Compiles 4000+ timeline.html templates per second per core
  • Renders 3000+ of 50 tweet timelines per second per core on 2011 Macbook Pro / MacPro hardware
  • New codegen module generates code for guards and mustaches
  • Theindy module uses the codegen module and invokedynamic to compile templates down to bytecode

Build suggestions:

  • Don't build, use Maven dependencies
  • If you must build but not test:
  • If you must build and test but not benchmark:
    • CI=1 mvn clean install -pl :compiler -am
  • If you must build, test and benchmark:
    • mvn clean install

Maven dependency information (ie. for most common cases you will just need thecompiler module):

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>

Example template file:

{{#items}}Name: {{name}}Price: {{price}}  {{#features}}  Feature: {{description}}  {{/features}}{{/items}}

Might be powered by some backing code:

publicclassContext {List<Item>items() {returnArrays.asList(newItem("Item 1","$19.99",Arrays.asList(newFeature("New!"),newFeature("Awesome!"))),newItem("Item 2","$29.99",Arrays.asList(newFeature("Old."),newFeature("Ugly.")))    );  }staticclassItem {Item(Stringname,Stringprice,List<Feature>features) {this.name =name;this.price =price;this.features =features;    }Stringname,price;List<Feature>features;  }staticclassFeature {Feature(Stringdescription) {this.description =description;    }Stringdescription;  }}

And would result in:

Name: Item 1Price: $19.99  Feature: New!  Feature: Awesome!Name: Item 2Price: $29.99  Feature: Old.  Feature: Ugly.

Evaluation of the template proceeds serially. For instance, if you have blocking code within one of your callbacks,the system will pause while executing them:

staticclassFeature {Feature(Stringdescription) {this.description =description;  }Stringdescription()throwsInterruptedException {Thread.sleep(1000);returndescription;  }}

If you change description to return aCallable instead it will automatically be executed in a separatethread if you have provided anExecutorService when you created yourMustacheFactory.

Callable<String>description()throwsInterruptedException {returnnewCallable<String>() {@OverridepublicStringcall()throwsException {Thread.sleep(1000);returndescription;    }  };}

This enables scheduled tasks, streaming behavior and asynchronous i/o. Check out theexample module in orderto see a complete end-to-end example:

packagemustachejava;importcom.github.mustachejava.DefaultMustacheFactory;importcom.github.mustachejava.Mustache;importcom.github.mustachejava.MustacheFactory;importjava.io.IOException;importjava.io.PrintWriter;importjava.io.Writer;importjava.util.Arrays;importjava.util.List;publicclassExample {List<Item>items() {returnArrays.asList(newItem("Item 1","$19.99",Arrays.asList(newFeature("New!"),newFeature("Awesome!"))),newItem("Item 2","$29.99",Arrays.asList(newFeature("Old."),newFeature("Ugly.")))    );  }staticclassItem {Item(Stringname,Stringprice,List<Feature>features) {this.name =name;this.price =price;this.features =features;    }Stringname,price;List<Feature>features;  }staticclassFeature {Feature(Stringdescription) {this.description =description;    }Stringdescription;  }publicstaticvoidmain(String[]args)throwsIOException {MustacheFactorymf =newDefaultMustacheFactory();Mustachemustache =mf.compile("template.mustache");mustache.execute(newPrintWriter(System.out),newExample()).flush();  }}

An alternative approach for providing variables would be to use a Map object, like:

publicstaticvoidmain(String[]args)throwsIOException {HashMap<String,Object>scopes =newHashMap<String,Object>();scopes.put("name","Mustache");scopes.put("feature",newFeature("Perfect!"));Writerwriter =newOutputStreamWriter(System.out);MustacheFactorymf =newDefaultMustacheFactory();Mustachemustache =mf.compile(newStringReader("{{name}}, {{feature.description}}!"),"example");mustache.execute(writer,scopes);writer.flush();  }

License

FOSSA Status

About

Implementation of mustache.js for Java

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors54


[8]ページ先頭

©2009-2026 Movatter.jp