Статьи

Начало работы с FigDice

Среди множества шаблонных систем большинство работает почти одинаково; переменные «внедряются» с использованием какого-либо синтаксиса, будь то фигурные скобки, процентные знаки или что-то еще в соответствии с соглашением библиотеки. Обычно они имеют базовые управляющие структуры, такие как if...then и, конечно, итерация.

FigDice , однако, использует совершенно другой подход. Вдохновленный PHPTAL — предметом будущей статьи — он дает слою представления ответственность за «извлечение» необходимых данных вместо того, чтобы полагаться на контроллеры для сборки и «проталкивания» их в шаблоны.

Плоды инжира

В этой серии из двух частей я собираюсь более подробно взглянуть на нее, на то, как она работает и как ее использовать.

Установка

Вы можете получить код с сайта , Github или, еще лучше, Composer:

 "figdice/figdice": "dev-master" 

Библиотека также доступна как .phar ; Вы можете скачать последнюю версию (прямая ссылка) или сгенерировать ее самостоятельно, используя figdice-make-phar.php , доступный в репозитории Github .

Основное использование

Давайте сначала посмотрим на FigDice в его самом базовом виде — создание и рендеринг вида.

Для начала создайте новый экземпляр представления:

 $view = new \figdice\View(); 

Очевидно, вам необходимо убедиться, что библиотека доступна — использование Composer обеспечивает подходящий автозагрузчик.

Далее необходимо загрузить соответствующий шаблон относительно текущего пути :

 $view->loadFile( '../templates/home.html' ); 

Чтобы отобразить шаблон, вызовите render() :

 $view->render(); // returns the HTML content 

figdice-арка-550

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

Скелет приложение

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

Вы найдете это на Github , и вы можете увидеть это в действии здесь . Обратите внимание, что демо включает в себя функциональность, которую мы добавим позже во второй части.

Создание макета

Первое, на что следует обратить внимание, это то, что FigDice в значительной степени основан на XML. Как таковой, он опирается на несколько пользовательских элементов XML и, что очень важно. требует, чтобы ваши HTML-теги были правильно закрыты.

Давайте начнем с создания простого двухколонного макета страницы.

 <!-- file: layout.html --> <html> <head> <title fig:slot="docTitle" /> <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" /> <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap-theme.min.css" /> </head> <body> <div class="container"> <header class="header"> <fig:include file="menu.html" /> <h3 class="text-muted">FigDice Example</h3> </header> <div class="row"> <div class="col-sm-12 col-md-9 col-lg-9"> <div class="content"> <h1 fig:slot="pageTitle" /> <div fig:slot="pageContent" /> </div> </div> <div class="col-sm-12 col-md-3 col-lg-3"> <fig:include file="tweets.html" /> </div> </div> <footer id="footer"> <fig:include file="footer.html" /> </footer> </div> </body> </html> 

Давайте рассмотрим несколько вещей.

<title fig:slot="docTitle" /> используется для генерации <title> путем определения «слота» для значения, в которое нужно перейти. Мы посмотрим, как эти данные «подключаются» к слоту в ближайшее время.

Обратите внимание, как закрываются теги <link> . Это очень важно; Поскольку FigDice широко использует XML, он должен соответствующим образом проверяться.

<fig:include file="menu.html" /> не требует пояснений — FigDice позволяет легко разбить ваши шаблоны на более мелкие файлы шаблонов. Мы делаем то же самое для footer.html колонтитула — footer.html — и для блока Tweets ( tweets.html ), который мы вскоре tweets.html .

Вот содержимое menu.html :

 <ul class="nav nav-pills pull-right"> <li><a href="/">Home</a></li> <li><a href="/about">About</a></li> </ul> 

И footer.html :

 <p>&copy; 2014 Someone or Other</p> 

Простая домашняя страница

Теперь давайте создадим домашнюю страницу для нашего примера приложения. В новом файле с именем index.html :

 <xml fig:mute="true"> <!-- Mute because this tag should not end up in the HTML document. But the FigDice template must have an XML root node. --> <!-- Load the page layout --> <fig:include file="layout.html" /> <!-- Set the <title> tag --> <title fig:plug="docTitle">Sample application homepage</title> <!-- Set the <h1> tag --> <h1 fig:plug="pageTitle">Homepage</h1> <!-- "Plug in" the page content --> <div fig:plug="pageContent">Lorem ipsum...</div> </xml> 

На этот раз наш шаблон представляет собой чистый XML и содержит еще несколько тегов FigDice.

Обратите внимание, что открывающий <xml> имеет атрибут fig:mute , который имеет значение true. Как отмечают комментарии, этот атрибут говорит FigDice не включать этот элемент в окончательный HTML.

<fig:include file="layout.html" /> сообщает FigDice о макете, который мы создали минуту назад. Однако это не включает файл так же, как мог бы include PHP; вот где входят слоты и заглушки .

<div fig:plug="pageContent">Lorem ipsum...</div> указывает, что мы должны «вставить» контент в «слот» под названием pageContent , который, как вы помните, мы создали в layout.html .

Наконец, давайте определим действительно простой маршрут для отображения страницы:

 $app->get('/', function () use ($view) { $view->loadFile( '../templates/home.html' ); return $view->render(); }); 

Работа с данными

В традиционном подходе MVC контроллер извлекает, собирает и затем «вводит» данные в представления. Подразумевается, что это означает, что контроллер должен знать, какие данные требуются и какие представления им интересны.

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

Для этого FigDice использует каналы . Фид — это класс, который расширяет figdice\Feed и должен содержать метод run() для возврата соответствующих данных.

Чтобы продемонстрировать это, давайте создадим блок, который отображает последние твиты пользователя на каждой странице.

Если вы посмотрите на макет, вы увидите, что мы уже добавили следующую строку, чтобы включить его:

 <fig:include file="tweets.html" /> 

На самом деле, получение твитов из API Twitter довольно просто, но выходит за рамки этой статьи — так что давайте подделать. Вот канал:

 <?php namespace Sitepoint\Feed; use figdice\Feed; class TwitterFeed extends Feed { public function run() { return array( array( 'body' => 'This is an example of a Tweet, though it isn\'t really a Tweet', ), array( 'body' => 'This is another example of a Tweet, though it isn\'t really a Tweet either', ), array( 'body' => 'Using REAL Tweets is left as an example, you see', ), ); } } 

Для простоты мы возвращаем только твиты.

Теперь давайте создадим шаблон, который «извлекает» данные из класса TwitterFeed и отображает их, используя простой неупорядоченный список:

 // file: twitter.html <?xml version="1.0" encoding="utf-8"?> <fig:template xmlns:fig="http://figdice.org/"> <fig:feed class="TwitterFeed" target="tweets" /> <ul> <li fig:walk="tweets" fig:text="body" /> </ul> </fig:template> 

Объявление <fig:feed> указывает, что мы должны создать экземпляр TwitterFeed и сделать его данные доступными с помощью ключевых tweets .

Затем мы создаем простой неупорядоченный список. Каждая итерация <fig:walk> создает элемент <li> когда он «проходит» по данным, присвоенным переменной tweets . Атрибут fig:text указывает, что текстовое содержимое тега <li> должно быть заполнено с использованием body каждого твита.

Вот результат:

 <ul> <li>This is an example of a Tweet, though it isn't really a Tweet</li> <li>This is another example of a Tweet, though it isn't really a Tweet either</li> <li>Using REAL Tweets is left as an example, you see</li> </ul> 

Фабрика

Мы еще не совсем там; для того, чтобы использовать каналы, вам понадобится фабрика . Фабрика должна реализовать \figdice\FeedFactory , которая требует, чтобы она включала метод create отвечающий за создание экземпляра данного класса фида.

Вот пример, который довольно понятен:

 <?php namespace Sitepoint\Factory; use Sitepoint\Feed\TwitterFeed; class FeedFactory implements \figdice\FeedFactory { /** * In this simple example, we did not declare additional * arguments for our factory. You can experiment by yourself. */ public function __construct() { } /** * In this simple example, we did not pass attributes to * the fig:feed invokation. * Had we specify XML attributes (in addition to class and target), * they would be interpreted by the Expression engine, and passed * as the $attribute argument, as key/value pairs. * @see \figdice\FeedFactory::create() */ public function create($className, array $attributes) { if ($className == 'TwitterFeed') { return new TwitterFeed(); } // Explicitly return null when our Factory cannot handle // the requested class, so that more Factories can chain // the lookup. return null; } } 

Делая это таким образом, вместо return new $classname , нам не нужно загрязнять наш код представления информацией о пространстве имен.

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

Наконец, чтобы заставить это работать, вам нужно зарегистрировать его в вашем View:

 $view->registerFeedFactory(new FeedFactory()); 

Если вы перейдете на домашнюю страницу приложения, вы должны увидеть список твитов.

Резюме

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

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