
Типобезопасный движок шаблонов Java Mustache с проверкой шаблонов во время компиляции, статической привязкой значений и расширяемым экранированием для HTML и других типов контента.
Типобезопасный шаблонизатор Java Mustache.
Шаблоны компилируются в читаемый Java-исходный код, а привязки значений проверяются статически.
Документация также доступна на javadoc.io, но там она не агрегирована, как указано выше.
Агрегированная javadoc-документация является предпочтительной, а остальная часть этого readme
предназначена в основном для пропаганды маркетинга.
Для предыдущих релизов:
https://jstach.io/doc/jstachio/VERSION/apidocs
Где VERSION — нужная вам версия.
Рассмотрено в why_jstachio_is_better.md.
Синтаксис Mustache (v 1.3) без логики.
Получите поддержку, подобную JEP 430, уже сегодня, но с ещё большими возможностями.
Шаблоны компилируются в Java-код
Привязки значений проверяются статически.
В шаблонах можно ссылаться на методы, поля и getter-методы.
Понятные сообщения об ошибках с контекстом.
Нулевая конфигурация. Никаких плагинов или настроек не требуется. Всё делается стандартным javac в любой IDE и/или сборочной системе.
Поддерживаются не-HTML шаблоны. Набор поддерживаемых типов контента с экранированием расширяем.
Макеты поддерживаются через спецификацию наследования Mustache.
Точка расширения запасного сервиса рендеринга через ServiceLoader
Настройка допустимых типов, которые можно выводить; иначе — ошибка компилятора (чтобы избежать toString у классов, у которых нет дружелюбного toString).
Форматтер для кастомного toString переменных во время выполнения
Добавление дополнительных implements интерфейсов к сгенерированному коду для своего рода трейтов-дополнений (@JStacheInterfaces)
Мощная поддержка лямбд
Поддержка Map<String, ?>
Поддержка Optional<?>
Совместимость с расширениями индексов списков JMustache и Handlebars (например, -first, -last, -index)
Это безусловно самый быстрый Java-шаблонизатор, подобный Mustache, а также один из самых быстрых в целом.
Ноль зависимостей, кроме самого JStachio
Доступен вариант с абсолютно нулевыми зависимостями во время выполнения (весь необходимый код генерируется, и даже jstachio не нужен во время выполнения). Нет необходимости использовать Maven shade для процессоров аннотаций и других проектов с нулевыми зависимостями. Также полезно для нативных проектов Graal VM, чтобы максимально минимизировать занимаемое место.
Поддержка Spring Framework высшего уровня (то есть сам проект предоставляет плагины, в отличие от вспомогательного проекта)
Быть самым быстрым Java-шаблонизатором не является целью этого проекта!
(однако на момент последнего обновления этого readme это самый быстрый из известных мне)
Не то чтобы производительность имела большое значение для языков шаблонов (редко бывает узким местом), но JStachio очень быстрый:
https://github.com/agentgt/template-benchmark


@JStache(template = """
{{#people}}
{{message}} {{name}}! You are {{#ageInfo}}{{age}}{{/ageInfo}} years old!
{{#-last}}
That is all for now!
{{/-last}}
{{/people}}
""")
public record HelloWorld(String message, List<Person> people) implements AgeLambdaSupport {
}
public record Person(String name, LocalDate birthday) {
}
public record AgeInfo(long age, String date) {
}
public interface AgeLambdaSupport {
@JStacheLambda
default AgeInfo ageInfo(Person person) {
long age = ChronoUnit.YEARS.between(person.birthday(), LocalDate.now());
String date = person.birthday().format(DateTimeFormatter.ISO_DATE);
return new AgeInfo(age, date);
}
}
@Test
public void testPerson() throws Exception {
Person rick = new Person("Rick", LocalDate.now().minusYears(70));
Person morty = new Person("Morty", LocalDate.now().minusYears(14));
Person beth = new Person("Beth", LocalDate.now().minusYears(35));
Person jerry = new Person("Jerry", LocalDate.now().minusYears(35));
String actual = JStachio.render(new HelloWorld("Hello alien", List.of(rick, morty, beth, jerry)));
String expected = """
Hello alien Rick! You are 70 years old!
Hello alien Morty! You are 14 years old!
Hello alien Beth! You are 35 years old!
Hello alien Jerry! You are 35 years old!
That is all for now!
""";
assertEquals(expected, actual);
}
<properties>
<io.jstach.version>0.6.0-SNAPSHOT</io.jstach.version>
</properties>
...
<dependencies>
<dependency>
<groupId>io.jstach</groupId>
<artifactId>jstachio</artifactId>
<version>${io.jstach.version}</version>
</dependency>
</dependencies>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>17</source> <!-- 17 is the minimum -->
<target>17</target> <!-- 17 is the minimum -->
<annotationProcessorPaths>
<path>
<groupId>io.jstach</groupId>
<artifactId>jstachio-apt</artifactId>
<version>${io.jstach.version}</version>
</path>
<!-- other annotation processors -->
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
Прим.: jar с аннотациями (jstachio-annotation) подтягивается транзитивно
dependencies {
implementation 'io.jstach:jstachio:VERSION'
annotationProcessor 'io.jstach:jstachio-apt:VERSION'
}
{{#name}}
<p>Name: {{.}}, Name Length is {{length}}</p>
{{/name}}
<p>Age: {{ age }}</p>
<p>Achievements:</p>
<ul>
{{#array}}
<li>{{.}}</li>
{{/array}}
</ul>
{{^array}}
<p>No achievements</p>
{{/array}}
<p>Items:</p>
<ol>
{{#list1}}
<li>{{value}}</li>
{{/list1}}
</ol>