глупый вопрос - в боевых проектах использовал или сделал и положил на полку? :)
UPD: не знаю, как оно там с точки зрения парсинга, но смущает, что: - циклы {forEach a => el, i} {end} - ифы {if a > 3} {end} - вичи :) {with obj} {end} - темплейты {template test(obj)} {end} - прото {proto a} {end} - блок {block a}Вася{end} заканчиваются на {end} в то время, как - cdata {cdata} {end cdata} на {end cdata}. Не порядок, однако. На первый взгляд, из-за того, что окончания для многих блоков единообразно, сложно будет отследить вложенность блоков. Привет бейсик, здравствуй наглядность: {forEach a => el, i} {next} {if a > 3} {end if} {with obj} {end with} {template test(obj)} {end template} {proto a} {end proto} {block a}Вася{end block} {cdata} {end cdata} |
Цитата:
Я очень жирно использую ООП и мне крайне важно было максимально гибкая система наследования в шаблонах, а также одинаково удобная система использования на сервере (node.js) и клиенте. Ошибки и новые фичи исправляю по мере необходимости. На этой недели собирался сделать большой фикс, так как всплыли некоторые оч противные баги (вроде невозможности декларировать константы внутри прототипа). С cdata проблема в том, что содержимое вырезается по регулярке до анализа шаблона и построения дерева, поэтому возможна следующая проблема: {cdata} {end} {end} Фактически содержимое внутри блока cdata никак не обрабатывается, поэтому я могу написать что угодно, но в данном случае нужно либо как то экранировать {end} теги внутри области (как например это делается в xml), тому кто пишет шаблон или ввести особый закрывающий тег, как сейчас сделано у меня. А так я не вижу смысла делать для каждой директивы свой закрывающий тег - это имхо не круто, тем более с точки зрения парсинга это не даёт профита, т.к. по шаблону у меня строится дерево, в котором видна вся вложенность блоков. Ну а чтобы было видно человеку - нужно делать отступы :) {template foo(params, type = 'static')} {if type === 'static'} муахахаха! {else} {block bar} ... {end} {end} {end} |
kobezzza, спасибо за ответ.
По поводу {end} я категорически тебе предлагаю сделать так, как написал выше. Причина - удобство. Я вижу какой тег закрыт :) Пример // начало кода // много букв {end} {end} смысл примера в том, что я не вижу шапки кода, только подвал. Т.о. для того, чтобы отличить одно от другого, придется скроллить. Иными словами, на этом уровне все кошки серы (почти все). Можно замутить опрос, но на мой взгляд это скорее минус, чем плюс. |
еще можно пойти по пути html
{foreach} a => el, i} {/foreach} {if a > 3} {/if} {with obj} {/with} {template test(obj)} {/template} {proto a} {/proto} {block a}Вася{/block} {cdata} {/cdata} т.е. я к тому, что должно быть видно, какой тег закрыт Цитата:
Почему развел демагогию: присматриваюсь к твоему шаблонизатору :D |
Цитата:
Цитата:
UPD: Я протупил, писать {end что то} можно уже сейчас, т.е. {forEach data => el, i} {end forEach} Т.к. парсер обрабатывает директиву, как {названиеДирективы любые условия}, а в случае с end условий нет, т.е. можно писать что угодно и это ничего не сломает :) {forEach data => el, i} {end это конец моего блока} |
Добавил поддержку закрытия директив через / , как в xml. Новая версия доступна на гитхабе.
{template foo()} {/template} Раз уж зашла тема, скажу что в следующей версии добавлю: 1) Переменные. Я долго противился этому введению, пока пару раз сам не встал на грабли, когда константы не могут их заменить. В отличии от констант переменные нельзя будет явно переопределить в дочернем шаблоне, а только через переопределение родительского блока или прототипа или константы на которую переменная ссылается. Т.е. {template base()} {block foo} {var a = 1} ... {end} {end} {template child() extends base} /// Переопределяем блок и заодно переменную внутри него {block foo} {var a = 2} {end} {end} 2) Циклы. Есть задачи, вроде: сгенерить для select-а номер года от 19.. до ныненшнего, а с итератором такое решение выглядит немного странно. {for var i = 0; i < 10; i++} ... {end} вместо {forEach new Array(10) => el, i} ... {end} 3) Также улучшу и задокументирую некоторые нестандартные фичи, о которых сейчас знаю только я :) В остальном будет исправление известных ошибок и написание новых тестов. |
kobezzza, отлично, спасибо :)
|
Почти закончил работу, над новой версией, скорее всего во вторник выложу, но возник вопрос, когда переписывал модуль обработки scope, а именно:
Мой шаблонизатор поддерживают директиву with (в JS with не используется), которая позволяет явно указывать контекст поиска свойств объекта, т.е. : {template foo()} {my = { name: 'Koba', age: 23 }} {with my} <p>Имя: {name}</p> <p>Возраст: {age}</p> {end} {end} Это очень удобно, особенно когда у нас ссылка вроде myObj.someProp1.someProp2. А также в моём шаблонизаторе есть "волшебная" директива proto, которая позволяется создавать что-то вроде микрошаблонов. {template foo()} {proto logo} <img src="..." alt="моё супер лого" /> {end} <div class="header"> ... {apply logo} </div> <div class="footer"> ... {apply logo} </div> {end} Думаю смысл кода выше всем понятен, но всё же поясню: внутри директивы proto мы декларируем часть шаблона, которая не будет выведена сразу после декларации, а только после того, как мы её вызовем, с помощью директивы apply. А теперь собственно суть проблемы: сейчас директива proto всегда использует глобальный scope шаблона, т.е. {template foo()} {my = { name: 'Koba', age: 23 }} {with my} {proto gen} <p>Имя: {name}</p> <p>Возраст: {age}</p> {end} /// Будет ошибка, т.к. прототип всегда использует глобальный контекст шаблона {apply gen} {end} {end} Проблема решается в общем то довольно тривиально: нужно просто поместить директиву with внутрь прототипа, но я подумал, а что если прототипы будут при декларации получать родительский scope, т.е. пример выше сможет корректно работать, т.к. директива proto находится в контексте with и будет его наследовать. Как вам такое предложение? |
Цитата:
{template foo()} {my = { name: 'Koba', age: 23 }} {proto gen} <p>Имя: {name}</p> <p>Возраст: {age}</p> {end} {with my} {apply gen} {end} {end} |
Цитата:
|
Часовой пояс GMT +3, время: 19:34. |