Статьи

Усы в мире Java


Усы — это система шаблонов с реализацией на многих языках, включая Java и JavaScript.
Шаблоны также поддерживаются различными веб-фреймворками и JS-библиотеками на стороне клиента.

Усы имеют простое представление о системе «без логики», потому что в ней отсутствуют какие-либо явные управляющие операторы, такие как
if ,
else или goto, а
также отсутствует
оператор
for, однако зацикливание и условный расчет могут быть выполнены с помощью пользовательских тегов, которые работают со списками и лямбдами. ,

Название, к сожалению, связано не столько с Томом Селлеком, сколько с интенсивным использованием фигурных скобок, которые выглядят как усы. Сходство более чем сопоставимо.

Усы есть реализация для большинства широко используемых языков, таких как: Java, Javascript, Ruby, Net и многих
других .

Шаблон на стороне клиента в JavaScript

Допустим, у вас есть какой-то REST-сервис, и вы создали объект просмотра книги, который имеет дополнительную функцию, которая добавляет идентификатор ассоциаций amazon в URL книги:

var book = {
  id : 12,
  title : "A Game of Thrones",
  url : "http://www.amazon.com/gp/product/0553573403/",
  amazonId : "myAwesomeness",
  associateUrl : function() {
    return this.url + '?tag=' + this.amazonId;
  },
  author : {
    name : 'George R. R. Martin',
    imdbUrl : 'http://www.imdb.com/name/nm0552333/',
    wikiUrl : 'https://en.wikipedia.org/wiki/George_R._R._Martin'
  },
  haveInStock : true,
  similarBooks : [{
    id : 13,
    title : "Decision Points"
  }, {
    id : 13,
    title : "Spoken from the Heart"
  }],
  comments : []
};

Стандартный способ рендеринга данных без использования шаблонов — создать выходную переменную и просто добавить все внутри, а в конце просто разместить данные в нужном месте.

jQuery(document).ready(function() {
  var out = '<div class="book-box"><h3>' + book.title + 
  '</h3><span> is awesome book get it on <a href="' +
 book.associateUrl() + '">Amazon</a></span></div>';
  jQuery('#content-jquery').html(out);
});

Это довольно просто, но если вы, например, хотите изменить элемент span с помощью div, потребуется немного времени, чтобы выяснить, где он должен быть закрыт, и часто вы можете пропустить, если элемент должен быть в одинарных или двойных кавычках. Большая проблема здесь заключается в том, что содержимое представляет собой набор строк, которые должны быть легко стилизованы с помощью CSS и JavaScript. По мере того, как код становится больше, это становится неуправляемым, а изменения во что-либо становятся медленнее, особенно если вы добавляете поверх функций манипулирования этого jQuery, таких как appendTo () или prependTo (). Такое непосредственное использование типа out + = для создания содержимого напоминает мне стиль HttpServlet, использующий средство записи и выполнения out.print (). и по той же причине, по которой это было почти заброшено, мы не должны делать это в JavaScript.

Чтобы упростить работу, мы можем добавить шаблонизатор, такой как Mustache, который является одним из многих заманчивых движков на стороне клиента. Так как же выглядит шаблон в усах, хорошо для примера выше с книгой это будет выглядеть так:
 

<script id="book-template" type="text/x-mustache-template">
      <div class="book-box">
      <h3>{{title}}</h3>
      <span> is awesome book get it on 
        <a href="{{associateUrl}}">Amazon</a>
      </span>
    </div>

Таким образом, этот шаблон можно разместить в любом месте на странице, а затем выбрать и отобразить, когда вам это нужно:

jQuery(document).ready(function() {
  var template = jQuery('#book-template').html();
  var renderedData = Mustache.render(template, book);
  jQuery('#content-mustache').html(renderedData);
});

Метод nder принимает содержимое шаблона и объектную книгу представления. Здесь замечательно то, что шаблон выглядит почти так же, как HTML, что упрощает его стилизацию, изменение и обслуживание.
Также вы можете использовать раздел, например:  {{#conditon}}   код или данные здесь {{/ условие}}, где, если значение равно true, раздел отображается, в противном случае весь блок игнорируется.

Если условия возвращают непустой список, это можно повторить, используя ту же конструкцию. Инвертированное условие выполняется с помощью  {^ conditon}} кода или данных здесь {{/ условие}} .

Точечная нотация может использоваться для доступа к подэлементам (не в каждой реализации), например, если вы хотите отобразить страницу imdb авторов из предыдущего примера, она будет выглядеть как {{author.imdbUrl}} . Существуют структуры, называемые частичными, которые можно использовать, если нам нужно включить частичные элементы во время рендеринга, а также, если необходимо, некоторые стандартные функции Mustache JS могут быть переопределены.

Вы можете получить пример с https://github.com/mitemitreski/blog-examples/tree/master/mustache-js.

Серверная рендеринг усов в Spring MVC

Существует реализация шаблонов Mustache для Java, которая называется Mustache.java, а другая — JMustache . Поскольку использование в веб-фреймворках необходимо, существует несколько статей об использовании Mustache в веб-приложениях на Java, например, на основе Struts, но я выбрал опцию Spring MVC, поскольку нашел ее более интересной для моего использования.

Для примера я использовал усино-весеннее представление   , которое довольно просто добавить с помощью maven: 

 <dependency>
    <groupId>com.github.sps.mustache</groupId>
    <artifactId>mustache-spring-view</artifactId>
    <version>1.0</version>
    </dependency> 

Это автоматически получит jMustache:

 + — com.github.sps.mustache: mustache-spring-view: jar: 1.0: compile
  \ — com.samskivert: jmustache: jar: 1.2: compile

Следующая часть включает представление в сервлете контекст и добавление соответствующих путей:

<beans:bean id="viewResolver" 
class="org.springframework.web.servlet.view.mustache.MustacheViewResolver">
 <!-- FIXME reload every time-->
 <beans:property name="cache" value="false" />
 <!-- The default view path is below -->
 <beans:property name="prefix" value="/WEB-INF/views/" />
 <!-- The default suffix path is below -->
 <beans:property name="suffix" value=".mustache" />
 <beans:property name="templateLoader">
  <beans:bean
   class="org.springframework.web.servlet.view.mustache.MustacheTemplateLoader" /> 
 </beans:property>
</beans:bean>

Как видите, конфигурация чрезвычайно проста, вам просто нужно добавить путь, в котором будут храниться шаблоны, суффикс, в котором будут заканчиваться шаблоны, фактический загрузчик шаблонов и, если шаблоны должны быть кэшированы. Во время разработки очень полезно установить для этого свойства значение true, так как таким образом вы будете получать мгновенную информацию об изменениях в ваших шаблонах.

Контроллер будет очень простым, так как это всего лишь небольшое подтверждение концепции:

/**
* Hello Mustache.
*/
@Controller
public class HomeController {

  private static final Logger logger = 
     LoggerFactory.getLogger(HomeController.class);

  /**
  * Simple controller that 
  * redirects to home and adds map and date objects.
  */
  @RequestMapping(value = "/", method = GET)
  public String home(Locale locale, Model model) {

    Date date = new Date();
    DateFormat dateFormat = 
        DateFormat.getDateTimeInstance(DateFormat.LONG,
        DateFormat.LONG, locale);

    Properties properties = System.getProperties();

    Map<String, String> map = 
       new HashMap<String, String>((Map) properties);

    String formattedDate = dateFormat.format(date);
    model.addAttribute("serverTime", formattedDate);
    model.addAttribute("props", map.entrySet());
    return "home";
  }

}
 

Контроллер просто заполняет системные свойства serer, и текущее время добавления передает модель в сторону шаблона. В соответствии с предыдущей конфигурацией имя шаблона — home.mustache, и оно находится в / WEB-INF / views /. 

Шаблон настолько прост, насколько это возможно, идея здесь состояла лишь в том, чтобы проиллюстрировать, как можно повторять Java-карты.

<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset=utf-8>
<title>Hello Mustache</title>
</head>
<body>
<div id="container">

  <p>Current server time is {{serverTime}}</p>
  <p>All the current system properties</p>
      <ul>
        {{#props}}
         <li>{{key}} = {{value}} </li>
        {{/props}}
      </ul>
</div>
</body>
</html>

Итак, как это работает? Хорошо, если мы возьмем serverTime, это может быть свойство java, ключ или метод, который делает его очень простым и читаемым. Полный пример можно найти на моей странице github.
Это просто обычный maven clean-пакет и он запущен, он протестирован на Tomcat 6 с Java 1.6, но достаточно прост для работы в любом месте. Хотя я пока не могу сказать, что использовал рендеринг на стороне сервера в производственной среде, они определенно выглядят многообещающе. Есть плагины для vim , emacs и textmate, но для eclipse нет плагина. В eclipse вы можете обойти Eclipse-> Preferences-> General-> Content_Types и добавить * .mustache для распознавания как html, по крайней мере, вы получите подсветку синтаксиса html.

Крутая вещь с Mustache заключается в том, что вы можете очень легко переключаться на то, будете ли вы использовать рендеринг на стороне сервера на стороне клиента. Кроме того, очень трудно добавить ненужную логику в шаблоны, что упрощает разработку.

Не забывайте, что ваше приложение горячо, только если у него потрясающие усы.

 

Другие ссылки