Работаем с jquery templates

Микрошаблоны

Микрошаблоны (англ. microtemplate) мы уже видели на примере .


Это HTML со вставками переменных и произвольным JS.

Пример:

Шаблонная система компилирует этот код в JavaScript-функцию с минимальными модификациями, и она уже, запустившись с данными, генерирует результат.

Достоинства и недостатки такого подхода:

Недостатки

  • Жёстко привязан к языку JavaScript.
  • При ошибке в шаблоне приходится лезть внутрь «страшной» функции

Достоинства

  • Простая и быстрая шаблонная система
  • Внутри JS-функции доступен полноценный браузерный отладчик, функция хоть и страшна, но понятна.

Включение произвольного JS-кода в шаблон, в теории, позволяет делать в нём всё, что угодно. Но обратная сторона медали – шаблон вместо внятного HTML может стать адским нагромождением разделителей вперемешку с вычислениями. Что рекомендуется делать в шаблонах, а что нет?

Можно разделить код на два типа с точки зрения шаблонизации:

  • Бизнес-логика – код, формирующий данные, основной код приложения.
  • Презентационная логика – код, описывающий, как показываются данные.

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

В шаблонах допустима лишь презентационная логика.

Зачастую, нужно использовать один и тот же шаблон и в браузере и на сервере.

Например, серверный код генерирует HTML со списком сообщений, а JavaScript на клиенте добавляет к нему новые по мере появления.

…Но как использовать на сервере шаблон с JavaScript, если его основной язык – PHP, Ruby, Java?

Эту проблему можно обойти. На сервер, использующем PHP, Ruby, Java или какой-то другой язык, дополнительно ставится виртуальная машина V8 и настраивается интеграция с ней. Почти все платформы это умеют.

После этого становится возможным запускать JavaScript-шаблоны и передавать им данные в виде объектов, массивов и так далее.

Этот подход может показаться искусственным, но на самом деле он вполне жизнеспособен и используется в ряде крупных проектов.

Эта шаблонка и большинство других систем, которые мы рассмотрим далее, допускают прекомпиляцию.


То есть, можно заранее, до выкладывания сайта на «боевой сервер», обработать шаблоны, создать из них JS-функции, объединить их в единый файл и далее, в «боевом окружении» использовать уже их.

Современные системы сборки (brunch, grunt с плагинами и другие) позволяют делать это удобно, а также хранить шаблоны в разных файлах, каждый – в нужной директории с JS-кодом для виджета.

Основы синтаксиса: переменные, условия, циклы

Перейдём сразу к практике и посмотрим, как выглядит шаблон, взяв для примера немного упрощенную версию HTML-кода сайта webew.ru:

<html><head>     /* Многострочные комментарии — как в C или PHP */         <title>{*title*}</title>         <base href=»{*=BASEHREF*}»> /* константа */         /* условные конструкции: */         {?*keywords*}         <meta name=»keywords» content=»{*keywords*}»>     {?}         {?*description*}         <meta name=»description» content=»{*description*}»>     {?}         /* условие с негативной частью */     <link rel=»stylesheet» href=» {?*default_css*} default.css {?!} special.css {?} «>  </head><body>     <div id=»logo»>         <a href=»»><img src=»{*logo.image*}» alt=»{*logo.alt*}»></a>     </div>     <div id=»menu»>                 /* цикл: */                 {%*menu*}             <a href=»{*menu:url*}»>{*menu:title*}</a>         {%}         </div>         <div id=»content»>         {*content*}     </div>         <div id=»footer»>         webew.ru &copy; {*year*}     </div></body></html>  

А вот соответствующий код PHP:

ini_set(‘pcre.backtrack_limit’, 1024*1024); // (см. ниже)$DATA’title’ = ‘Webew: теория и практика веб-технологий ‘;define(‘BASEHREF’, ‘http://webew.ru/’);$DATA’logo’ = array(     ‘image’ => ‘i/logo.gif’,     ‘alt’ => ‘Логотип webew.ru’     );$DATA’menu’ = array(     array(‘url’ => ‘css’, ‘title’ => ‘CSS’),     array(‘url’ => ‘php’, ‘title’ => ‘PHP’),     array(‘url’ => ‘seo’, ‘title’ => ‘Интернет-маркетинг’),     array(‘url’ => ‘c’, ‘title’ => ‘C/C++’)     );$DATA’content’ = ‘Приветствуем вас на webew.ru!’;require_once ‘websun.php’; // подключаем файл с шаблонизатором$tpl = ‘templates/main.tpl’; // путь к шаблону$html = websun_parse_template_path($DATA, $tpl); // запуск шаблонизатораecho $html; // получили обработанный шаблон, отдаем клиенту результат  

Несмотря на то, что переменные $DATA’keywords’ и $DATA’description’ не установлены, при обработке шаблона не возникнет никаких ошибок или предупреждений.

Условная конструкция вида {?*keywords*} что-то {?} означает «вставить что-то, если в переменной, переданной шаблону (в данном случае $DATA) присутствует элемент keywords и при этом он не является пустой строкой, нулём, FALSE, NULL или пустым массивом». Соответственно, конструкция {?!*keywords*} … {?} срабатывает, если какое-нибудь из этих условий не выполняется.

Шаблонизатор не генерирует ошибок или предупреждений в том случае, если какой-либо из запрошенных переменных или констант вообще не существует (вместо них молчаливо будет вставлена пустая строка) поэтому формат передаваемых данных может быть нестрогим.

В цикле ключи массива указываются через двоеточие — {*menu:title*}, а вне цикла через точку — {*logo.image*}.

Можно также обращаться к переменным глобальной области видимости, в т.ч. суперглобальным массивам. Для этого перед именем переменной нужно поставить знак доллара. Например, подстановка в шаблон переменной $_GET’foo’ выглядит так: {*$_GET.foo*}.

Свой язык

Для того, чтобы сделать шаблон ещё короче, а также с целью «отвязать» их от JavaScript, ряд шаблонных систем предлагают свой язык.

Например:

  • Mustache
  • Handlebars
  • Closure Templates
  • …тысячи их…

Шаблон для меню в Handlerbars, к примеру, будет выглядеть так:

Как видно, вместо JavaScript-конструкций здесь используются хелперы. В примере выше – «блочный» хелпер: он показывает своё содержимое для каждого элемента и является альтернативой .

Есть и другие встроенные в шаблонизатор хелперы, можно легко делать свои.

Использование такого шаблона:

Библиотека шаблонизации Handlebars «понимает» этот язык. Вызов принимает строку шаблона, разбивает по разделителям и, аналогично предыдущему виду шаблонов, делает JavaScript-функцию, которая затем по данным выдаёт строку-результат.

Если «свой язык шаблонизатора» очень прост, то библиотеку для его поддержки можно легко написать под PHP, Ruby, Java и других языках, которые тем самым научатся понимать такие шаблоны.

Если шаблонка действительна нацелена на кросс-платформенность, то явные JS-вызовы в ней запрещены. Всё делается через хелперы.

Если же нужна какая-то логика, то она либо выносится во внешний код, либо делается через новый хелпер – он отдельно пишется на JavaScript (для клиента) и для сервера (на его языке). Получается полная совместимость.

Это создаёт определённые сложности. Например, в Handlebars есть хелпер , который выводит содержимое, если истинно условие . При этом вместо нельзя поставить, к примеру, или вызов , будет ошибка. Все вычисления должны быть сделаны на этапе передачи данных в шаблон.

Так сделано как раз для переносимости шаблонной системы на другие языки, но на практике не очень-то удобно.

Продвинутые кросс-платформенные шаблонизаторы, в частности, Closure Templates, обладают более мощным языком и умеют самостоятельно разбирать и компилировать многие выражения.

Экранирование значений


Что делать, если в SQL запрос требуется подставить строковое значение? Например, на сайте есть возможность поиска города по его названию. Форма поиска передаст поисковый запрос в GET-параметр, а мы используем его в SQL-запросе:

Но если в параметре будет символ кавычки, то смысл запроса можно кардинально изменить. Передав в search_text значение , мы выполним запрос, что выведет список всех городов:

Смысл запроса поменялся, потому что кавычка из параметра запроса считается управляющим символом: MySQL определяет окончание значение по символу кавычки после него, поэтому сами значения кавычки содержать не должны. Очевидно, приведение к числовому типу не подходит для строковых значений. Поэтому, чтобы обезопасить строковое значение, используют операцию экранирования.

Экранирование добавляет в строке перед кавычками (и другими спецсимволами) знак обратного слэша . Такая обработка лишает кавычки их статуса — они больше не определяют конец значения и не могут повлиять на логику SQL-выражения.

За экранирование значений отвечает функция . Этот код обработает значение из параметра, сделав его безопасным для использования в запросе:

Термины шаблонизации

В разговоре о шаблонизации очень важно придерживаться определённых терминов, чтобы всегда было понимание, о чём идёт речь. Договоримся использовать следующую терминологию:. Лейаут — это шаблон, который содержит HTML-код, общий для всех страниц сайта

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

Лейаут — это шаблон, который содержит HTML-код, общий для всех страниц сайта. В нём могут содержаться подключение стилей, мета-теги, шапка, подвал. Также лейаут содержит область для вставки уникального содержимого каждой страницы.

Шаблон страницы — это шаблон с уникальным для одной страницы HTML-кодом. Например, для главной страницы там может быть список новостей. Также шаблон страницы может включать в себя блоки.

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

Кодогенерация

Вам может потребоваться создавать JavaScript в рантайме изнутри backend-а. Зачем? Для создания отчетов на стороне браузера, например. Или получить скрипт на F# изнутри программы на Go. Или Kotlin-овский код изнутри ReactJS (не могу представить, зачем это может понадобится, но вдруг у вас такие специфические наклонности).

В случае с кодогенерацией, лучше сначала написать руками результирующий код (то что мы хотим сгенерировать) а только потом разбить его на шаблон и модель. Этот подход избавит нас от тоски излишней сложности модели. Модель усложнить никогда не поздно, но лучше начать с простого.

Здесь мы видим, что у нас на странице есть от одного до N графиков lineChart, у каждого из которого свой источник данных, заголовок и список показателей. Моделька:

ну и шаблон:

Обратите внимание: такой «в лоб» подход к шаблонизации требует отдельного усилия по экранированию значений в модельке. если в series.title у нас прокрадется запятая или кавычка — «Hello Kitty\»» — синтаксиc результирующего файла с треском развалится

Поэтому пишите функции экранирования и используйте их при создании моделей. Используйте форматтеры, если шаблонизатор это умеет.

Третий кубик полетел в дверь и со стуком отскочил. Тоже никуда не годится. Интересно. а можно кинуть кубик так, чтобы он проскочил под дверью и долетел до конца коридора? Можно ли 3д-печатать резиной? Или лучше сделать его наполненным маленькими такими икосаэдрами, наполненными воздухом?…

Формы¶

Формы — это часть языка HTML. Формы нужны для передачи данных от клиента на сервер. Чаще всего формы используются для регистрации пользователей, заполнения анкет, оформления заказа в интернет магазине, и так далее.

Через формы можно отправлять как простую текстовую информацию, так и файлы.

Большую часть времени программирования на PHP вы будете так или иначе работать с формами и данными из них.

HTML описывает то, из каких элементов состоит форма, и как она выглядит. Но без принимающей стороны, то есть сервера, который принимает эти данные и обрабатывает их нужным образом, создавать формы нет никакого смысла.

PHP содержит множество средств для работы с формами. Это позволяет очень просто решать типичные задачи, которые часто возникают в веб-программировании:


Практически любой современный сайт содержит как минимум несколько разных HTML-форм.

Composer: пакетный менеджер для PHP¶

В PHP для управления библиотеками используют пакетный менеджер под названием Composer. Это мощный и удобный инструмент, который позволит навсегда забыть про головную боль, связанную с поиском, установкой и разрешением зависимостей у библиотек.

Как начать работу с Composer

  • Скачать Composer;
  • Инициализировать его в проекте;
  • Подключить файл автозагрузки в нужный сценарии;
  • Установить нужную библиотеку.

Установка

Скачате Composer для Windows. Это обычный установочный файл с режимом «мастера», который проведёт вас по всему процессу установки. В конце можно будет проверить его работу, открыв командную строку. Если выполнить команду , то вы увидите длинный перечень его возможностей.

Инициализация в проекте

Продолжим работу с командной строкой. Сначала перейдём в рабочую папку проекта (если вы установили OpenServer в стандартную папку, то, например, так: ). Теперь выполним последовательно команды и . На этом инициализация закончена. Можно заметить, что в проекте появилась новая папка с именем .

Подключение сценария автозагрузки

Composer упрощает не только установку библиотек, но и их использование. Он берёт на себя подключение всех необходимых файлов классов библиотеки. За это отвечает специальный сценарий . Сценарий — единственный файл, который необходимо подключить для использования любых библиотек.

использует механизм «автозагрузки». Он перехватывет обращение к классам библиотек и подключает все необходимые сценарии «на лету». Чтобы это всё работало подключите в вашем сценарии:

Установка библиотеки из Composer

Composer скачивает и устанавливает библиотеки по их имени. Это означает, что сначала нужно «нагуглить» нужную библиотеку, перейти на её сайт, и найти там в описании её имя. Например, название библиотеки может быть таким:

Теперь мы можем попросить composer установить библиотеку. Для этого введите команду . Composer загрузит и установит библиотеку в папку . Останется подключить установленную библиотеку в сценарии и можно её использовать.

Подключение библиотеки в сценариях

Рассмотрим подключения и использования на примере библиотеки для валидации форм — GUMP. Установим её командой: .

Теперь подключим библиотеку в сценарии, где происходит валидация формы:

Сначала мы подключаем универсальный файл автозагрузки, который отвечает за подключение классов библиотеки: .

Затем создаём новый объект валидатора и вызываем его методы для передачи правил валидации и проверки формы. На этом всё.

Итого

Шаблоны полезны для того, чтобы отделить HTML от кода. Это упрощает разработку и поддержку.

В этой главе подробно разобрана система шаблонизации из библиотеки LoDash:

  • Шаблон – это строка со специальными вставками кода или переменных , .
  • Вызов превращает шаблон в функцию, которой в дальнейшем передаются данные – и она генерирует HTML с ними.

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

Шаблонных систем много. Многие основаны на схожем принципе – генерации функции из строки, например:

  • EJS
  • Jade
  • Handlebars

Есть и альтернативный подход – шаблонная система получает «образец» DOM-узла и клонирует его вызовом , каждый раз изменяя что-то внутри. В отличие от подхода, описанного выше, это будет работать не с произвольной строкой текста, а только и именно с DOM-узлами. Но в некоторых ситуациях у него есть преимущество.

Такой подход используется во фреймворках:

  • AngularJS
  • Knockout.JS

С этим читают