Комментарии 27
Месье знает толк, как говорится.
4) Поддержка шаблонов в любом текстовом редакторе — ибо они на самом деле представляют из себя чистый JS синтаксисДа, вот только
Line 17: hr; --- Expected an assignment or function call and instead saw an expression.
спасибо за репорт — а есть код в котором этот баг воспроизводиться?
Извиняюсь. С утра не проснулся и подумал что это какой-то Exception. Если вы про варнинги JSHint — то «это не баг это фича» ©. Я фактически использую конструкции которые не имеют смысла в чистом JS и базирую шаблонизацию на них. Возможно это не лучшая идея — но как маленький бонус в WebStorm я получаю подсветку шаблонов с помощью вот таких вот предупреждений :D
(html (:mytag :id "bar" "Foo"))
==>
<div class='mytag' id='bar'>Foo</div>
Когда то это уже не прокатило с Lisp'ом и в Lisp очень мощная система макросов и гибче языковые конструкции, но JavaScript уже намного популярнее, может что и получится.
Есть еще такие вещи.
Но вопрос смешения декларативности и императивности по-прежнему открыт.
Первые три «преимущества» – серьезные недостатки.
Можно с этого места поподробнее? Искренне хочу подискутировать :)
Речь идет об инкапсуляции логики шаблона от бизнес логики и ограничениях возможностей, потому что зачастую шаблоны делают люди, которым лучше не давать в руки eval.
Но на мой взгляд главный недостаток в том, что одно из самых важных (по моему мнению) свойств шаблоннизаторов — легкость переноса из верстки (html) в полноценный шаблон. Тут с этим полная беда.
Но на мой взгляд главный недостаток в том, что одно из самых важных (по моему мнению) свойств шаблоннизаторов — легкость переноса из верстки (html) в полноценный шаблон. Тут с этим полная беда.
Подождите, ведь автор поста и не говорил ничего о смешении бизнес-логики с отображением — с помощью JS можно в шаблоне реализовывать компоненты, которых нет в HTML или другую логику связанную чисто с отображением.
Где alert новый компонент (например, bootstrap alert) превратится в
// Partial - подшаблон
function _item(){
b[args({style: 'color: blue', class: 'test'})].raw("Name:").b;
div.context.name.div;
hr;
alert.raw("Привет");
}
Где alert новый компонент (например, bootstrap alert) превратится в
<div class="alert">Привет</div>
отпишусь всем в 1 коментарии
спасибо sferrka — абсолютно верно подмечанно. правда компонет Alert в терминах STEN пока реализовываеться вот таким способом
function _alert(){
div['class="alert"'].context.div;
}
и переиспользуеться он в большом шаблоне вот так
function _template(){
partial(_alert, "Hello world");
}
что в свою очеред компилируеться в
function compiled__alert(context,r){
r=r||"";
r+='<div '+('class="alert"')+'>'+(context)+'</div>';
return r
}
to erlioniel
К сожалению вы не правы. В любой более или менее развитый шаблонизатор можно запихнуть бизнес логику. Можно != нужно. Что вам мешает разделить код шаблонов от кода бизнес логики? Ничего. Держите код шаблонов в отдельном месте и не пишите там бизнес логику. Все просто
Я очень не люблю идею — давайте затупим скальпель а то люди могут им пораниться. Не надо делать инструменты тупее. Нужно людей делать умнее.
to printf
По поводу «путания шаблонов и логики» — могу сказать только одно. Не путайте. Данная библиотека тут ни причем.
По поводу безопасности. Вас никто не заставляет тащить саму библиотеку STAN в проект. Пока к сожалению у меня небыло времени написать препроцессор — но вы сами можете довольно легко его написать и ложить в проект только скомпилированные шаблоны — и никаких eval не будет. PS: Постараюсь как можно быстрее написать плагины для Grunt и Gulp.
По поводу «вот это шаблоны» — Вы привели явно не лучшие примеры, но всеравно. Скажите. В каком из них для прохода по массиву я могу использовать lodash? ;)
спасибо sferrka — абсолютно верно подмечанно. правда компонет Alert в терминах STEN пока реализовываеться вот таким способом
function _alert(){
div['class="alert"'].context.div;
}
и переиспользуеться он в большом шаблоне вот так
function _template(){
partial(_alert, "Hello world");
}
что в свою очеред компилируеться в
function compiled__alert(context,r){
r=r||"";
r+='<div '+('class="alert"')+'>'+(context)+'</div>';
return r
}
to erlioniel
К сожалению вы не правы. В любой более или менее развитый шаблонизатор можно запихнуть бизнес логику. Можно != нужно. Что вам мешает разделить код шаблонов от кода бизнес логики? Ничего. Держите код шаблонов в отдельном месте и не пишите там бизнес логику. Все просто
Я очень не люблю идею — давайте затупим скальпель а то люди могут им пораниться. Не надо делать инструменты тупее. Нужно людей делать умнее.
to printf
По поводу «путания шаблонов и логики» — могу сказать только одно. Не путайте. Данная библиотека тут ни причем.
По поводу безопасности. Вас никто не заставляет тащить саму библиотеку STAN в проект. Пока к сожалению у меня небыло времени написать препроцессор — но вы сами можете довольно легко его написать и ложить в проект только скомпилированные шаблоны — и никаких eval не будет. PS: Постараюсь как можно быстрее написать плагины для Grunt и Gulp.
По поводу «вот это шаблоны» — Вы привели явно не лучшие примеры, но всеравно. Скажите. В каком из них для прохода по массиву я могу использовать lodash? ;)
Ни в каком из них не нужен lodash просто в силу архитектуры (обход массива правильно реализован).
Если для таких простейших действий необходим ворох костылей, значит, все очень плохо.
Если для таких простейших действий необходим ворох костылей, значит, все очень плохо.
Зачем использовать для прохода по массиву lodash, если давно есть работающий во всех вменяемых браузерах нативный Array#forEach, который умеет ровно то же самое?)
Путать шаблоны и код это моветон, а доступ из шаблона в глобальное пространство имен – еще и дыра в безопасности (да-да, «хоть что-то у нас в безопасности»).
Такой шаблон нельзя применять в CMS, и его должен писать всенепременно программист, с нуля (ведь скопировать имеющуюся разметку и добавить в нужные места «шаблонные» макросы, как это обычно делается, не получится).
Вот шаблонизаторы: Nunjucks, Mustache, Django.
Такой шаблон нельзя применять в CMS, и его должен писать всенепременно программист, с нуля (ведь скопировать имеющуюся разметку и добавить в нужные места «шаблонные» макросы, как это обычно делается, не получится).
Вот шаблонизаторы: Nunjucks, Mustache, Django.
Обработчики событий предполагается навешивать на элементы после работы шаблонизатора?
Мда… советую остановиться пока не поздно. Вы начали не с того, в первую очередь шаблонизатор должен быть надежным, уметь выводить ошибки и быть понятным. Весь этот JS синтаксис просто головная боль, как для человека, так и любой нормальной IDE, чего уже говорить про JSHint.
Ну, а бечмарк с самим собой — это прям огонь, порадовали :]
Ну, а бечмарк с самим собой — это прям огонь, порадовали :]
Только давайте без лишнего драматизма :) «Мы послали терминатора чтобы остановить тебя от создания этого шаблонизатора»
Отлаживать данный шаблонизатор удобнее чем любой существующий, ибо по сути мы просто отлаживаем JS.
От JSHint можно избавится /* jshint expr:true */ ( поместив это только в файлы шаблонов )
Ну а бенчмарк вы всегда можете сравнить сами
jsperf.com/javascript-templating-shootoff-extended/92
Отлаживать данный шаблонизатор удобнее чем любой существующий, ибо по сути мы просто отлаживаем JS.
От JSHint можно избавится /* jshint expr:true */ ( поместив это только в файлы шаблонов )
Ну а бенчмарк вы всегда можете сравнить сами
jsperf.com/javascript-templating-shootoff-extended/92
Отлаживать ваш «шаблонизатор», а точнее реплейсер, сложней чем любой другой нормальный шаблонизатор, не обманывайте себя.
Все эти div.b и div.e, это же «рак», если шаблон будет больше 10 строчек, то уследить, кто-где закрылся…
Или представьте, что где-то в шаблоне есть конструкция div.context.foo.bar.baz.qux, сейчас вся «цепочка» должна быть определена, в противном случае шаблон просто молча упадет c JS-ошибкой.
Вот смотрите, я ради разминки написал «супер быстрый» и короче вашего на 4 строки «шаблонизатор» и как по мне, читается легче, пилить статью? :]
Все эти div.b и div.e, это же «рак», если шаблон будет больше 10 строчек, то уследить, кто-где закрылся…
Или представьте, что где-то в шаблоне есть конструкция div.context.foo.bar.baz.qux, сейчас вся «цепочка» должна быть определена, в противном случае шаблон просто молча упадет c JS-ошибкой.
Вот смотрите, я ради разминки написал «супер быстрый» и короче вашего на 4 строки «шаблонизатор» и как по мне, читается легче, пилить статью? :]
var result = absurdTpl(function (ctx) {
h1.head | "AbsurdTpl";
form[{ action: "/", type: "post" }];
h2 | "Simple form";
ctx.items.forEach(function (inp) {
label | inp.label + ":";
input[{ value: inp.value }];
});
hr;
button[{ type: "submit" }] | "Send";
});
console.log(result({ items: [{ label: "E-mail", value: "trash@rubaxa.org" }] }));
>>div.context.foo.bar.baz.qux, сейчас вся «цепочка» должна быть определена, в противном случае шаблон просто молча упадет c JS-ошибкой.
>>
Вы явно любите говорить о том о чем не знаете. Что пичально.
Строчка «div.context.foo.bar.baz.qux» моментально падает с ошибкой.
>> я ради разминки написал «супер быстрый» и короче вашего на 4 строки
Ну во-первых ваш шаблонизатор не совместим ни с jsbin ни с jsfiddle
jsbin.com/tazulewe/20/edit
Оставляю вам это как ДЗ ( если совсем лень — вот вам подсказка — добавьте где угодно в JS коментарий — //noprotect )
Во-вторых. У вас нет возможности вызвать один шаблон из другово. Так что «не удивительно» что ваш код короче на 4 строчки.
>> Вот смотрите…
Кстати, спасибо — подтолкнули на ряд идей, по оптимизации. Плюс нашел ряд проблем как у вас так и у себя.
>> пилить статью? :]
Ну, вы не маленький, думаю сможете для себя сами решить :)
>>
Вы явно любите говорить о том о чем не знаете. Что пичально.
Строчка «div.context.foo.bar.baz.qux» моментально падает с ошибкой.
>> я ради разминки написал «супер быстрый» и короче вашего на 4 строки
Ну во-первых ваш шаблонизатор не совместим ни с jsbin ни с jsfiddle
jsbin.com/tazulewe/20/edit
Оставляю вам это как ДЗ ( если совсем лень — вот вам подсказка — добавьте где угодно в JS коментарий — //noprotect )
Во-вторых. У вас нет возможности вызвать один шаблон из другово. Так что «не удивительно» что ваш код короче на 4 строчки.
>> Вот смотрите…
Кстати, спасибо — подтолкнули на ряд идей, по оптимизации. Плюс нашел ряд проблем как у вас так и у себя.
>> пилить статью? :]
Ну, вы не маленький, думаю сможете для себя сами решить :)
Охо-хо, ну да ладно, надеюсь когда вы поймете, на сколько ваш «шаблонизатор» — не шаблонизатор, будет не слишком поздно.
Строчка «div.context.foo.bar.baz.qux» моментально падает с ошибкой.Это вы невнимательно читаете, я как раз об это и написал. Падение с JS-ошибкой это неправильное, я бы даже сказал фатальное поведение для шаблонизатора.
Ну во-первых ваш шаблонизатор не совместим ни с jsbin ни с jsfiddleОй, ну могли бы сами поправить jsbin.com/juxusofo/1/edit
Во-вторых. У вас нет возможности вызвать один шаблон из другово.Ой, ну это это делается очень просто, количество кода увеличится на
.replace(/~([\w+_-]+)/, 'buf += absurdTpl["$1"]')
Скрытый текст
var item = absurdTpl("form-item", function (ctx) {
label | ctx.label + ":";
input[{ value: ctx.value }]
});
var result = absurdTpl("form", function (ctx) {
form[{ action: "/", type: "post" }]
h2 | "Simple form" // !!!
ctx.items.forEach(function (inp) {
~form-item(inp);
});
hr;
button[{ type: "submit" }] | "Send"
});
Кстати, спасибо — подтолкнули на ряд идей, по оптимизации. Плюс нашел ряд проблем как у вас так и у себя.Лол, весь мой код одна сплошная проблема, так что не благодарите.
Всеравно спасибо за коментарии ( извиняюсь если где-то грубил )
А по поводу «остановиться пока не поздно». Я больше чем уверен что если это плохая идея — она умрет сама сабой. Если все настолько плохо насколько вы описываете то мне не придется прилагать никаких усилий чтобы проект накрылся медным тазом :)
PS: для меня этот проект интересен. На вашем месте я бы наверно тоже не воспринял этот проект серьезно, но не знаю. Возможно это возрастное — подросту — буду умнее. А пока всеравно хочется попробовать насколько далеко можно зайти с подобной идеей. Есть же яркий пример PHP :D
А по поводу «остановиться пока не поздно». Я больше чем уверен что если это плохая идея — она умрет сама сабой. Если все настолько плохо насколько вы описываете то мне не придется прилагать никаких усилий чтобы проект накрылся медным тазом :)
PS: для меня этот проект интересен. На вашем месте я бы наверно тоже не воспринял этот проект серьезно, но не знаю. Возможно это возрастное — подросту — буду умнее. А пока всеравно хочется попробовать насколько далеко можно зайти с подобной идеей. Есть же яркий пример PHP :D
Я говорю, что у вас плохой посыл. Микро «шаблонизаторов» море, но все они годятся для очень примитивных задач, если делать что-то серьезное, то нужен нормальный шаблонизатор, который умеет выводить как compile, так и runtime ошибки.
По мимо этого, писать на JS реально плохая идея, вы увеличиваете вероятность ошибки во много раз, любое несовпадение типов (тот же undefined), отсутствие какого либо метода и шаблон будет падать. Обойти это конечно можно, но для этого нужно будет пропускать код через что-то типа Esprime и разбирать «выражения», преобразуя их в «безопасные». Проще запилить подсветку для IDE.
P.S. Как идея да, забавно, можно побаловаться, но вот в люди тащить это не стоит, кто-то может и всерьез воспринять.
По мимо этого, писать на JS реально плохая идея, вы увеличиваете вероятность ошибки во много раз, любое несовпадение типов (тот же undefined), отсутствие какого либо метода и шаблон будет падать. Обойти это конечно можно, но для этого нужно будет пропускать код через что-то типа Esprime и разбирать «выражения», преобразуя их в «безопасные». Проще запилить подсветку для IDE.
P.S. Как идея да, забавно, можно побаловаться, но вот в люди тащить это не стоит, кто-то может и всерьез воспринять.
Ну есть же TypeScript. Он вполне себе может помочь с проблемой несовпадения типов. ( compile time only )
По-поводу несовпадения типов и undefined — все известные мне шаблоны ( Handelbars, Mustashe, Jinja2, Razor ect ) зачастую страдают ровно от техже проблем. Есть какие-то примеры шаблонизаторов которые удволетворяют всем требованиям которые вы описываете?
А про отсутствие «нормальных» сообщений об ошибках знаю — но что вообще можно с этим сделать идей никаких нет. Тут даже это не проблема STAN. Это проблема всех шаблонных движков — туда можно отправить undefined или {} — и на выходе получить html.
По поводу Esprime — тоже складывается ощущение что возможно придется его использовать. Пока просто ищу альтернативные пути. Занимающее мало кода.
PS: Не думаю что стоит прятать какие-либо идеи от людей. Даже если они плохие.
По-поводу несовпадения типов и undefined — все известные мне шаблоны ( Handelbars, Mustashe, Jinja2, Razor ect ) зачастую страдают ровно от техже проблем. Есть какие-то примеры шаблонизаторов которые удволетворяют всем требованиям которые вы описываете?
А про отсутствие «нормальных» сообщений об ошибках знаю — но что вообще можно с этим сделать идей никаких нет. Тут даже это не проблема STAN. Это проблема всех шаблонных движков — туда можно отправить undefined или {} — и на выходе получить html.
По поводу Esprime — тоже складывается ощущение что возможно придется его использовать. Пока просто ищу альтернативные пути. Занимающее мало кода.
PS: Не думаю что стоит прятать какие-либо идеи от людей. Даже если они плохие.
Сообщения об ошибках есть у все достойных шаблонизаторов. Jade, Handelbars, Mustashe и другие популярные движки, корректно выводят ошибки при компиляции и не падают при undefined (как и не выводят его).
А про отсутствие «нормальных» сообщений об ошибках знаю — но что вообще можно с этим сделать идей никаких нет. Тут даже это не проблема STAN. Это проблема всех шаблонных движков — туда можно отправить undefined или {} — и на выходе получить html.
Напрашиваются прокси-объекты в runtime, но в JS их еще не запилили.
А было бы здорово — обращаемся к неизвестному полю у объекта — получаем либо валидный объект с измененным свойством toString
Div.prototype.toString = function() {
return "<div ....";
}
, либо корректную ошибку с указанием имени и всего чего угодно.
Хотя если использовать только известные теги и свойства, то прокси-объекты можно реализовать через getter-setter'ы. Как вам идея?
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
STAN — самый короткий шаблонный движок