Einführung in Moustache

1. Übersicht

In diesem Artikel konzentrieren wir uns auf Moustache-Vorlagen und verwenden eine der Java-APIs zum Erstellen dynamischer HTML-Inhalte.

Moustache ist eine logiklose Vorlagen-Engine zum Erstellen dynamischer Inhalte wie HTML und Konfigurationsdateien.

2. Einführung

Einfach ausgedrückt wird die Engine als logiklos klassifiziert, da sie keine Konstrukte enthält, die if-else-Anweisungen und for-Schleifen unterstützen.

Die Moustache-Vorlagen bestehen aus Tag-Namen, die von {{}} umgeben sind (die Schnurrbärten ähneln - daher der Name) und von einem Modellobjekt unterstützt werden, das die Daten für die Vorlage enthält.

3. Maven-Abhängigkeit

Das Kompilieren und Ausführen der Vorlagen wird von mehreren Sprachen unterstützt - sowohl clientseitig als auch serverseitig.

Um die Vorlagen aus Java verarbeiten zu können, verwenden wir die Java-Bibliothek, die als Maven-Abhängigkeit hinzugefügt werden kann.

Java 8+:

 com.github.spullara.mustache.java compiler 0.9.4 

Java 6/7:

 com.github.spullara.mustache.java compiler 0.8.18 

Wir können die neuesten Versionen der Bibliothek im Central Maven Repository überprüfen.

4. Verwendung

Schauen wir uns ein einfaches Szenario an, das zeigt, wie man:

  1. Schreiben Sie eine einfache Vorlage
  2. Kompilieren Sie die Vorlage mit der Java-API
  3. Führen Sie es aus, indem Sie die erforderlichen Daten bereitstellen

4.1. Eine einfache Schnurrbartvorlage

Wir werden eine einfache Vorlage zum Anzeigen der Details einer Aufgabenaufgabe erstellen:

{{title}}

Created on {{createdOn}}

{{text}}

In der obigen Vorlage können die Felder in den geschweiften Klammern ({{}}) sein:

  • Methoden und Eigenschaften einer Java-Klasse
  • Schlüssel eines Map- Objekts

4.2. Kompilieren der Schnurrbartvorlage

Wir können die Vorlage wie folgt kompilieren:

MustacheFactory mf = new DefaultMustacheFactory(); Mustache m = mf.compile("todo.mustache"); 

MoustacheFactory sucht im Klassenpfad nach der angegebenen Vorlage. In unserem Beispiel platzieren wir todo.mustache unter src / main / resources .

4.3. Ausführen der Moustache-Vorlage

Die für die Vorlage bereitgestellten Daten sind eine Instanz der Todo- Klasse. Die Definition lautet:

public class Todo { private String title; private String text; private boolean done; private Date createdOn; private Date completedOn; // constructors, getters and setters }

Die kompilierte Vorlage kann ausgeführt werden, um HTML wie folgt zu erhalten:

Todo todo = new Todo("Todo 1", "Description"); StringWriter writer = new StringWriter(); m.execute(writer, todo).flush(); String html = writer.toString();

5. Schnurrbartabschnitte und Iterationen

Schauen wir uns nun an, wie die Aufgaben aufgelistet werden. Zum Durchlaufen von Listendaten verwenden wir Schnurrbartabschnitte.

Ein Abschnitt ist ein Codeblock, der je nach Wert des Schlüssels im aktuellen Kontext ein- oder mehrmals wiederholt wird.

Es sieht ungefähr so ​​aus:

{{#todo}}  {{/todo}}

Ein Abschnitt beginnt mit einem Pfund (#) und endet mit einem Schrägstrich (/), wobei auf jedes der Zeichen der Schlüssel folgt, dessen Wert als Grundlage für das Rendern des Abschnitts verwendet wird.

Im Folgenden sind die Szenarien aufgeführt, die je nach Wert des Schlüssels auftreten können:

5.1. Abschnitt mit nicht leerer Liste oder nicht falschem Wert

Erstellen wir eine Vorlage todo-section.mustache, die einen Abschnitt verwendet:

{{#todo}} 

{{title}}

Created on {{createdOn}}

{{text}}

{{/todo}}

Schauen wir uns diese Vorlage in Aktion an:

@Test public void givenTodoObject_whenGetHtml_thenSuccess() throws IOException { Todo todo = new Todo("Todo 1", "Todo description"); Mustache m = MustacheUtil.getMustacheFactory() .compile("todo.mustache"); Map context = new HashMap(); context.put("todo", todo); String expected = "

Todo 1

"; assertThat(executeTemplate(m, todo)).contains(expected); }

Erstellen wir eine weitere Vorlage todos.mustache zum Auflisten der Aufgaben :

{{#todos}} 

{{title}}

{{/todos}}

Und erstellen Sie damit eine Liste von Aufgaben:

@Test public void givenTodoList_whenGetHtml_thenSuccess() throws IOException { Mustache m = MustacheUtil.getMustacheFactory() .compile("todos.mustache"); List todos = Arrays.asList( new Todo("Todo 1", "Todo description"), new Todo("Todo 2", "Todo description another"), new Todo("Todo 3", "Todo description another") ); Map context = new HashMap(); context.put("todos", todos); assertThat(executeTemplate(m, context)) .contains("

Todo 1

") .contains("

Todo 2

") .contains("

Todo 3

"); }

5.2. Abschnitt mit leerer Liste oder falsch oder Null Wert

Testen wir die todo-section.mustache mit einem Nullwert :

@Test public void givenNullTodoObject_whenGetHtml_thenEmptyHtml() throws IOException { Mustache m = MustacheUtil.getMustacheFactory() .compile("todo-section.mustache"); Map context = new HashMap(); assertThat(executeTemplate(m, context)).isEmpty(); }

And likewise, test todos.mustache with an empty list:

@Test public void givenEmptyList_whenGetHtml_thenEmptyHtml() throws IOException { Mustache m = MustacheUtil.getMustacheFactory() .compile("todos.mustache"); Map context = new HashMap(); assertThat(executeTemplate(m, context)).isEmpty();; }

6. Inverted Sections

Inverted sections are those which are rendered only once based on the non-existence of the key or false or null value or an empty list. In other words, these are rendered when a section is not rendered.

These start with a caret (^) and end with a slash (/) as shown below:

{{#todos}} 

{{title}}

{{/todos}} {{^todos}}

No todos!

{{/todos}}

The above template when provided with an empty list:

@Test public void givenEmptyList_whenGetHtmlUsingInvertedSection_thenHtml() throws IOException { Mustache m = MustacheUtil.getMustacheFactory() .compile("todos-inverted-section.mustache"); Map context = new HashMap(); assertThat(executeTemplate(m, context).trim()) .isEqualTo("

No todos!

"); }

7. Lambdas

The values for keys of a mustache section can be a function or a lambda expression. In such case, the complete lambda expression is invoked by passing in the text within the section as a parameter to the lambda expression.

Let's look at a template todos-lambda.mustache:

{{#todos}} 

{{title}}{{#handleDone}}{{doneSince}}{{/handleDone}}

{{/todos}}

Der handleDone- Schlüssel wird wie folgt in einen Java 8-Lambda-Ausdruck aufgelöst:

public Function handleDone() { return (obj) -> done ? String.format("Done %s minutes ago", obj) : ""; }

Der durch Ausführen der obigen Vorlage generierte HTML-Code lautet:

Todo 1

Todo 2

Todo 3Done 5 minutes ago

8. Fazit

In diesem Einführungsartikel haben wir uns mit dem Erstellen von Schnurrbartvorlagen mit Abschnitten, invertierten Abschnitten und Lambdas befasst. Und wir haben die Java-API verwendet, um die Vorlagen zu kompilieren und auszuführen, indem wir relevante Daten bereitgestellt haben.

Es gibt einige erweiterte Funktionen von Moustache, die es wert sind, erkundet zu werden - wie zum Beispiel:

  • Bereitstellen eines aufrufbaren Werts als Wert, der zu einer gleichzeitigen Auswertung führt
  • Verwenden von DecoratedCollection , um den ersten, letzten und Index der Sammlungselemente abzurufen
  • Invert- API, die die Daten mit dem Text und der Vorlage angibt

Und wie immer ist der vollständige Quellcode dafür auf Github verfügbar.