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

в 12:27, , рубрики: javascript, template engine, web-разработка, Веб-разработка, шаблонизаторы, метки: , , ,

Введение

Все вы наверняка уже слышали или используете в повседневной жизни различные шаблонизаторы, они же 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-ы — кому как нравится), тут есть масса ньюансов, предлагаю обсудить это в комментариях.

Автор: LexeY4eg

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js