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