Rocker-это оптимизированный Java 8+, около нулевого рендеринга, быстрый шаблонный двигатель, который производит статически напечатанные шаблоны объектов Java, которые собираются вместе с остальной частью вашего проекта. Нет больше «разминки» времени в производстве, логики на основе медленных размышлений или неприятных сюрпризов, которые должны были быть пойманы во время разработки.
Напишите свои шаблоны, используя интуитивно понятный синтаксис без тегов со стандартными выражениями Java для логики, итерации и значений. Используйте Special's Rocker ?
Оператор присутствия для нулевой оценки. Вся тяжелая работа осуществляется рецевым анализатором во время разработки, что поднимает зависимости времени выполнения до нескольких классов. Rocker будет проанализировать ваши шаблоны и генерировать хорошо документированные исходные файлы Java (чтобы вы могли легко осмотреть и понять, как это работает).
Включает следующие функции:
?
Оператор присутствия расширяет синтаксис для упрощенной обработки нулевых значений.Проект Fizzed, Inc. (Следуйте в Twitter: @fizzed_inc)
Разработка и поддержание проектов OpenSource требует значительного времени. Если вы найдете этот проект полезным или нуждающейся в коммерческой поддержке, мы хотели бы пообщаться. Бросить нам электронное письмо по адресу [email protected]
Спонсоры проекта могут включать следующие преимущества:
Основываясь на следующем эталонном эталоне, Рокер является явным победителем. ~ 250% быстрее, чем Freemarker, в то же время требуя отказа от майки меньше памяти.
Большинство шаблонов используются для веб -сайтов, поэтому вот быстрый образец, показывающий, как работают шаблоны рокеров и могут звонить друг другу в процессе рендеринга. Создайте шаблон, содержащий общий заголовок и нижний колонтитул, а также заполнитель для содержания тела. Создать шаблон src/main/java/views/main.rocker.html
@args (String title, RockerBody content)
< html >
< head >
< title > @title </ title >
</ head >
< body >
@content
</ body >
</ html >
Шаблон, который мы на самом деле планируем показать пользователю, предоставит свой контент в контексте нижнего колонтитула общего/заголовка. С точки зрения Java, он передает блок рендеринга, который будет выполняться в другом шаблоне. Создать шаблон src/main/java/views/index.rocker.html
@args (String message)
@views.main.template("Home") - > {
< h1 > Hello @message! </ h1 >
}
Эй, как насчет аргумента RockerBody content
? Мы освещаем его более подробно в синтаксисе Readme, но сейчас просто понимаем, что это единственный особый тип аргумента и инструктирует рокер, который шаблон ожидает, что «тело» будет передано в него.
Парсер рокера будет генерировать исходный файл Java для каждого шаблона. Они будут target/generated-sources/rocker/views/main.java
и target/generated-sources/rocker/views/index.java
. В вашем приложении вы можете отображать шаблон индекса так.
static public void main ( String [] args ) {
String output = views . index . template ( "World" )
. render ()
. toString ();
}
Выход равен:
< html >
< head >
< title > Home </ title >
</ head >
< body >
< h1 > Hello World! </ h1 >
</ body >
</ html >
После того, как вы генерируете источники Java и загляните в код, легко увидеть, как это работает. Класс @content
Синтаксис идентичен тому, как Lambda определяется в Java 8 (реализовано с Lambdas для Java 8 и анонимных внутренних классов для Java 6/7). Rocker делает несколько вещей за кулисами, чтобы убедиться, что шаблоны, которые создают другие шаблоны, имеют один и тот же контекст рендеринга (выходной буфер, контекст-специфичный для приложения/неявное состояние).
Проверьте файл syntax.md для полного глубокого погружения на синтаксис рокера.
Рокер имеет растущий список рамок, с которыми он был легко интегрирован. Если вы хотите ссылаться на добавленную новую структуру, пожалуйста, подайте проблему или отправьте PR:
Статический (простой текст) для каждого шаблона рокера (по умолчанию) хранится внутренне как статические байтовые массивы, уже преобразованные в ваш целевой Charset (например, UTF-8). Когда шаблон отображается - статические байтовые массивы повторно используются по всем запросам. Рокер отображает оптимизированный выходной поток, который хранит составной (связанный список) представление об повторно используемых байтовых массивах плюс ваш динамический содержимое. Поскольку шаблоны состоят в основном из статического контента, переведенного в один и тот же Charset снова и снова, а не выделять новую память, копирование этого контента, а затем преобразование в целевой Charset для каждого запроса - рокер просто использует указатель на него снова и снова снова. Этот метод создает быстрые и эффективные память.
Допустим, у вас есть шаблон, состоящий из 9000 байтов простого статического текста и 1000 байтов динамического содержания. Без этой оптимизации потребовалось бы ~ 100 МБ памяти для обслуживания 10000 запросов (10000 байтов x 10000 запросов). При этой оптимизации потребуется ~ 10 МБ памяти для обслуживания 10000 запросов (1000 байтов x 10000 запросов). Помимо более низкой памяти, вы также вырезаете 90 МБ копий памяти и 90 МБ строк UTF-8 String-> BYTE. Довольно полезная оптимизация.
Все составлено компилятором вашего проекта вместе с другим вашим исходным кодом Java. Любой динамический код в вашем шаблоне в конечном итоге преобразуется в стандартную Java и составлен. Не используется отражение.
Версия 0.10.0 Введена поддержка шаблонов горячих перезагрузков во время разработки. Горячая перезагрузка позволяет изменить исходный код шаблона, сохранить его и иметь изменения в следующем запросе - без необходимости перезагрузить JVM. Рокер предлагает два разных вкуса горячей перезагрузки для гибкости.
Основная особенность шаблонов рокеров заключается в том, что ваши шаблоны проверяются на время компиляции на предмет использования, аргументов, логики и т. Д. Компилятором Java.
В версии 0.10.0 основная структура шаблона была изменена там, где шаблон генерирует два базовых класса. Каждый шаблон генерирует класс модели (его интерфейс) и класс реализации (его рендеринг). Ваше приложение будет взаимодействовать только непосредственно с моделью, что позволит рокеру динамически перекомпилировать и перезагрузить класс реализации.
Основным преимуществом Flavor One является то, что ваш код приложения остается прежним и проверяется временем компиляции Java Compiler, в то время как содержание шаблона может быть изменено и автоматически перезагружено во время выполнения. Только в случае, когда вы фактически измените аргументы шаблона, вам нужно будет перезапустить ваше приложение.
Если вы предпочитаете удобство полностью динамических шаблонов, аромат двух поддерживает горячую перезагрузку как класса модели шаблона (его интерфейс), так и класс реализации (его рендеринг). Ваше приложение потеряет некоторую проверку времени компиляции и небольшой удар производительности, но получите удобство всего, что можно перезарядть. То, как ваше приложение будет использовать шаблоны, также отличается.
import com . fizzed . rocker . Rocker
...
// dynamic interfaces, dynamic implementation
String rendered = Rocker . template ( "views/index.rocker.html" )
. bind ( "val" , "ValueA" )
. render ()
. toString ();
Путь и аргументы шаблона будут проверены во время выполнения. Обратите внимание, что каждое привязываемое значение должно соответствовать имени и типу, объявленным в вашем шаблоне.
В случае, если ваша привязываемая карта может содержать больше значений, чем необходимые для расслабленной связки. Расслабленная альтернатива не пройдет рендеринг, если атрибут является дополнительным для требуемого списка. Например:
@args (String name)
Hello ${name}!
Будет отображаться в расслабленном режиме как:
Map map = new HashMap ();
map . put ( "name" , "Joe" );
map . put ( "age" , 42 );
Rocker . template ( "views/hello.rocker.html" )
. relaxedBind ( map )
. render ();
// -> Hello Joe!
Поддержка горячей перезагрузки добавляется в ваши сгенерированные шаблоны по умолчанию в версии 0.10.0. Если вы хотите отключить поддержку, установите конфигурацию/системную свойство rocker.optimize
на True во время вашей сборки. Поскольку код присутствует в ваших шаблонах по умолчанию, вам просто нужно включить его во время выполнения.
Зависимость rocker-compiler
должна быть добавлена в вашу сборку. Эта зависимость должна присутствовать только во время разработки и может быть удалена в производстве. В Maven это означает, что вы захотите добавить зависимость в provided
области.
< dependency >
< groupId >com.fizzed</ groupId >
< artifactId >rocker-compiler</ artifactId >
< version >2.1.0</ version >
< scope >provided</ scope >
</ dependency >
Активируйте горячую перезагрузку во время выполнения. Вы можете активировать горячую перезагрузку либо системным свойством, либо программно. Для активации горячей перезагрузки с помощью системы в Maven.
mvn -Drocker.reloading=true ...rest of args...
В качестве альтернативы вы можете активировать горячую перезагрузку программно.
import com . fizzed . rocker . runtime . RockerRuntime
...
RockerRuntime . getInstance (). setReloading ( true );
Существует простой пример, демонстрирующий горячую перезагрузку в действии. Этот проект использует Blaze, чтобы помочь задачам сценариев. Запустить следующее
java -jar blaze.jar hot_reload
Укажите свой браузер на http: // localhost: 8080
Затем измените и сохраните rocker-test-reload/src/test/java/views/index.rocker.html
и обновите свой браузер.
Рокер состоит из двух компонентов - анализатора/генератора и времени выполнения. Чтобы использовать Rocker в вашем проекте, добавьте зависимость во время выполнения в ваше приложение, а затем включите анализатор в вашем инструменте сборки, а затем создать первый шаблон.
Рокер опубликован в Maven Central. Добавить в качестве зависимости в Maven:
< dependency >
< groupId >com.fizzed</ groupId >
< artifactId >rocker-runtime</ artifactId >
< version >2.1.0</ version >
</ dependency >
<!-- for hot-reloading support only during development -->
< dependency >
< groupId >com.fizzed</ groupId >
< artifactId >rocker-compiler</ artifactId >
< version >2.1.0</ version >
< scope >provided</ scope >
</ dependency >
Добавить в качестве зависимости в Градле:
repositories {
mavenCentral()
}
dependencies {
compile group : ' com.fizzed ' , name : ' rocker-runtime ' , version : ' 2.1.0 '
// add rocker-compiler dependency as needed
}
Рокер поддерживает Maven и Gradle из коробки.
Добавьте следующее в свой POM
< build >
< plugins >
< plugin >
< groupId >com.fizzed</ groupId >
< artifactId >rocker-maven-plugin</ artifactId >
< version >2.1.0</ version >
< executions >
< execution >
< id >generate-rocker-templates</ id >
< phase >generate-sources</ phase >
< goals >
< goal >generate</ goal >
</ goals >
</ execution >
</ executions >
</ plugin >
</ plugins >
</ build >
По умолчанию Rocker будет рекурсивно обрабатывать любые файлы шаблонов, заканчивающиеся .rocker.html
в src/main/java
. Справочник, который сохранен шаблон, станет стандартным пакетом Java, в который будут представлены сгенерированные классы Java. Сгенерированные исходные файлы Java будут сохранены в target/generated-sources/rocker
. Плагин позаботится о добавлении этого сгенерированного каталога в ваш корень источников.
Поддерживаются следующие свойства:
templateDirectory
- это базовый каталог, который рекурсивно начинается с файлов шаблонов расположения и анализа. package
Java A будет сгенерирован для использования этого каталога в качестве базы. Так что, если у вас есть ${templateDirectory}/views/mytemplate.rocker.html
, то Rocker генерирует ${outputDirectory}/views/mytemplate.java
. По умолчанию ${project.build.sourceDirectory}
.
outputDirectory
- это каталог, который анализатор будет генерировать источники для шаблонов. По умолчанию ${project.build.directory}/generated-sources/rocker
classDirectory
- это каталог, который функция Hot Reload будет (Re) компилировать классы во время выполнения. По умолчанию ${project.build.outputDirectory}
failOnError
определяет, приводит ли какие -либо ошибки анализа/генерирования провалиться. По умолчанию к истинному.
skip
определяет, следует ли пропустить выполнение плагина. По умолчанию ложно.
touchFile
- это файл, чтобы «прикоснуться» после успешного генерирования источников Java. Полезно для запуска других рабочих процессов. Многие IDE не будут автоматически перезагрузить сгенерированные источники для завершения кода, если ни явно не указан для перезагрузки, либо если файл Maven pom.xml не изменяется. Таким образом, это значение по умолчанию устанавливается на ${basedir}/pom.xml
. Обычно это безобидно, чтобы сохранить это.
skipTouch
отключает TouchFile. По умолчанию ложно.
addAsSources
добавит outputdirectory в Maven в качестве источников, которые должны быть скомпилированы. По умолчанию к истинному.
addAsTestSources
добавит выходную директорию в Maven в качестве скомпилированных источников тестирования. По умолчанию ложно. Если это правда, это оценивается перед добавками и эффективно говорит Maven компилировать ваши шаблоны в качестве тестового кода.
Следующие свойства также поддерживаются, но важно понимать, что это по сути переопределяется переоборудованием для анализатора, и все они по умолчанию со значением по умолчанию Рокера.
javaVersion
- это версия Java, которую вы хотели бы, чтобы ваши шаблоны компилируются и совместимы с время выполнения. По умолчанию в Java версию JVM выполняет Maven (например, 1,8 ").
optimize
определяет, будет ли поддержка горячей перезагрузки удалена из сгенерированных шаблонов. Ложь по умолчанию.
extendsClass
- это класс, который должен расширять все реализации шаблонов. Полезно для промежуточных классов, специфичных для приложений, которые вы хотели бы расширить все шаблоны. По умолчанию по умолчанию Рокер.
extendsModelClass
- это класс, который должны расширять все шаблонные модели. Полезно для промежуточных классов для конкретных приложений, которые вы хотели бы расширить все шаблоны. По умолчанию по умолчанию Рокер.
plainTextStrategy
- это стратегия, используемая для внедрения простого текста как часть шаблонов. По умолчанию static_byte_arrays_via_unloaded_class, но если вам нужна совместимость с GRAALVM, вы бы попробовали static_byte_arrays
discardLogicWhitespace
определяет, следует ли отбрасывать пробелы в шаблонах, которые определяются как часть логических/управляющих блоков. Помогает сделать визуализированный контент более профессиональным, при этом сохраняя большую часть вашего форматирования нетронутым. По умолчанию по умолчанию Рокер.
targetCharset
является целевым Charset для вывода шаблона. По умолчанию по умолчанию Рокер.
suffixRegex
- это регулярное выражение для поиска шаблонов для анализа. По умолчанию по умолчанию Рокер.
markAsGenerated
добавляет аннотацию @Generated в сгенерированные классы. Удержание является классом, так что аннотация может использоваться инструментами, которые полагаются только на файлы класса, а не на исходный код. По умолчанию по умолчанию Рокер.
Спасибо @victory
и @mnlipp
за вклад в плагин Gradle. @etiennestuder
также имел альтернативный плагин Gradle, который вы также захотите рассмотреть. Плагин Rocker's Gradle опубликован на gradle.org. Просто добавьте следующее в свой сценарий сборки:
plugins {
id " com.fizzed.rocker " version " 2.1.0 "
}
sourceSets {
main {
rocker {
srcDir( ' src/main/java ' )
}
}
}
rocker {
// (All settings are shown with their defaults)
//
// Skips building templates all together
skip false
// Base directory for generated java sources, actual target is sub directory
// with the name of the source set. The value is passed through project.file().
outputBaseDirectory = " $b uildDir /generated-src/rocker "
// Base directory for the directory where the hot reload feature
// will (re)compile classes to at runtime (and where `rocker-compiler.conf`
// is generated, which is used by RockerRuntime.getInstance().setReloading(true)).
// The actual target is a sub directory with the name of the source set.
// The value is passed through project.file().
classBaseDirectory = " $b uildDir /classes "
failOnError true
skipTouch true
// must not be empty when skipTouch is equal to false
touchFile " "
javaVersion ' 1.8 '
extendsClass null
extendsModelClass null
optimize null
discardLogicWhitespace null
targetCharset null
suffixRegex null
postProcessing null
markAsGenerated null
}
Синтаксис шаблона подробно описан ниже, но сейчас для создания нового файла в ${templateDirectory}/views/HelloWorld.rocker.html
@*
Example of hello world
*@
@args (String message)
Hello @message!
Время компилировать свой проект и начать использование шаблона. Вы можете назвать это из Java, как это:
static public void main ( String [] args ) {
String output = views . HelloWorld
. template ( "World" )
. render ()
. toString ();
}
Рокер сильно оптимизирован (по умолчанию) для выходных шаблонов в виде байтовых массивов. RockerOutput
по com.fizzed.rocker.runtime.ArrayOfByteArraysOutput
. Это отличный выбор для байтовых массивов или асинхронного io. Тем не менее, структура имеет возможность для оптимизированного рендеринга в строки (или другие пользовательские выходы).
Для эффективного представления в строке:
import com . fizzed . rocker . runtime . StringBuilderOutput ;
static public void main ( String [] args ) {
StringBuilderOutput output = views . HelloWorld
. template ( "World" )
. render ( StringBuilderOutput . FACTORY );
String text = output . toString ();
}
Для эффективного представления в выходное средство:
import com . fizzed . rocker . runtime . OutputStreamOutput ;
static public void main ( String [] args ) throws Exception {
final OutputStream os = new FileOutputStream ( new File ( "test" ));
OutputStreamOutput output = views . HelloWorld
. template ( "World" )
. render (( contentType , charsetName ) -> new OutputStreamOutput ( contentType , os , charsetName ));
}
Обратите внимание, что если есть исключение во время рендеринга, у выходного потока будет представлен частичный шаблон (вплоть до исключения). В большинстве случаев было бы лучше представить по умолчанию com.fizzed.rocker.runtime.ArrayOfByteArraysOutput
и написать свой буфер массивов байтов непосредственно в ваш выходной поток.
В действии есть многочисленные демонстрации рокера. От шаблонов разбора до модели до асинхронной отправки результатов на HTTP -сервер. Этот проект использует Blaze, чтобы помочь задачам сценариев. Запустите следующее для полного списка:
java -jar blaze.jar -l
Copyright (C) 2015+ Fizzed, Inc.
Эта работа лицензирована по лицензии Apache, версия 2.0. Смотрите лицензию для деталей.