GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — GitHub - JavaMuller/mustache.java: Implementation of mustache.js for Java

BranchesTags
Open more actions menu
 
 

Latest commit

 

History

1,127 Commits
1,127 Commits

Folders and files

NameName
Last commit message
Last commit date
benchmarks
benchmarks
 
 
compiler
compiler
 
 
example
example
 
 
handlebar
handlebar
 
 
javascript
javascript
 
 
mustache-maven-plugin
mustache-maven-plugin
 
 
scala-extensions
scala-extensions
 
 
site
site
 
 
src/test/resources
src/test/resources
 
 
.gitignore
.gitignore
 
 
.gitmodules
.gitmodules
 
 
.travis.yml
.travis.yml
 
 
LICENSE
LICENSE
 
 
README.md
README.md
 
 
circle.yml
circle.yml
 
 
nodetest.js
nodetest.js
 
 
pom.xml
pom.xml
 
 

Repository files navigation

Mustache.java Build Status

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 95k.

Mustache.java is a derivative of mustache.js.

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

Travis CI: https://travis-ci.org/spullara/mustache.java

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 profiling Java and .NET applications. Take a look at YourKit's leading software products:

  • YourKit Java Profiler
  • YourKit .NET Profiler

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 the mustache specification 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
  • Any Iterable can be used for list-like behaviors
  • Returning a Callable allows for concurrent evaluation if an ExecutorService is configured
  • Template inheritance is supported by this implementation, see mustache/spec#38 (eg. {{<super}}{{$content}}...{{/content}}{{/super}})
  • Additional functions/lambdas (eg. {{#func1}}...{{/func1}}) are implemented using Function from Java 8 (post-substitution)
  • Use TemplateFunction 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.
  • The handlebar 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 the CapturingMustacheVisitor for mocks and tests
  • The DecoratedCollection can provide first / last / index for elements in a collection
  • The invert call can take text and a template and solve for the data

Performance:

  • See the com.github.mustachejavabenchmarks package in the compiler 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
  • The indy 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:
    • git clone https://github.com/spullara/mustache.java.git
    • set your JAVA_HOME to a JDK 8 JDK
    • mvn -DskipTests clean install
  • If you must build and test but not benchmark:
    • CI=1 mvn clean install
  • If you must build, test and benchmark:
    • mvn clean install

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

Java 8+:

<dependency>
  <groupId>com.github.spullara.mustache.java</groupId>
  <artifactId>compiler</artifactId>
  <version>0.9.1</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:

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;
  }
}

And would result in:

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

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

static class Feature {
  Feature(String description) {
    this.description = description;
  }

  String description() throws InterruptedException {
    Thread.sleep(1000);
    return description;
  }
}

If you change description to return a Callable instead it will automatically be executed in a separate thread if you have provided an ExecutorService when you created your MustacheFactory.

Callable<String> description() throws InterruptedException {
  return new Callable<String>() {

    @Override
    public String call() throws Exception {
      Thread.sleep(1000);
      return description;
    }
  };
}

This enables scheduled tasks, streaming behavior and asynchronous i/o. Check out the example module in order to see a complete end-to-end 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();
  }
}

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

  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();
  }

About

Implementation of mustache.js for Java

www.javarants.com/2010/05/03/the-ideal-web-application-templating-system/

Resources

Readme
License
Activity
Custom properties

Stars

0 stars

Watchers

0 watching

Forks

0 forks
Report repository

Releases

Packages

Contributors

Languages

You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.