Шаблоны для jQuery (плагин jquery-tmpl)

Внимание. Этот пост немного устарел, и есть более актуальный.

Пару дней назад коллега спросил, знаю ли я какой-нибудь шаблонизатор для jQuery. И я вспомнил, что читал о плагинах, разработанных Майкрософтом, среди которых был и шаблонизатор jQuery Templates (jquery-tmpl). Заодно и сам разобрался, как он работает, и начал использовать в своём проекте. В обмен коллега показал мне удобный способ хранения шаблонов.

Итак, шаблон. Он хранится внутри тега script (это и есть тот самый удобный способ).

<script type="text/plain" id="tmpl_photo">
  <div class="sh-photo jstree-draggable" data-id="${id}">
    <img src="${image}" width="${width}" height="${height}" alt="${title}">
  </div>
</script>

Имена, указанные, в фигурных скобках, — ключи хэша с данными, которые мы будем показывать. Я пока пользовался только простейшим шаблонным тегом ${}. Кроме него есть условный тег, цикл и всякие другие штуки.

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

$.template('photo', $('#tmpl_photo').html());

Теперь шаблон будет доступен по имени photo и мы можем отобразить с его помощью какие-нибудь данные.

var photos = [
  {id: 1, image: 'photo1.jpg', title: 'Photo 1', width: 100, height: 100},
  {id: 1, image: 'photo1.jpg', title: 'Photo 2', width: 100, height: 100}
];

$.tmpl('photo', photos).appendTo('#container');

Очень удобно, что функция может принимать массив и применять шаблон к каждому элементу. Но не очень удобно, что шаблонизатор работает как бы наоборот, т. е. нужно выполнить преобразование, а потом прицепить куда-то результат. Да ещё и новые данные всегда будут добавляться к уже имеющимся в контейнере, а не заменять их. Поэтому я для себя сделал вот такую функцию.

$.fn.tmplTo = function(tmpl, data) {
  return this.each(function() {
    var elem = $(this);
    elem.empty();
    $.tmpl(tmpl, data).appendTo(elem);
  });
};

Теперь шаблон применяется к контейнеру (который будет предварительно очищаться) и не теряется цепочность вызовов. Работает вот так.

$('#container')
  .tmplTo('photo', photos)
  .show();