- PVSM.RU - https://www.pvsm.ru -

Введение в JadePHP

По предложению автора интересностей и полезностей для веб-разработчика #17 [1], предлагаю свой перевод статьи Introduction to JadePHP [2].

Существуют десятки [3] шаблонизаторов. Среди наиболее известных можно выделить Smarty [4], Twig [5] (используется в следующей версии Drupal), Blade (используется по умолчанию в Laravel) и, конечно же, vanilla PHP. Если не говорить конкретно о PHP, то для eRuby / ERB [6] и Haml [7] для Ruby / Ruby on Rails и Javascript есть ряд популярных вариантов, как например Mustache [8], Handlebars [9], Hogan [10] и EJS [11]. У одних различия в синтаксисе незначительные, у других они более выраженные.

Шаблонизатор Jade [12], который значительно отличяется от других, обычно ассоциируется с JavaScript приложениями, например он поддерживается в Express для Node.js. В этой статье, я поговорю о Jade или, более конкретно, о Jade сделанной для PHP — JadePHP [13].

Haml и Jade

Было бы неправильно говорить о Jade, не упомянув Haml, который был вдохновляющей идеей для Jade. И в самом деле, существуют несколько библиотек [14] для поддержки Haml в PHP. Jade придерживается той же философии что и HAML, то есть создание «красивых» шаблонов и то что авторы называют шаблонизацией «хайку». Что бы это не значило, у Haml и Jade есть некоторые одинаковые качества, которые фундаментально отличают их от большинства других шаблонизаторов.

В чем разница?

Большинство шаблонизаторов предполагают написание конечной разметки с «внедрением» в нее placeholder'ов а и основной логики. У Jade же есть не только placeholder'ы и логика, но и способ для сокращенного написания XML подобных элементов. В общем, это означает HTML, хотя вы можете использовать это для RSS и собственно XML.

В сущности, если вы хотите, то вы можете использовать Jade как сокращения для HTML без его «традиционных» шаблонизаторских возможностей.

Как использовать репозиторий

К сожалению, в настоящий момент код недоступен через Composer [15], хотя его не трудно запаковать, если у кого-то найдется час другой. Но вы можете его запустить, клонировав репозиторий и включив autoload.php.dist (Github репозиторий включает UniversalClassLoader из Symphony).

Ниже, адаптированый пример из README проекта. Предполагается, что репозиторий был помещен в директорию jade.

use EverzetJadeDumperPHPDumper,
        EverzetJadeVisitorAutotagsVisitor,
        EverzetJadeFilterJavaScriptFilter,
        EverzetJadeFilterCDATAFilter,
        EverzetJadeFilterPHPFilter,
        EverzetJadeFilterCSSFilter,
        EverzetJadeParser,
        EverzetJadeLexerLexer,
        EverzetJadeJade;

$dumper = new PHPDumper();
$dumper->registerVisitor('tag', new AutotagsVisitor());
$dumper->registerFilter('javascript', new JavaScriptFilter());
$dumper->registerFilter('cdata', new CDATAFilter());
$dumper->registerFilter('php', new PHPFilter());
$dumper->registerFilter('style', new CSSFilter());

// Initialize parser & Jade
$parser = new Parser(new Lexer());
$jade   = new Jade($parser, $dumper);

$template = __DIR__ . '/template.jade';

// Parse a template (both string & file containers)
echo $jade->render($template);

Этот код скомпилирует файл tempalte.jade и покажет его содержимое.

То где это можно применить, зависит от вашего рабочего процесса, например, используете ли вы framework и т.д. К примеру, можно было бы использовать сервис вроде Watchman [16], Guard [17] или Resource Watcher [18], чтобы следить за файловой системой и изменениями в ваших Jade шаблонах, и компилировать их в определенное время в процессе разработки.

Простой пример

Рассмотрим простой пример, который отобразит полную HTML страницу с двумя переменными, пока без логики.

!!! 5
html(lang="en-us")

  meta(charset="utf-8")
  meta(http-equiv="X-UA-Compatible", content="IE=Edge;chrome=1")

  title(dir="ltr")= pageTitle

  meta(name="viewport", content="width=device-width, initial-scale=1.0")

  link(rel="stylesheet", media="screen", href="/css/styles.css")

  body
  header
  h1 My Jade Application
  div#content
  div.inner
      =$bodyContent

  script(data-main="js/main.js", src="js/libs/require.js")

Важно: нужно использовать два пробела для отступа. На данный момент это единственный метод понятный Jade PHP. Иначе возникнут ошибки или это будет некорректная разметка.

Сразу становится очевидным, Jade довольно отличается от привычного HTML. Во-первых, у него нет угловых скобок < > и закрывающих тэгов. А также нет фигурных скобок, двойных фигурных скобок или других общепринятых способов для обозначения переменных в шаблонах. (Тем не менее вы можете использовать синтаксис с двойными фигурными скобками. Но это не является частью Jade).

Jade выглядит как очень сжатый метод для генерирации разметки. Посмотрим на итоговый HTML:

<!DOCTYPE html>
<html lang="en-us">
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=Edge;chrome=1" />
    <title dir="ltr"><?php echo pageTitle ?></title>
    <meta name="viewport" content="width=device-width" initial-scale="1.0" />
    <link rel="stylesheet" media="screen" href="/css/styles.css" />
    <body>
        <header>
            <h1>My Jade Application</h1>
        </header>
        <div id="content">
            <div class="inner">
                <?php echo $bodyContent ?>
            </div>
        </div>
        <script data-main="js/main.js" src="js/libs/require.js"></script>
    </body>
</html>

Пройдемся по всем ключевым строкам в шаблоне Jade, для того чтобы понять, как работают HTML сокращения.

!!! 5 — сокращение для HTML5 doctype. Это единственное место, где вы увидите тройной восклицательный знак в синтаксисе. Вы также можете использоывать !!! xml, чтобы получить <?xml version="1.0" encoding="utf-8" ?>. Для transitional, вы можете использовать !!! transitional чтобы получить <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">. По умолчанию !!! default даст <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

Примечание: в последней версии Jade, приправленной JavaScript, объявление !!! 5 было изменено на doctype html. Возможно, JadePHP последует этому примеру, хотя наверное врядли, судя по отсутсвию активности на Github.

HTML тэг указывается по одному его имени, без необходимости его закрытия. Например:

body
  header

… если бы вы остановились на этом, привело бы к следующему результату:

<body>
  <header></header>
</body>

Заметьте, как структура документа представлена с отступами.

Вы можете поместить содержимое тэга после его имени с пробелами:

h1 My Jade Application

… становится

<h1>My Jade Application</h1>

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

p 
  | Curabitur blandit tempus porttitor. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. 
  | Aenean eu leo quam. 
  | Pellentesque ornare sem lacinia quam venenatis vestibulum.

Это скомпилируется в:

<p>Curabitur blandit tempus porttitor. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum.</p>

Вы можете использовать формат схожий с CSS селекторами для добавления id и class атрибутов в HTML элементы:

div#content
  div.inner

… приводит к:

  <div id="content">
    <div class="inner">

Другие атрибуты как src, href, lang, media, и т.д. могут быть указаны, используя круглые скобки:

html(lang="en-us") === <html lang="en-us">
link(rel="stylesheet", media="screen", href="/css/styles.css") === <link rel="stylesheet" media="screen" href="/css/styles.css" />

Знак равно используется для подстановки переменных. Как видно выше, когда вы компилируете Jade шаблон, он конвертирует:

= $pageTitle

в следующее:

<?php echo $pageTitle ?>

Добавляем немного логики

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

header
    h1= $pageTitle
    - if ($loggedIn):
    p.greeting Welcome back!
    - else:
    a(href="/login") Please login
    - endif;

Если скомпилировать этот шаблон, в результате получится следующее:

<header>
    <h1><?php echo $pageTitle ?></h1>
    <?php if ($loggedIn) ?>
    <p class="greeting">Welcome back!</p>
    <?php else ?>
    <a href="/login">Please login</a>
    <?php endif ?>
</header>

Для циклов код очень схожий:

ul
  - foreach ($items as $item):
  li= $item

Фильтры

У JadePHP есть возможность использовать фильтры для обработки блоков текста разными способами. Например:

:php
    | $value = 10;
    | $computed_value += 100;
    | print $computed_value;

…будет преобразован в:

<?php
    $value = 10;
    $computed_value += 100;
    print $computed_value;
?>

Вероятно более полезные фильтры будут для JavaScript и CSS. Например:

:style
| body {
|   background: yellow;
| }

…будет преобразован в:

<style type="text/css">
body {
  background: yellow;
}

Устанавливаются эти фильтры следующим образом (смотри пример с кодом выше для понимания контекста этих объявлений):

$dumper->registerFilter('javascript', new JavaScriptFilter()); 
$dumper->registerFilter('php', new PHPFilter());
$dumper->registerFilter('style', new CSSFilter());

Первый аргумент — это текст, который вы размечаете в своем шаблоне с добавлением двоеточия. Для примера выше вы можете использовать :javascript, :php и :style соответственно.

Если включить EverzetJadeFilterFilterInterface, то вы даже можете определять свои собственные фильтры.

Зачем использовать Jade?

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

Метод сокращения Jade не для всех. Одни люди будут утверждать что его легче читать, а другие страстно с этим не согласятся. Но если вы считаете что это достойный метод, то это уже хороший повод его выбрать.

Другая причина, по которой вы можете решить использовать Jade (кстати говоря о количестве шаблонизаторов) — это чередование между технологиями. Если вы часто переключаетесь между, скажем, Node.js и PHP, то существует некоторая логика для поддержания постоянства. Зачем изучать один инструмент, а затем использовать что-то совершенно другое, если он доступен для многих языков?

Резюме

В этой статье я рассмотрел JadePHP, портированный шаблонизатор Jade, изначально ориентированный на JavaScript. Я дал вам несколько наводок на то, как его использовать, и идей о том, зачем он вам может понадобится. Попробуете ли вы его, или он кажется вам необоснованно сжатым? Напишите что вы о нем думаете в комментариях.

Автор: kgbalien

Источник [19]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/news/60937

Ссылки в тексте:

[1] интересностей и полезностей для веб-разработчика #17: http://habrahabr.ru/post/220975/

[2] Introduction to JadePHP: http://www.sitepoint.com/introduction-jadephp/

[3] десятки: http://en.wikipedia.org/wiki/Comparison_of_web_template_engines

[4] Smarty: http://www.smarty.net/

[5] Twig: http://twig.sensiolabs.org/

[6] eRuby / ERB: http://en.wikipedia.org/wiki/ERuby

[7] Haml: http://haml.info/

[8] Mustache: http://mustache.github.io/

[9] Handlebars: http://handlebarsjs.com/

[10] Hogan: http://twitter.github.io/hogan.js/

[11] EJS: http://embeddedjs.com/

[12] Jade: http://jade-lang.com/

[13] JadePHP: https://github.com/everzet/jade.php

[14] существуют несколько библиотек: https://code.google.com/p/phamlp/

[15] в настоящий момент код недоступен через Composer: https://github.com/everzet/jade.php/issues/8

[16] Watchman: https://github.com/facebook/watchman

[17] Guard: https://github.com/guard/guard

[18] Resource Watcher: https://github.com/jasonlewis/resource-watcher

[19] Источник: http://habrahabr.ru/post/224391/