Статьи

Демо руля, и почему вы должны рассмотреть шаблонизатор

Некоторое время я думал, что мне нужно взять и начать использовать шаблонизатор JavaScript. Несколько лет назад я использовал jQuery, но этот проект был заброшен, и мне еще только предстоит посмотреть, какое решение, если таковое будет, подойдет мне. Еще одна причина, по которой я не нашел времени, заключается в том, что большинство моих примеров JavaScript — это маленькие маленькие демонстрации, созданные для постов в блоге. Когда я пишу в блоге, я стараюсь сделать свой код максимально простым. Я делаю все MVC только для демонстрации форматирования даты. Это может быть не реальный мир, но он также держит вас сосредоточенным на теме, которую я пытаюсь обсудить.

Сегодня я сделал время — а более конкретно — сделал демо. Демо глупо Это даже не важно. Что важно, это:

Если вы когда-либо использовали JavaScript для построения строк HTML, вы никогда не понимали, насколько это тяжело, пока вам это не нужно. Вы никогда не понимали, насколько вы устойчивы к добавлению новых функций или настройке дизайна. Вы никогда не понимали, сколько вы сдерживаете — просто из-за сильной боли в тылу!

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

Именно так я себя чувствую сегодня — и любой день, когда мой компьютер вызывает у меня улыбку, — хороший день. Хорошо, достаточно бессвязно.

Я слышал о руле от разных людей. Это также шаблонизатор, который использует Ember.js . Handlebars работает, позволяя вам определять шаблоны, используя простые блоки скриптов, поэтому, например, вы можете написать свой шаблон в своем документе следующим образом:

<script id="result-template" type="text/x-handlebars-template">
<div class="entry">
  <h1>{{title}}</h1>
  <div class="body">
    {{body}}
  </div>
</div>
</script>

Затем вы используете API панели управления, чтобы создать шаблон из блока, применить к нему данные, а затем отобразить его на экране. Это все относительно просто, но документы не обязательно делают большую работу, я думаю о демонстрации простых примеров на «полных» страницах, чтобы вы могли видеть вещи в контексте. Вот тривиальный пример:

 

<!DOCTYPE html>
<html>
<head>
	<title>Test 1</title>
	<script src="js/handlebars-1.0.0.beta.6.js"></script>
	<script id="result-template" type="text/x-handlebars-template">
	<h2>Your Bio</h2>
	<p>
	Your name is {{firstname}} {{lastname}} and you are {{age}} years old.
	</p>
	</script>
    <link rel="stylesheet" href="style.css" type="text/css" />
</head>

<body>

	<h2>Render Simple Bio</h2>

	<input type="text" id="firstname" placeholder="First Name"><br/>
	<input type="text" id="lastname" placeholder="Last Name"><br/>
	<input type="number" id="age" placeholder="Age"><br/>
	<button id="demoButton">Demo</button>

	<div id="resultDiv"></div>

	<script>

	document.addEventListener("DOMContentLoaded", function() {

		//Get the contents from the script block 
		var source = document.querySelector("#result-template").innerHTML;
		//Compile that baby into a template
		template = Handlebars.compile(source);

		document.querySelector("#demoButton").addEventListener("click", function() {
			var fname = document.querySelector("#firstname").value;
			var lname = document.querySelector("#lastname").value;
			var age = document.querySelector("#age").value;

			var html = template({firstname:fname, lastname:lname,age:age});
			document.querySelector("#resultDiv").innerHTML = html;

		});
	});


	</script>

</body>
</html>

Обратите внимание, что у меня есть простой шаблонный блок сверху. Если вы никогда раньше не видели Handlebars или какой-либо движок шаблонов JavaScript, вы можете догадаться, какие части блока представляют динамические части, а какие — статический текст.

У меня есть простая форма с кнопкой, привязанной к простому слушателю щелчка. Глядя на JavaScript, вы можете видеть, что сначала мне нужно взять HTML-код из блока шаблона. Затем я собираю это. Это дает мне шаблон, который я могу использовать для генерации вывода.

Моя форма имеет простой обработчик кликов. Когда вы нажимаете кнопку, я передаю значения в свой шаблон и извлекаю из него HTML-код. Вы можете запустить это демо здесь:

http://raymondcamden.com/demos/2012/apr/19/test1.html

Конечно, не каждый шаблон будет простым набором ключей и значений. Ваш шаблон также может быть динамическим на основе переданных значений. Давайте рассмотрим другой пример, в котором используются как списки, так и условные выражения.

 

<!DOCTYPE html>
<html>
<head>
	<title>Test 2</title>
	<script src="js/handlebars-1.0.0.beta.6.js"></script>
	<script id="result-template" type="text/x-handlebars-template">
	<h2>Your Favorite Things</h2>

	{{#if things}}
		<ul>
		{{#each things}}
			<li>{{this}}</li>
		{{/each}}
		</ul>
	{{else}}

		<p>
		Apparently, you like nothing. Poor you.
		</p>

	{{/if}}
	</script>
    <link rel="stylesheet" href="style.css" type="text/css" />
</head>

<body>

	<h2>List of Things</h2>
	<p>
		Enter a comma-separated list of things you like.
	</p>
	<input type="text" id="things" placeholder="Things you like..."><br/>
	<button id="demoButton">Demo</button>

	<div id="resultDiv"></div>

	<script>

	document.addEventListener("DOMContentLoaded", function() {

		//Get the contents from the script block 
		var source = document.querySelector("#result-template").innerHTML;
		//Compile that baby into a template
		template = Handlebars.compile(source);

		document.querySelector("#demoButton").addEventListener("click", function() {
			var things = document.querySelector("#things").value;
			if(things.length) var arrThings = things.split(",");

			var html = template({things:arrThings});
			document.querySelector("#resultDiv").innerHTML = html;

		});
	});


	</script>

</body>
</html>

 

В нашем шаблоне у нас здесь две вещи. Первый — это условие, которое проверяет, является ли «вещи» истинным значением (правда, является одной из вещей, которые делают JavaScript таким увлекательным). В истинной части условного выражения мы используем каждый блок для перечисления набора значений.

Если вы прокрутите вниз до HTML / JavaScript, вы увидите, что я просто прошу вас ввести список того, что вам нравится. Это значение разбивается на массив и передается (если были значения) в шаблон. Демо это ниже ..

http://raymondcamden.com/demos/2012/apr/19/test2.html

Давайте посмотрим на еще один пример. Одним из круче аспектов Handlebars является то, что вы можете добавлять пользовательские функции в движок. Например, вы можете написать функцию cowbell, которая обернет ваши результаты в красивые качающиеся звуки cowbell. Хорошо, может быть, не так. Но как насчет чего-то более сложного — например, преобразования адреса электронной почты в хеш MD5, который можно использовать для Gravatar? Да — ни за что это не сработает …

<!DOCTYPE html>
<html>
<head>
	<title>Test 3</title>
	<script src="js/handlebars-1.0.0.beta.6.js"></script>
	<script src="js/webtoolkit.md5.js"></script>
	<script id="result-template" type="text/x-handlebars-template">
	<h2>You and Your Gravatar</h2>
	<p>
	Your email is {{email}} and your gravatar is:<br/>
	<img src="{{gravatarurl email }}">
	</p>

	</script>
    <link rel="stylesheet" href="style.css" type="text/css" />
</head>

<body>

	<h2>Enter Email Address for Awesomeness</h2>
	<input type="email" id="email" placeholder="Email goes here..."> 
	<button id="demoButton">Demo</button>

	<div id="resultDiv"></div>

	<script>

	document.addEventListener("DOMContentLoaded", function() {

		//Tip on using Gravar with JS: http://www.deluxeblogtips.com/2010/04/get-gravatar-using-only-javascript.html
		Handlebars.registerHelper('gravatarurl', function(email) {
		    return 'http://www.gravatar.com/avatar/' + MD5(email) + '.jpg?s=250';
		});

		//Get the contents from the script block 
		var source = document.querySelector("#result-template").innerHTML;
		//Compile that baby into a template
		template = Handlebars.compile(source);

		document.querySelector("#demoButton").addEventListener("click", function() {
			var email = document.querySelector("#email").value;
			if(!email.length) return;

			var html = template({email:email});
			document.querySelector("#resultDiv").innerHTML = html;

		});
	});


	</script>

</body>
</html>

 

Обратите внимание, что в шаблоне у нас есть одно простое значение — электронная почта, а затем это: электронная почта gravatar. Это не что-то встроенное в Handlebars, а скорее, внедренное через функцию registerHelper, которую вы видите в главном блоке скрипта страницы. Вы можете продемонстрировать это здесь:

http://raymondcamden.com/demos/2012/apr/19/test3.html Хорошо. Время поднять его на ступеньку выше. Много месяцев назад Джейсон Дин познакомил меня с API ComicVine . Это бесплатный API, который предоставляет доступ к их довольно обширной базе данных комиксов. К сожалению, их API не очень хорошо поддерживается, и в документации отсутствуют некоторые важные детали. Но я смог взять их службу и построить следующее.

<!DOCTYPE html>
<html>
<head>
	<title>Comic Character Searcher</title>
	<script src="js/handlebars-1.0.0.beta.6.js"></script>
	<script id="result-template" type="text/x-handlebars-template">
	<h2>Results</h2>
	<p>
	Your search returned {{number_of_total_results}} result(s).
	</p>

	{{#each results}}
	<div class="result">
	<h3>{{name}}</h3>
	<p>{{{leftTrim description}}}</p>
	<a href="{{site_detail_url}}">
	{{#if image.super_url}}
	<img src="{{image.super_url}}">
	{{else}}
	<img src="generic.png">
	{{/if}}
	</a>
	</div>
	{{/each}}
	</script>
    <link rel="stylesheet" href="style.css" type="text/css" />
</head>

<body>

	Comic Character Search: 
	<input type="text" id="search" autofocus> <i>Results credit ComicVine.com</i>

	<div id="resultDiv"></div>

	<script>
	var baseURL = "http://api.comicvine.com/search/?api_key=4da2671a38f182f28110923ac684980d9658628a&format=jsonp&json_callback=handleResponse&resources=character&field_list=image,site_detail_url,name,description";

	var template;
	var resultDiv = document.querySelector("#resultDiv");

	//Custom helper to trim and remove html as well
	Handlebars.registerHelper('leftTrim', function(text) {
		text = text.replace(/<.*?>/g," ").trim();
		if(text.length > 100) return text.substring(0,100) +"...";
		else return text;
	});

	document.addEventListener("DOMContentLoaded", function() {
		console.log("Business Time");

		var source = document.querySelector("#result-template").innerHTML;
		template = Handlebars.compile(source);

		document.querySelector("#search").addEventListener("keyup", function() {
			var text = this.value.trim();
			if(text.length <= 3) return;

			var reqURL = baseURL + "&query="+escape(text);
			//Credit: http://stackoverflow.com/a/9649610/52160
			var script = document.createElement('script');
			script.src = reqURL;
			document.getElementsByTagName('head')[0].appendChild(script);

		});
	});

	function handleResponse(resp) {
		//console.dir(resp);
		if(resp.error && resp.error == "OK") {
			var html = template(resp);
			resultDiv.innerHTML = html;
		}
	}
	</script>

</body>
</html>

 

Это приложение использует JSON / P и ComicVine API, чтобы вы могли осуществлять поиск по базе данных персонажей. Хорошая строка поиска — «паук». Очевидно, там нет всего , но интересно посмотреть, что там. Ах да — обязательно поищите «Бейондер» — лучшее, что выйдет из Marvel в 80-х годах. Вы можете продемонстрировать это здесь: