Комментарии 20
Ничего хорошего из этого не выйдет :-)
+4
А теперь предположим, что в html встречается последовательность символов
Всё-таки для шаблонов нужен нормальный парсер.
[=[
или ]=]
. И абстракция потекла…Всё-таки для шаблонов нужен нормальный парсер.
+4
Да, есть несколько неучтенных моментов, которые я в ближайшие пару дней поправлю и задокументирую.
0
Для более сложного можно использовать мой вариант. Он подстраивается под начинку. Но да, не «одной строкой».
0
Исправлено.
0
Причем тут спагетти-код? Исходно термин «спагетти-код», он же «макаронный код», означал код с запутанным потоком управления — многочисленными операторами GOTO (или избыточным использованием исключений). Также спагетти-кодом называют код со слишком обширными связями между модулями, когда формально независимые модули невозможно использовать раздельно.
Шаблоны в стиле php — не самая удачная конструкция исключительно из-за похожести символов <? и ?> на тэги HTML. Других недостатков у таких этих шаблонов нет, и называть их «спагетти-кодом» некорректно.
Шаблоны в стиле php — не самая удачная конструкция исключительно из-за похожести символов <? и ?> на тэги HTML. Других недостатков у таких этих шаблонов нет, и называть их «спагетти-кодом» некорректно.
+4
Есть, они смешивают логику и верстку из-за чего и верстать не удобно и за логикой сложно уследить.
+1
А что, кто-то заставляет их смешивать? Можно же их и разнести: либо просто логику в начало файла передвинуть, либо даже по разным файлам — язык-то позволяет. Хоть убейте, не вижу никакой принципиальной разницы между
<? if ($foo) { ?>
<div><?=$foo?></div>
<? } ?>
и@if (foo != null) {
<div>@foo</div>
}
кроме удобочитаемости.+1
Да, такой формат. Ты просто не сможешь ничего отрендерить, не применив циклы, ветвления и функции.
Оба примера содержат смешение логики и верстки. Правильный пример мог бы выглядеть так:
Оба примера содержат смешение логики и верстки. Правильный пример мог бы выглядеть так:
myViewList = {
get content(){
if( this.items ) {
return this.items.map( item => new myViewItem( item ) )
} else {
return new myViewEmpty
}
}
}
<div type="myViewList">{content}</div>
<div type="myViewItem">
<div type="myViewItem_title">{title}</div>
<div type="myViewItem_count">{count}</div>
</div>
<div type="myViewEmpty">
List is empty. Try to reduce filters.
</div>
-1
Вот извините, но именно ваш пример и является спагетти-кодом (точнее, спагетти-версткой). О том, что myViewItem и myViewEmpty являются альтернативными вариантами разрешения {content} в myViewList, не сказано нигде — и догадаться об этом, читая верстку, невозможно.
Так зачем нужна «чистая от логики» верстка, если понять ее можно только глядя на логику?
Так зачем нужна «чистая от логики» верстка, если понять ее можно только глядя на логику?
+5
{content} может разрешаться во всё, что угодно и на этапе вёрстки совершенно не важно во что. Задача верстальщика — предоставить кубики лего из которых программист может строить приложение любой сложности просто стыкуя их в разных комбинациях. Прежде чем оголтело кидаться минусами, я бы советовал вам попробовать — это реально гораздо удобней.
А пока подумайте над следующими проблемами так называемых «традиционных шаблонов» и над способами их решения:
1. рендеринг блоков разных типов одним списком (например, лента новостей)
2. перестановка блоков местами в зависимости от набора параметров (например, полей много, но заполнены только частично и нужно выводить их в компактном виде)
3. ленивая загрузка минимума данных, необходимого для рендеринга, а не всего подряд (в запросе надо указать какие поля моделей надо прогрузить)
4. возможность пользователя конфигурировать раскладку блоков на странице и переключать их видимость (например, дашборд)
5. реиспользование верстки (ссылка на пользователя, ссылка на метку, кнопка и тп)
А пока подумайте над следующими проблемами так называемых «традиционных шаблонов» и над способами их решения:
1. рендеринг блоков разных типов одним списком (например, лента новостей)
2. перестановка блоков местами в зависимости от набора параметров (например, полей много, но заполнены только частично и нужно выводить их в компактном виде)
3. ленивая загрузка минимума данных, необходимого для рендеринга, а не всего подряд (в запросе надо указать какие поля моделей надо прогрузить)
4. возможность пользователя конфигурировать раскладку блоков на странице и переключать их видимость (например, дашборд)
5. реиспользование верстки (ссылка на пользователя, ссылка на метку, кнопка и тп)
-1
Задача верстальщика — сверстать страницу, а не заставлять программиста играть в кубики. Тем более, что верстальщику гораздо проще напрямую сверстать страницу, чем сначала верстать ее, а потом нарезать на кубики.
Не говорю уже о том, что в вашей модели верстальщик и программист должны работать параллельно, потому что ни один из них не увидит результата своей работы до завершения чужой. В традиционной модели такого ограничения нет.
И даже если в команде считается, что задача верстальщика — только HTML-верстка, а шаблон должен готовить программист — то «нарезание» готовой верстки на циклы и условные операторы не сложнее ее нарезания на блоки.
1. Для того, чтобы рендерить разные типы блоков одним списком, надо их получить одним списком. Рендеринг — наименьшая из проблем, которая решается оператором цикла и несколькими условными операторами.
2,4. Перестановка блоков местами и возможность конфигурировать раскладку блоков — да, они требуют выделения части верстки в отдельную сущность «блок». «Традиционные» шаблоны легко позволяют это сделать. Но, заметьте, выделять в автономный блок следует лишь то, что и правда должно быть выделено — при этом как общий макет страницы, так и внутренняя верстка блока могут быть сделаны так, как удобно верстальщику, а не так, как его ограничили вы.
3. Ленивая загрузка данных — это когда выполняется 100500 уточняющих запросов к БД при каждом формировании страницы? Спасибо, не надо! Лучше я по-старинке, одним-двумя запросами все необходимое вытащу.
5. Те блоки верстки, которые должны быть переиспользуемы, легко становятся функциями. Важно, что решение сделать их повторно используемыми может быть принято верстальщиком единолично, без согласования с программистом или архитектором проекта.
Не говорю уже о том, что в вашей модели верстальщик и программист должны работать параллельно, потому что ни один из них не увидит результата своей работы до завершения чужой. В традиционной модели такого ограничения нет.
И даже если в команде считается, что задача верстальщика — только HTML-верстка, а шаблон должен готовить программист — то «нарезание» готовой верстки на циклы и условные операторы не сложнее ее нарезания на блоки.
Прежде чем оголтело кидаться минусами, я бы советовал вам попробовать — это реально гораздо удобней.В разное время мне случалось редактировать шаблоны веб-страниц на движке Razor (который в ASP.NET MVC) и на укозе (там используются блоки, как вы предлагаете). Так вот — первая задача была выполнена за 15 минут, а вторую я бросил. Поэтому я возвращаю вам ваш совет: попробуйте делать так, как делают все нормальные люди — это реально гораздо удобней.
1. Для того, чтобы рендерить разные типы блоков одним списком, надо их получить одним списком. Рендеринг — наименьшая из проблем, которая решается оператором цикла и несколькими условными операторами.
2,4. Перестановка блоков местами и возможность конфигурировать раскладку блоков — да, они требуют выделения части верстки в отдельную сущность «блок». «Традиционные» шаблоны легко позволяют это сделать. Но, заметьте, выделять в автономный блок следует лишь то, что и правда должно быть выделено — при этом как общий макет страницы, так и внутренняя верстка блока могут быть сделаны так, как удобно верстальщику, а не так, как его ограничили вы.
3. Ленивая загрузка данных — это когда выполняется 100500 уточняющих запросов к БД при каждом формировании страницы? Спасибо, не надо! Лучше я по-старинке, одним-двумя запросами все необходимое вытащу.
5. Те блоки верстки, которые должны быть переиспользуемы, легко становятся функциями. Важно, что решение сделать их повторно используемыми может быть принято верстальщиком единолично, без согласования с программистом или архитектором проекта.
0
Если речь о лендингах, то да, сверстал страницу и свободен. Если речь о полноценном сайте или даже веб-приложении, то важным становится реиспользуемость кода, легкость поддержки, выдержанность единого дизайна (как внешнего, так и внутреннего). Программисту проще писать без тестов, но поддерживать результат потом невозможно. Работа верстальщика не заканчивается на первичной верстке. Он должен иметь возможность править верстку без ковыряния в куче логики. Путь «верстальщик делает статический макет, программист разрезает его и натягивает на шаблонизатор, потом верстальщик поправил макет, программист заново его нарезает» — порочен.
В «традиционной модели» шаблон зависит от формата данных, которые должен сформировать программист. Никакого разделения не получится. В «непривычной модели» зависимости нет и верстальщик может компоновать блоки как угодно, причем выводить их сразу во всех возможных состояниях, а не заниматься ерундой вида «поправил код. перезагрузил страницу, подождал пока пройдет вся инициализация, накликал нужное состояние, увидел косяк и по новой».
Ещё раз — проблема не в «нарезании» — это однократная операция. Проблема в поддержке, которая нужна постоянно. И верстальщик, не имея должной квалификации и желания разбираться просто сделает копипасту сложного условия вместо того, чтобы рефакторить логику.
Можно пример укозового шаблона? В любом случае тезис похож на «я привык работать молотком, поэтому забиваю шурупы быстрее чем вкручиваю». За 8 лет, а перепробовал всё, что только можно, от говнокода на smarty до крупных проектов на xslt :-)
1. Получить одним списком это проблема только в строготипизированных языках. Но вывод слишком поверхностный. Там еще вынести все эти шаблоны придется по любому, или этот мегашаблон, который умеет рендерить всё, разрастётся до неприличных размеров.
2, 4. В современных динамичных приложениях такие блоки — далеко не единичные случаи. Даже «общего макета страницы» может не быть.
3. Нет, это когда клиент выгружает с сервера не все 100500 полей на каждый чих, а только те, что нужно показать. Но тем не менее, много простых запросов куда лучше кластеризуются, кешируются, параллелизуются, чем один сложный.
5. Продвигаемая мной идея как раз и позволяет делать это легко и просто. О чём спор? :-)
В «традиционной модели» шаблон зависит от формата данных, которые должен сформировать программист. Никакого разделения не получится. В «непривычной модели» зависимости нет и верстальщик может компоновать блоки как угодно, причем выводить их сразу во всех возможных состояниях, а не заниматься ерундой вида «поправил код. перезагрузил страницу, подождал пока пройдет вся инициализация, накликал нужное состояние, увидел косяк и по новой».
Ещё раз — проблема не в «нарезании» — это однократная операция. Проблема в поддержке, которая нужна постоянно. И верстальщик, не имея должной квалификации и желания разбираться просто сделает копипасту сложного условия вместо того, чтобы рефакторить логику.
Можно пример укозового шаблона? В любом случае тезис похож на «я привык работать молотком, поэтому забиваю шурупы быстрее чем вкручиваю». За 8 лет, а перепробовал всё, что только можно, от говнокода на smarty до крупных проектов на xslt :-)
1. Получить одним списком это проблема только в строготипизированных языках. Но вывод слишком поверхностный. Там еще вынести все эти шаблоны придется по любому, или этот мегашаблон, который умеет рендерить всё, разрастётся до неприличных размеров.
2, 4. В современных динамичных приложениях такие блоки — далеко не единичные случаи. Даже «общего макета страницы» может не быть.
3. Нет, это когда клиент выгружает с сервера не все 100500 полей на каждый чих, а только те, что нужно показать. Но тем не менее, много простых запросов куда лучше кластеризуются, кешируются, параллелизуются, чем один сложный.
5. Продвигаемая мной идея как раз и позволяет делать это легко и просто. О чём спор? :-)
-1
В современных динамичных приложениях такие блоки — далеко не единичные случаи. Даже «общего макета страницы» может не быть.Приведите пример сайта, у которого нечего вынести в общий макет (кроме одностраничных сайтов, где само слово «общий» теряет смысл). Я пока что из таких видел только одну CMS, работающую по принципу «создай все сам, редактируя БД через тот же интерфейс, который ты сейчас создаешь». Спасибо, но такая CMS должна отправиться в то же место, куда и мегаблочные спагетти-шаблоны.
В любом случае тезис похож на «я привык работать молотком, поэтому забиваю шурупы быстрее чем вкручиваю».Оба раза я видел шаблонизатор впервые.
Ещё раз — проблема не в «нарезании» — это однократная операция. Проблема в поддержке, которая нужна постоянно.Вот мне надо исправить положение имени пользователя на странице. Допустим, я как веб-разработчик уже имею опыт, но на проекте впервые, так что ничего еще в нем не знаю (сравнивать поведение человека в знакомом проекте смысла нет, потому что в обоих случаях он найдет нужное место сразу же).
В традиционном шаблоне достаточно найти элемент в инспекторе (встроенная возможность браузера, 2 клика), запомнить его окружение — и найти похожий блок кода в шаблоне. Поскольку структура шаблона и результата совпадает — это несложно.
Теперь берем ваш шаблонизатор. Где искать блок, выводящий имя пользователя? Искать по файлу строку «username»? А если она называется «user_name» или «login»? Ну хорошо, блок с именем пользователя нашли — но проблема оказалась не в нем, а во внешнем блоке. Как найти внешний блок, не заглядывая в логику? А если в эту логику заглянуть — то зачем мы ее с такой кровью отделяли?
0
Да тот же google.ru (морда и результаты поиска)
Правда там смена раскладки сделана на css — гораздо менее гибким муторным способом.
Вы так и не привели примера укозного шаблона.
«запомнить его окружение»
«и найти похожий блок кода в шаблон»
Как-то всё это похоже на гадание на кофейной гуще.
«структура шаблона и результата совпадает»
Опять же только в лендингах она совпадает. В остальных же случаях — частично пересекается, не более.
Конкретно в моём шаблонизаторе у каждого элемента есть идентификатор, который однозначно идентифицирует шаблон из которого этот элемент получен и вьюшку, которая послужила источником данных.
Тут подробней описано как оно работает
Правда там смена раскладки сделана на css — гораздо менее гибким муторным способом.
Вы так и не привели примера укозного шаблона.
«запомнить его окружение»
«и найти похожий блок кода в шаблон»
Как-то всё это похоже на гадание на кофейной гуще.
«структура шаблона и результата совпадает»
Опять же только в лендингах она совпадает. В остальных же случаях — частично пересекается, не более.
Конкретно в моём шаблонизаторе у каждого элемента есть идентификатор, который однозначно идентифицирует шаблон из которого этот элемент получен и вьюшку, которая послужила источником данных.
Тут подробней описано как оно работает
0
На том же google.ru можно дофига чего вынести в общий макет — наличие нескольких выбивающихся из макета страниц этому ничуть не мешает.
Ну где я вам сейчас возьму укозный шаблон? 10 лет назад я тот сайт редактировал. Создайте там сайт да посмотрите на этот ужас.
С идентификаторами элементов — ладно, выкрутились :) В таком виде действительно можно быстро найти нужное место.
Вы так и не привели примера укозного шаблона.
Ну где я вам сейчас возьму укозный шаблон? 10 лет назад я тот сайт редактировал. Создайте там сайт да посмотрите на этот ужас.
С идентификаторами элементов — ладно, выкрутились :) В таком виде действительно можно быстро найти нужное место.
0
В луашной библиотеке Lapis тоже есть шаблоны с возможностью экранировать теги HTML.
Про Lapis по-русски: habrahabr.ru/post/240217/
Про Lapis по-русски: habrahabr.ru/post/240217/
+1
Более того, в moonscript есть возможность делать так
Я задавался задачей сделать что-то аналогичное etlua максимально просто.
Скрытый текст
[list_users: "/users"]: =>
users = Users\select! -- `select` all the users
@html ->
ul ->
for user in *users
li ->
a href: @url_for("user", user.id), user.name
Я задавался задачей сделать что-то аналогичное etlua максимально просто.
+1
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
One-liner для компиляции шаблонов на Lua