Показать сообщение отдельно
  #1 (permalink)  
Старый 08.04.2013, 17:23
Аватар для FINoM
Новичок
Отправить личное сообщение для FINoM Посмотреть профиль Найти все сообщения от FINoM
 
Регистрация: 05.09.2010
Сообщений: 2,298

Шаблонизатор aTemplate
Сегодня расскажу о шаблонизаторе, который я сделал несколько месяцев назад, но немного завис с документацией. Шаблонизатор успешно используется в нескольких проектах и работает на ура, перетерпевая только самые незначительные изменения. В качестве объяснения процитирую текст из первой версии документации, где я противопоставлял jQuery.tmpl и EJS со своим (этот текст будет выпилен, так как во-первых не очень красиво получается, во-вторых есть куча альтернатив).

---------
Шаблонизатор aTemplate — модификация микро-шаблонизатора Джона Резига http://ejohn.org/blog/javascript-micro-templating/ с расширенным функционалом. Целью aTemplate является создание шаблонизатора, лишенного минусов самых популярных на сегоднышний день шаблонизаторов jQuery.tmpl и EJS.

Что умеет aTemplate?
1. Делать всё, что оригинальный шаблонизатор Джона Резига. Синтаксис шаблонов аналогичен шаблонизатору EJS.
Как известно, jQuery.tmpl имеет собственный синтаксис шаблонов, далекий от оригинального JS кода, поэтому его скорость меньше. Кроме этого, у людей, использующих jQuery.tmpl часто возникают трудности из-за этого: сделать что-либо, выходящее за рамки шаблонизатора, например, получить индекс текущей итерации либо невозможно, либо очень сложно. aTemplate, как и EJS лишен этого минуса, так как в нем используется самый обычный Javascript без заморочек создателя.

2. Перебирать элементы с помощью each, который наличествует в jQuery.tmlp, но отсутствует в EJS. Часто разработчику приходится перебирать набор данных из массива или объекта, и, в случае с EJS, приходится использовать некрасивый for:
<% for( var i = 0; i < users.length; i++ ) { %>
	<span><%= users[ i ].name %></span>
<%} %>

или
<% for( var i in users ) if( users.hasOwnProperty( i ) ) { %>
	<span><%= users[ i ].name %></span>
<%} %>

или
<% for( var i = 0; i < users.length; i++ ) with( users[ i ] ){ %>
	<span><%= name %></span>
<%} %>

Вместо
{{each users}}
	<span>${name}</span>
{{/each}}

Второй вариант удобнее, правда?
aTemplate делает это так (хотя синтаксис EJS тоже сработает):
<%#each( users )%>
	<span><%= name %></span>
<%#/each%>


Причем, поддерживаются как массивы, так и обычные объекты.

3. Привязывать данные к элементу. Часто есть нужда привязать данные к элементу, генерируемому шаблонизатором. Такого функционала нет ни в jQuery.tmpl ни в EJS.

4. Работа в качестве jQuery плагина. Не пугайтесь, aTemplate можно использовать и без этой библиотеки.

Что не умеет aTemplate
Делать ajax запросы для получения шаблонов. Автору такой функционал показался излишеством. При желании программист, использующий aTemplate, может добавить его самостоятельно.

В итоге мы получаем:
1. Скорость, сравнимую с шаблонизатором Джона Резига
2. Гибкость, как в EJS
3. Удобство, как jQuery.tmpl

--------

Конструкция <%#each%> может содержать псевдоаргументы: перебираемый объект, текущий элемент итерации, ключ.
<%#each( users, user, index )%>
...
<%#/each%>

По умолчанию эти псевдоаргументы следующие:
this, _item, _key
Это значит, что можно не определять все три.
Написав:
<%#each%>
...
<%#/each%>

Получаем то же самое, что и:
<%#each( this, _item, _key )%>
...
<%#/each%>



Шаблонизатор запускается так:
aTemplate({
	template: 'templatetext',
	data: data
});


Поддержка карринга сохранена:
aTemplate({
	template: 'templatetext'
})( data );


Вместо template можно указать name:
aTemplate({
	name: 'name'
})


При этом, template будет браться из элемента (div, script...) с атрибутом data-atemplate. Я предпочитаю использовать script:
<script type="text/atemplate" data-atemplate="mytemplate">...</script>



По поводу работы в качестве jQuery плагина:
$( '#mytemplateblock' ).aTemplate( data );

или
$( '#mytemplateblock' ).aTemplate()( data );


Где '#mytemplateblock' - блок, в котором находится шаблон, например:
<div id="mytemplateblock">...</div>




Я всегда испытывал проблемы с тем, как же привязать объект к ноде в текстовом шаблоне. Привязка данных — это очень простая фича, которой мне всегда не хватало.

Раньше приходилось извращаться вот так:
<% for( var i = 0; i < this.length; i++ ) { %>
	<div data-name="<%= this[i].name %>" data-email="<%= this[i].email %>" data-age="<%= this[i].age %>" ... ><%= this[i].name %></div>
<%}%>


Здесь это делается так:
<%#each( this, user )%>
	<div data-abind="<%= at.bindData( user ) %>"><%= name %></div>
<%#/each%>




Вытащить данные из элемента можно так:
aTemplate.getBindedData( node );

или по айдишнику, который генерируется функцией at.bindData:
aTemplate.getBindedData( id );


Людям, использующим jQuery будет особенно удобно извлекать данные:
$( element ).data( 'aTemplate' );

или так:
$( element ).data().aTemplate;

или вот так:
$( element ).aTemplateData();


Несмотря на краткость кода, о функционале можно писать очень много, поэтому я могу забыть что-то упомянуть.

Ах, да, для тех, кто использует EJS и его небольшое дополнение view.js, последний был портирован для aTemplate:
<script type="text/atemplate">
	link_to( name, href );
 </script>


(честно признаюсь, тестирование всех функций view.js не проводилось)

https://github.com/finom/aTemplate
В репозитории только код. В документации расчитываю показать все возможные применения (пока не могу сказать, когда это случится). Несмотря на это, шаблонизатор уже можно юзать. Код очень простой (я надеюсь), поэтому, легко разобраться, как работает тот же each или привязка данных.
__________________
"Matreshka is fucking awesome" © чувак с Reddit
Matreshka.js - Три возможности

Последний раз редактировалось FINoM, 08.04.2013 в 17:42.
Ответить с цитированием