Write once, render anywhere — используем один шаблонизатор на клиенте и сервере

Введение


Все вы наверняка уже слышали или используете в повседневной жизни различные шаблонизаторы, они же template engine-ы. Используем мы их обычно для генерации HTML кода. В этом процессе у нас как правило есть какая-то модель данных и HTML шаблон который мы этими данными наполняем.
Раньше HTML страницы мы генерировали только на серверной стороное, а сегодня все чаще делаем это и на клиенте. Спрос родил предложение, и у нас стало все больше появляться шаблонизаторов которые работают на JavaScript, а есть и шаблонизаторы с реализациями на множестве языков одновременно, в том числе и на серверных, какие возможности нам это дает, я попытаюсь описать в данной статье. Одним из примеров таких шаблонизаторов является mustache (прошу обратить внимание на список реализаций), который я буду использовать для примеров в этой статье. Т.е. слово mustache в статье вы можете заменять на фразу “любой шаблонизатор с имплементацией на JavaScript и вашем серверном языке”.

Очевидный пример использования


Очевидный пример использования такого шаблонизатора, это, конечно, возможность использования одного шаблона для генерации HTML кода на сервере и клиенте (наверняка, многим из вас приходилось дублировать код HTML блоков на javascript, и многие продолжают делать это сейчас). Необходимость в этом возникает постоянно, пример из жизни — twitter. Когда мы открываем twitter — сервер рендерит для нас первые несколько твитов, а при скроллировании вниз с помощью javascript подгружает следующую порцию и рендерит на клиенте по такому же шаблону. В этом случае, отлично подойдет mustache в чистом виде или в сочетании с icanhazjs. К слову, данный подход в некотором виде уже был упомянут на хабре тут и тут.

Менее очевидный пример использования


Есть также менее очевидный пример использования, на котором я бы хотел остановиться более подробно. Классический подход в реализации сайта — это создание дизайна, верстки и написание серверного кода, который наполняет верстку данными, и здесь также может найтись место для mustache.
Когда верстальщик отдает верстку, мы как правило не можем использовать ее в чистом виде, т.к. нам приходится наполнять ее серверным кодом, в итоге мы имеем сытную кашу из HTML + <ваш серверный язык программирования>. Неудобство такого подхода в том, что с момента когда мы наполнили верстку серверным кодом, ее становится сложно поддерживать, особенно если верстку и серверную часть делают разные люди. Мы не можем просто перезаписать HTML файлы с обновленной версткой которую нам выслал верстальщик, нам нужно очень аккуратно мержить изменения которые сделал верстальщик.
На самом деле мерж изменений это не единственная проблема, которая возникает при переносе верстки на сервер, я думаю каждый из вас сможет найти примеры из жизни когда интеграция доставляла неудобства.
Верстальщику порой приходится не сладко, когда ему нужно сверстать повторяющиеся блоки, которые выглядят немного поразному, и ему приходится копипастить куски своей верстки с этими блоками, а при изменении верстки делать изменения сразу во всех местах.
Серверный программист также вспоминает много плохих слов, когда вдруг оказывается, что верстальщик не предусмотрел в верстве стили для некоторых состояний компонентов, или в верстке захардкожены блоки и не тянутся при изменении данных.
В конце концов, тестировать верстку также очень неудобно, и практически невозможно, пока под нее не написали серверную часть. В связи с этим куча косяков, которых можно было избежать, вылезает уже после написания серверной части приложения, и мы начинаем пинать верстальщика чтобы он поправил верстку а потом серверного программиста чтобы он смержил изменения.
Всех этих негативных моментов можно попробовать избежать с помощью шаблонизаторов вроде mustache, ведь теперь у нас один шаблонизатор и на сервер и на клиенте. Сделать это не сложно, верстальщику нужно в верстке вместо того чтобы хардкодить данные, использовать mustache синтаксис, а затем написать пару строк javascript кода, с помощью которых он сможет заполнить свой шаблон данными. Для наглядности приведу небольшой пример:
<html>
	<head>
		<script type="text/javascript" src="mustache.js"></script>
		<script type="text/javascript" src="jquery.js"></script>
		<script>
			var data = {
			  "newsCategory": "IT",
			  "news": [
				  {
					"id": 1,
					"title": "Write once, render anywhere", 
					"preview": "bla bla bla", 
					"date": "01.01.2012"
				  },
				  {
					"id": 2,
					"title": "Mustache in action", 
					"preview": "bla bla bla", 
					"date": "02.02.2012"
				  }
			  ]
			}
			$(function(){
				$("body").html(Mustache.render($("body").html(), data));
			});
		</script>
	</head>
	<body>
		<h1>{{newsCategory}}</h1>
		<ul class="news">
			{{#news}}
			<li>
				<h2>{{title}}</h2>
				<p>{{preview}}</p>
				<a class="readMore" href="/news/{{id}}">Подробнее...</a>
				<div>{{date}}</div>
			</li>
			{{/news}}
		</ul>
	</body>
</html>

несложно догадаться, что при реализации серверной части мы сможем использовать тот-же шаблон, достаточно исключить не нужный javascript и использовать реализацию mustache для вашего серверного языка (Ruby, Java, PHP, Python, Scala и др. полный список тут).
Такой шаблон очень удобно тестировать (не нужно копипастить повторяющиеся блоки чтобы тестировать различные варианты их отображения, достаточно менять модель данных), верстальщик наверняка вам отдаст более качественную верстку чем при классическом подходе, в вы также сможете проверить насколько хороша верстка, подставив в javascript модель данных свои реальные данные. Такой шаблон также можно использовать в готовом виде на сервере и легко обновлять при обновлении верстки.
На самом деле, тот факт, что на момент создания шаблона уже будет готовая модель данных, дает много других, неявных преимуществ. Многих недочетов можно будет избежать ещё на этапе проектирования интерфейса.

Выводы


Безусловно, появление таких шаблонизаторов как mustache должно значительно упростить создание современных динамичных сайтов, и сделать процесс их создания более грамотным и удобным. И даже если в один прекрасный день, все начнут писать одностраничные клиенты на javascript, mustache все ещё можно будет использовать для генерации страниц для поисковиков на сервере.
В статье я не описал как можно использовать данный подход для построения страниц на сервере и клиенте из частей (partial-ы, include-ы — кому как нравится), тут есть масса ньюансов, предлагаю обсудить это в комментариях.

Средняя зарплата в IT

113 000 ₽/мес.
Средняя зарплата по всем IT-специализациям на основании 5 444 анкет, за 2-ое пол. 2020 года Узнать свою зарплату
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама

Комментарии 12

    +1
    Давно ищу Razor engine для клиента. Реально было бы удобно использовать один шаблон и для клиента и для сервера. Тем более если использовать подход view model per view, то даже ничего переделывать не надо будет.
      +1
      Может лучше без велосипедов, а взять старый-добрый XSLT. Сам не очень люблю эту технологию, но js шаблоны не нравятся ещё больше.
        0
        Очень медленно это дело работает и очень много ограничений по методам. Лет 5 назад конвертация на клиенте была практически невозможна(браузеры совсем не дружили). Конвертация силами сервера довольно ресурсоемкая. На php все было медленно и печально.
          0
          Мы в 2006-м вовсю использовали sajax www.ibm.com/developerworks/ru/library/os-phpajax/, проблем с браузерами и даже скоростью и производительностью на кривых тогда php библиотеках не было.
          Конечно, проблемы с прохорливостью трансформации на сервере есть, но она скажется только на хайлодах, коих 1%. Да и слухи сильно преувеличены.
          0
          Руки бы вам оборвать :) Кто потом будет поддерживать ваше наследие? Серьезно, применение XSLT — это очень неудачное решение, ибо любой язык разметки шаблонов проще и быстрее освоить чем XSLT.
            +1
            Вот именно, xslt стандартный механизм, который преподают даже в университетах, а сотый шаблонизатор нужно будет ещё выучить. Простые шаблоны на уровне большинства шаблонизаторов уже в первый день можно спокойно делать прочитав www.w3schools.com/xsl/default.asp
              –1
              Это бред, вы спорите с очевидным — XSL _сложнее_ любого императивного языка разметки шаблонов. Шаблоны XSLT громоздки. И, самое главное, у автора постановка задачи уже подразумевает знание JS.
                +1
                Вы же не питаетесь одними пельменями потому что их чуть легче готовить. Cпециально привёл ссылку чтобы показать что xsl не так уж сложен и его можно выучить без проблем. Да, он чуть сложнее, зато это стандартная кросплатформенная техника, работающая и на клиенте и на сервере, поддерживаемая большинством ЯП, которая существует уже много лет.
                Я же не навязываю, а просто привёл альтернативу для поста AlexShkor.
                  –1
                  Я не понимаю о чем мы спорим? Вы предлагаете XSLT, я вам говорю что этот вариант хуже, и говорю почему.
            –1
            Спасибо конечно, не не надо. Как по мне так лучше изучить 3-4 движка темплейтов, чем один XSLT.
            И вообще зачем мне нужен XSLT, если есть наглядный, красивый, удобный Razor, который я отлично знаю, да и все мои коллеги знают. Поэтому я и хочу его же на клиент.
            Вам в любом случае придется работать с другими движками, даже если вы будете переписывать все на XSLT всем с чем будете сталкиваться.
              0
              Люблю XSLT. Работал c ним почти десять лет на разных платформах начиная с Java и заканчивая шаблонизацией на клиенте.
              Но вот что непонятно. Преимущества очевидны. Из недостатков — относительная сложность.
              Так почему за 7-8 лет существования php не вышел в мейнстрим на сервере а на клиенте он так и остался кастрированным на уровне IE5
              =
              Имхо Относительно сложности — на 99% во всем виноват Валиков, чей учебник может вызвать заворот мозгов и устойчивое неприятие всего что связано с XSLT. А других долгое время на русском языке не было.
              Я до сих пор не понимаю чем отличается тупой XSLT-шаблон (в template-driven стиле) от любого другого шаблонизатора — та же дырка только в профиль.
            0
            Есть еще Jade, реализованный на всех популярных в Web языках (JavaScript, php, scala, ruby, python, java), который также можно использовать и на стороне клиента, и на стороне сервера.

            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

            Самое читаемое