Использование:
java -jar handlebars-proto-${current-version}.jar -dir myTemplates
Пример:
myTemplates/home.hbs
<ul>
{{#items}}
{{name}}
{{/items}}
</ul>
myTemplates/home.json
{
"items": [
{
"name": "Handlebars.java rocks!"
}
]
}
или, если вы предпочитаете YAML, myTemplates/home.yml:
items:
- name: Handlebars.java rocks!
http://localhost:6780/home.hbs
наслаждайтесь!
Иногда вам нужно или вы хотите протестировать несколько наборов данных в одном шаблоне. Вы можете сделать это, установив параметр data
в URI запроса.
Пример:
http://localhost:6780/home.hbs?data=mytestdata
Обратите внимание, что указывать расширение файла не обязательно.
См. документацию по встроенным помощникам.
Помощники block и partial работают вместе, чтобы обеспечить наследование шаблонов.
Использование:
{{#block "title"}}
...
{{/block}}
контекст: строковый литерал, определяющий имя региона.
Использование:
{{#partial "title"}}
...
{{/partial}}
контекст: строковый литерал, который определяет имя региона.
Предварительно скомпилируйте шаблон Handlebars.java в JavaScript с помощью handlebars.js.
user.hbs:
Hello {{this}}!
home.hbs:
<script type="text/javascript">
{{precompile "user"}}
</script>
Вывод:
<script type="text/javascript">
(function() {
var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
templates['user'] = template(function (Handlebars,depth0,helpers,partials,data) {
helpers = helpers || Handlebars.helpers;
var buffer = "", functionType="function", escapeExpression=this.escapeExpression;
buffer += "Hi ";
depth0 = typeof depth0 === functionType ? depth0() : depth0;
buffer += escapeExpression(depth0) + "!";
return buffer;});
})();
</script>
Вы можете получить доступ к предварительно скомпилированному шаблону с помощью:
var template = Handlebars.templates['user']
По умолчанию используется /handlebars-v1.3.0.js
для компиляции шаблона. Начиная с версии handlebars.java 2.x также можно использовать handlebars.js 2.x
Handlebars handlebars = new Handlebars();
handlebars.handlebarsJsFile("/handlebars-v2.0.0.js");
Для получения дополнительной информации ознакомьтесь с документацией по предварительной компиляции шаблонов.
Использование:
{{precompile "template" [wrapper="anonymous, amd or none"]}}
контекст: имя шаблона. Обязательно.
обёртка: одна из «анонимная», «amd» или «none». По умолчанию — «анонимный».
Также доступен плагин maven.
Помощник embedded позволяет «встроить» шаблон handlebars внутрь тега HTML <script>
:
user.hbs:
<tr>
<td>{{firstName}}</td>
<td>{{lastName}}</td>
</tr>
home.hbs:
<html>
...
{{embedded "user"}}
...
</html>
Вывод:
<html>
...
<script id="user-hbs" type="text/x-handlebars">
<tr>
<td>{{firstName}}</td>
<td>{{lastName}}</td>
</tr>
</script>
...
</html>
Использование:
{{embedded "template"}}
контекст: имя шаблона. Требуется.
Вспомогательная функция, построенная на основе ResourceBundle. ResourceBundle — наиболее известный механизм интернационализации (i18n) в Java.
Использование:
{{i18n Рэндер (Блог контекст, строка param0, int param1, boolean param2, Опции опции) {
вернуть ...
}
}
...
handlebars.registerHelpers(новый HelperSource());
**Или, если вы предпочитаете статические методы:**
```java
handlebars.registerHelpers(HelperSource.class);
### С простым ```JavaScript```
Это верно, начиная с версии ```1.1.0```, вы можете писать хелперы на JavaScript:
helpers.js:
```javascript
Handlebars.registerHelper('hello', function (context) {
return 'Hello ' + context;
})
handlebars.registerHelpers(new File("helpers.js"));
Круто, не правда ли?
handlebars.registerHelper("blog-list", новый Helper<Blog>() {
public CharSequence apply(List<Blog> list, Options options) {
String p0 = options.param(0);
assertEquals("param0", p0);
Integer p1 = options.param(1);
assertEquals(123, p1);
...
}
});
Bean bean = new Bean();
bean.setParam1(123);
Template template = handlebars.compileInline("{{#blog-list blogs \"param0\" param1}}{{/blog-list}}");
template.apply(bean);
handlebars.registerHelper("blog-list", новый Helper<Blog>() {
public CharSequence apply(List<Blog> list, Options options) {
String p0 = options.param(0, "param0");
assertEquals("param0", p0);
Integer p1 = options.param(1, 123);
assertEquals(123, p1);
...
}
});
Template template = handlebars.compileInline("{{#blog-list blogs}}{{/blog-list}}");
handlebars.registerHelper("blog-list", новый Helper<Blog>() {
public CharSequence apply(List<Blog> list, Options options) {
String class = options.hash("class");
assertEquals("blog-css", class);
...
}
});
handlebars.compileInline("{{#blog-list blogs class=\"blog-css\"}}{{/blog-list}}");
handlebars.registerHelper("blog-list", новый Helper<Blog>() {
public CharSequence apply(List<Blog> list, Options options) {
String class = options.hash("class", "blog-css");
assertEquals("blog-css", class);
...
}
});
handlebars.compileInline("{{#blog-list blogs}}{{/blog-list}}");
## Отчёт об ошибках
### Синтаксические ошибки
file:line:column: сообщение доказательство ^ [в файле:строке:столбце]
Примеры:
template.hbs
{{value
/templates.hbs:1:8: найдено 'eof', ожидается: 'id', 'parameter', 'hash' или '}' {{value ^
Если частичный шаблон не найден или содержит ошибки, добавляется вызов стека:
/deep1.hbs:1:5: Частичный '/deep2.hbs' не найден {{> deep2 ^ at /deep1.hbs:1:10 at /deep.hbs:1:10
### Ошибки помощников/времени выполнения
Ошибки помощников или времени выполнения похожи на синтаксические ошибки, за исключением двух вещей:
1. Проблема может быть (или не быть) в правильном месте
2. Трассировка стека недоступна
Примеры:
Блок-помощник:
```java
public CharSequence apply(final Object context, final Options options) throws IOException {
if (context == null) {
throw new IllegalArgumentException(
"found 'null', expected 'string'");
}
if (!(context instanceof String)) {
throw new IllegalArgumentException(
"found '" + context + "', expected 'string'");
}
...
}
base.hbs
{{#block}} {{/block}}
Handlebars.java сообщает:
/base.hbs:2:4: found 'null', expected 'string'
{{#block}} ... {{/block}}
Короче говоря, из помощника вы можете вызвать исключение, и Handlebars.java добавит имя файла, строку, столбец и доказательство.
Допустим, вам нужно получить доступ к текущему зарегистрированному пользователю на каждой странице. Вы можете опубликовать текущего зарегистрированного пользователя, подключившись к стеку контекста. Посмотрите, как это работает:
hookContextStack(Object model, Template template) {
User user = ....;// Получить зарегистрированного пользователя откуда-то
Map moreData = ...;
Context context = Context
.newBuilder(model)
.combine("user", user)
.combine(moreData)
.build();
template.apply(context);
context.destroy();
}
Где находится метод hookContextStack
? Ну, это зависит от вашего... Архитектура приложения
По умолчанию Handlebars.java использует методы JavaBean (то есть публичные методы getXxx и isXxx) и Map в качестве резолверов значений.
Вы можете выбрать другой резолвер значений. В этом разделе описывается, как это сделать.
Разрешает значения из публичных методов, начинающихся с «get/is».
Context context = Context
.newBuilder(model)
.resolver(JavaBeanValueResolver.INSTANCE)
.build();
Разрешает значения из нестатических полей.
Context context = Context
.newBuilder(model)
.resolver(FieldValueResolver.INSTANCE)
.build();
Разрешает значения из объектов java.util.Map
.
Context context = Context
.newBuilder(model)
.resolver(MapValueResolver.INSTANCE)
.build();
Разрешает значения из публичных методов.
Context context = Context
.newBuilder(model)
.resolver(MethodValueResolver.INSTANCE)
.build();
Разрешает значения из объектов JsonNode
.
Context context = Context
.newBuilder(model)
.resolver(JsonNodeValueResolver.INSTANCE)
.build();
Доступно в модулях Jackson 1.x и Jackson 2.x.
Context context = Context
.newBuilder(model)
.resolver(
MapValueResolver.INSTANCE,
JavaBeanValueResolver.INSTANCE,
FieldValueResolver.INSTANCE
).build();
Система кэширования предназначена для обеспечения масштабируемости и гибкости. Вот краткий обзор системы TemplateCache
:
public interface TemplateCache {
/**
* Удалить все сопоставления из кэша.
*/
void clear();
/**
* Исключить сопоставление для этого источника из этого кэша, если оно присутствует.
*
* @param source источник, чьё сопоставление должно быть удалено из кэша
*/
void evict(TemplateSource source);
/**
* Вернуть значение, к которому этот кэш сопоставляет указанный ключ.
*
* @param source источник, чей связанный шаблон должен быть возвращён.
* @param parser парсер Handlebars.
* @return шаблон.
* @throws IOException Если ввод не может быть проанализирован.
*/
Template get(TemplateSource source, Parser parser) throws IOException;
}
Как видите, метода put
нет. Вся тяжёлая работа выполняется в методе get
, который по сути является ядром системы кэширования.
По умолчанию Handlebars.java использует реализацию кэша null
(также известную как отсутствие кэша), которая выглядит следующим образом:
Template get(TemplateSource source, Parser parser) throws IOException {
return parser.parse(source);
}
В дополнение к кэшу null
Handlebars.java предоставляет ещё три реализации:
ConcurrentMapTemplateCache
— реализация кэша шаблонов на основе ConcurrentMap
, которая автоматически обнаруживает изменения в файлах.
Эта реализация работает очень хорошо в целом, но существует небольшое окно, когда два или более потоков могут компилировать один и тот же шаблон. Это не является большой проблемой с Handlebars.java, поскольку компилятор очень быстрый.
Но если по какой-то причине вы не хотите этого, вы можете использовать шаблонный кэш HighConcurrencyTemplateCache
.
HighConcurrencyTemplateCache
— реализация кэша шаблонов на основе ConcurrentMap
, которая автоматически обнаруживает изменения в файлах.
Этот кэш устраняет окно, созданное ConcurrentMapTemplateCache
до нуля.
Он следует шаблонам, описанным в книге «Java Concurrency in Practice» (Брайан Гетц), и гарантирует, что шаблон будет скомпилирован только один раз независимо от количества потоков.
GuavaTemplateCache
— реализация кэша шаблонов на основе Google Guava. Доступно в... handlebars=helpers — репозиторий для хелперов сообщества.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )