Javascript templates text template

javascript-шаблонизация для начинающих на примере lodash template

В своих постах я часто упоминаю javascript-шаблонизацию. Underscore и lodash-шаблоны, может, видели. И недавно понял свою ошибку. Я пишу про шаблоны так, как будто прям каждый обязан знать, что это такое. А если не знает, то легко загуглит. А давайте-ка вместе и погуглим. Чуть не первая статья, с хабра, цитирую
— Лучшим выбором оказываются шаблоны, потому что это приводит к более чистому базовому коду и лучшему процессу работы с ними.

Хм, ну окееей. Погуглим еще. Сайт developer.mozilla.org, серьезные ребята, почитаем.
— Шаблонными литералами называются строковые литералы, допускающие использование выражений внутри. С ними вы можете использовать многострочные литералы и строковую интерполяцию.

Че-то это вообще не то. Это что-то из es6. Ну и третья попытка:
— Неплохо бы использовать механизм шаблонизации на стороне клиента, чтобы отделить поведение приложения от его внешнего вида

Я в свое время читал похожие умные слова и ни фига не понимал. Если Вы понимаете, то читать дальше будет не интересно. Зайдите на хабр и прочитайте лучше там. А вот те, кто по этим фразам с трудом улавливает, о чем речь, но хочет понять, оставайтесь. Попробуем вместе разобраться, что такое javascript-шаблонизация, зачем она нужна и когда применяется.

Люблю случаи из жизни. Давай представим. Ты работаешь в веб-студии фронтендщиком. На пару с бекендщиком пилите сайты. Пусть его зовут Серега. Ты верстаешь шаблоны, отдаешь ему html-файлы, а он их натягивает на cms-ки или фреймворки. Какой-нибудь битрикс или laravel, не суть. Серега твой бро, он не воротит нос от html-тегов и вообще отличный парень. Нормально относится к тому, что ты просишь в зависимости от разных условий проставлять тегам нужные классы или не выводить определенные блоки. И все у вас хорошо, спокойно работаете, а по пятницам вместе бухаете в баре.

Однажды к вам приходит дизайнер и говорит, а чо мы список товаров делаем всегда одинаково? Пагинация, фу, прошлый век же. Давайте замутим подгрузку товаров аяксом, когда прокручиваем до конца страницы. Вы такие с Серегой думаете, а чо, прикольно. Набрасываете схему, ты отлавливаешь, когда юзер докрутил до подвала страницы, дергаешь аяксом запрос, а он отдает тебе html со списком товаров. А ты такой ррраз и $(‘#products’).append(response). Нормальная схема, все довольны. Ты делаешь верстку, несложную, примерно такую

Идешь к Сереге и объясняешь, мол, верстка такая, но есть две детали. Если товара нет в наличии, то в тексте у product__store пишешь «Нет в наличии». И еще не забудь кнопке button при этом проставить атрибут disabled. Серега говорит, без проблем, все сделаю. Ты дальше возишься с прокруткой страницы и отправкой аякс-запроса, он формирует html по твоей верстке и данным из базы. Потом стыкуетесь, все отлично, начальство и дизайнер довольны.

Читайте также:  Плагин pure php localization

Проходит неделя, к тебе снова идет дизайнер. Говорит, чувак, давай когда товара нет в наличии, немного стили изменим. Ну там заголовок сереньким сделаем, а кнопку «В корзину» вообще уберем. Ты говоришь, хорошо. Думаешь, так, стили поменять, это нужно класс модификатор навесить, типа -available прямо на li.product. А кнопку можно убрать через display: none, но лучше бы вообще убрать. Идешь к Сереге, рассказываешь это все, он делает, опять все довольны.

Магазин развивается, начальство придумывает новую фишку. Давайте сделаем рейтинги товаров. Нарисуем звездочки у каждого товара и пусть люди кликают. Вы с Серегой собираетесь на совет. Он говорит, мол, я заведу поле rating в базе, ты дергаешь post-запрос, отправляешь мне айдишник товара, а я там разберусь, в базе инкремент сделаю, рейтинг товара увеличиваю. Ты говоришь, все нормально, только звездочки в верстку не забудь добавить. И тут он отвечает, рано или поздно, он такое скажет. Мол, бро, я все понимаю, но и ты меня пойми. Мне твои звездочки до одного места. Я тут запросы в базу пишу и редисы настраиваю, давай ты версткой сам будешь заниматься. Я тебе отдам данные о товарах, в json-чике, а ты делай с ними, что хочешь. Хочешь, звездочки добавляй, хочешь, классы навешивай, хочешь, тексты меняй в зависимости от наличия. Ты немножко недоволен, нормально же все раньше было. Но в душе понимаешь, Серега прав. И говоришь, отличная идея, давай так и сделаем.

Серега готовит запрос и тебе рассказывает. Вот смотри, теперь тебе будет отдаваться не готовый html, а json-массив такого вида.

Ты говоришь, ну нормально, чо я массив что ли распарсить не смогу и в html добавить? И начинаешь делать. Сначала у тебя получается что-то вроде этого

var products = JSON.parse(response); var html = ''; products.forEach(function(product) < // формируем строку html для одного товара и добавляем ее в переменную html >); $('#products').append(html);

Пока ничего особенного, пока не начали реализовывать вот это

// формируем строку html для одного товара и добавляем ее в переменную html

Вспомним те условия, что у нас есть: класс-модификатор -available, разный текст в зависимости от наличия и убрать кнопку корзины, если нет товара. И начинаем писать что-то такое

Уф. Читать, конечно, тяжко, но пока еще можно. Вспомним, для чего мы это затеяли? Да, нам же звездочки рейтинга нужно добавить. Изящный код в нужное место и все.

Ну так себе, выглядит диковато, но ладно. Главное, теперь не надо Серегу дергать каждый раз со всякой фигней. И всей версткой ты управляешь на клиенте. Ты гордо говоришь, что вы с Серегой перенесли рендер html с сервера на клиент. Начальство довольно.

Читайте также:  Java string pattern validation

Но только эйфория недолго длится. Прибегает менеджер и говорит: так, у нас акция, последние 5 товаров со склада продаем со скидкой 20%. И красным выделяем такие товары. Обсуждаете с Серегой. Он говорит, слушай, давай я добавлю в респонс json-a поле count — сколько товаров на складе осталось. А ты на фронте скидку сам посчитаешь. А то сам знаешь, сегодня прибегут, скажут последние 5 товаров с 20% скидкой и цвет красный, а завтра последние 10 и скидка 15%. А цвет зеленый. А ты на фронте все разрулишь, все равно к тебе будут с этим бегать. Ты такой, ну окей, сделаю.

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

Как оно? Такое чувство, что с этим пора что-то делать. Это мы пока очень простые варианты рассматриваем, а что будет, если посложнее? У меня от кавычек одинарных и двойных уже в глазах рябит. Ошибиться в такой мешанине легче легкого. Чуть промахнулся, удалил кавычку лишнюю, попробуй потом найди, где косяк и почему все валится. Надо что-то делать. Для начала гуглим. А что гуглить-то? Хрен знает даже, как вопрос задать. Чешешь репу дальше.

Вдруг ты вспоминаешь, что у Сереги же должны были быть такие же проблемы. Раньше, когда он верстку сам натягивал. Какая разница, на бекенде, на фронтенде, у него такие же условия и вычисления. Идешь к нему. Показываешь код, спрашиваешь, как он раньше делал? Он говорит, у меня шаблонизатор есть, я туда данные загоняю, а на выходе готовый html. Спрашиваешь, а как это выглядит? Серега показывает, вот, например, у тебя такая строка

А у меня в шаблоне была бы такая

Блин, вроде ж то же самое, но по читабельности не сравнить. Ты говоришь, ладно, это самый простой случай, а как сделать такую штуку, посложнее?

html += '
' + (product.available ? 'В наличии' : 'Нет в наличии') + '
';

Серега отвечает, да примерно так же.

Или еще лучше, текст записать заранее в переменную, вот так

var availableText = product.available ? 'В наличии' : 'Нет в наличии');

Вот так точно лучше, кратко и ясно. А вычисления все отдельно. И 5 звездочек нечего лепить руками, циклом прогнал по массиву от 1 до 5 и все. А то завтра нужно будет 10 звездочек поставить, чтобы еще не копипастить, а просто заменить 5 на 10. Еще Серега что-то рассказывает про MVC, отделение логики приложения от представления, про модели и вьюхи, но ты слушаешь плохо, и так уже есть над чем подумать.

Читайте также:  Using regex with javascript

Ты подумал и теперь, имея некий багаж знаний, гуглишь уже целенаправленно. И инфу найти легче. Возможно, ты уже пользовался библиотеками lodash или underscore. Ты удивляешься, но в них есть функция работы с шаблонами _.template. Если про нее не знать, то читая доку и внимания не обратишь. Но теперь-то ты представляешь, что это такое, и смотришь внимательнее.

Оказывается, чтобы работать с шаблонами через lodash (да и вообще с любым шаблонизатором), нужно сделать 2 вещи: подготовить данные и верстку, то есть сам шаблон. Это и есть то самое отделение логики от представления. Или почти что MVC. Данные о товаре это условно модель, а шаблон — вьюха или представление.

Давайте сначала простейший пример, как работает _.template() в lodash (в underscore точно так же). Заглянем в документацию.
Там приведен код

var compiled = _.template('hello !'); compiled(< 'user': 'fred' >); // => 'hello fred!'

Такие смешные закорючки — это место для переменной user. Точнее, не переменная, а поле объекта < 'user': 'fred' >. user можно и без кавычек, просто

Смотрим дальше. Написать в одной строке ‘hello !’ легко. Но у нас немаленькая верстка из нескольких элементов. Чтобы сделать адекватно, применяют хитрый шаг. Шаблоны не сразу записывают в строки, а предварительно прямо в html в специальном теге

Или type=»text/x-template», можно по-разному, но суть одна — содержимое этого тега не исполняется как javascript, и мы из него вытаскиваем строку шаблона через простой $(‘#template-name’).html(). Давайте попробуем написать шаблон для нашего случая

Ну как? Сравните с тем, что было выше, где складывали строки. Читалось это совершенно иначе. В кавычках уже не путаемся. Видим, что у элемента с классом product могут быть еще 2 класса-модификатора classAvailable и classLast. Условие if (available) then вывести кнопку button тоже логически срисовывается. И даже цикл for, где мы выводим список li, не вызывает страха. Да, немножко непривычны эти постоянные , а в getDataForProductItemTemplate вычислим новое поле classNew и добавим его в return. Жизнь становится гораздо проще.

Подведу итоги. Надеюсь, мы смогли разобраться, зачем нужна javascript-шаблонизация. Или по крайней мере поняли ее плюсы и будем пытаться применять. На мой взгляд, синтаксис шаблонов в undescore/lodash не самый симпатичный. Но есть и куча других, например, handlebars. Он лаконичнее и приятнее. Например, там переменная выводится не , а > Кому как, но мне симпатичнее. Плюс в handlebars есть свои плюшки, типа вычисляемых полей и прочего. Впрочем, синтаксис lodash меня вообще не напрягает, поэтому именно его я и использую в своих статьях. И скажу по секрету, его можно переопределить под себя. Например, вместо

Источник

Оцените статью