В последнее время я периодически читаю курсы, посвященные технологии XSLT и ее использованию в качестве языка шаблонизатора UMI.CMS. И я всегда начинаю знакомство с XSLT с того, что формулирую основную идею, вынесенную в заглавие этой статьи: мы работаем с сайтом на UMI.CMS как с набором XML-сервисов.
В этой идее содержится вся суть подхода к разработке сайта на UMI.CMS при помощи XSLT-шаблонизатора. Шаблонизатор в этом случае является инструментом для агрегации и для вывода в необходимом нам виде данных, поступающих в формате XML, а XSLT — язык, при помощи которого мы управляем оформлением вывода. В этой статье я хотел бы рассказать об особенностях этого подхода для разработчика сайтов, в том виде, в котором это реализовано в UMI.CMS.
Следующие возможности UMI.CMS лежат в основе реализации этого подхода:
Рассмотрим отдельно каждую «деталь» этого конструктора.
Основной особенностью UMI.CMS является то, что все данные хранятся в виде объектов. Все привычные понятия в системах управления контента, такие как: страницы, пользователи, баннеры, заказы, скидки, адреса доставки товаров, сами товары – все это объекты в UMI.CMS. При этом структура объектов определяется универсальным образом при помощи понятия «типы данных». Типы данных — это шаблоны для создания объектов, которые определяют количество и тип «полей», в которых объекты, созданные по этим шаблонам, могут хранить информацию.
Эта архитектурная особенность обеспечивает единообразие представления всех сущностей системы, которое при использовании формата XML становится еще и чрезвычайно наглядным.
Структуру данных и сами данные для любого объекта системы разработчик может посмотреть непосредственно в окне браузера, сделав запрос по протоколу UObject. Больше не нужно заглядывать в базу данных напрямую.
Для страниц сайта, которые являются особыми объектами с привязкой к структуре сайта, реализована дополнительная надстройка, однако, они также являются объектами, хранящими данные. Структуру данных и сами данные для любой страницы разработчик также может посмотреть непосредственно в окне браузера, сделав запрос по протоколу UPage.
Бизнес-логика UMI.CMS реализуется при помощи API и макросов, которые, по сути своей, являются методами модулей UMI.CMS. Макросов в UMI.CMS достаточно много. Кроме того, любой разработчик всегда может дописать свой собственный макрос или даже целый модуль.
Типичными ситуациями использования макросов являются: построение меню сайта, ленты новостей, списка объектов каталога, формы обратной связи и многое другое.
Точно так же, как с объектами и страницами системы, структуру данных и сами данные, которые возвращают макросы системы, разработчик может посмотреть непосредственно в окне браузера, сделав запрос по протоколу UData.
Иногда перед разработчиком может стоять задача по получение некоторого списка объектов (или страниц) по какому-то заданному критерию. Это может быть какое-либо свойство, заданное пользователем или администратором сайта специально (например, «показывать на главной»), или это может быть любое другое свойство (например, дата публикации). Некоторые подобные возможности уже могут быть реализованы в виде макросов, однако бывают ситуации, когда стандартного функционала не хватает. В этой ситуации можно либо создать собственный макрос, либо воспользоваться еще одним протоколом, позволяющим получить выборку из базы данных – протоколом USel.
Особенностью использования этого протокола является то, что для формирования выборки используются специальные шаблоны в формате XML, описывающие результаты, которые мы хотим получить. Эти шаблоны запросов также могут принимать параметры, что позволяет использовать их достаточно гибко.
Точно так же, структуру данных и сами данные, которые возвращают запросы к базе данных системы, разработчик может посмотреть непосредственно в окне браузера, сделав запрос по протколу USel.
Подход к сайту как к набору XML-сервисов гарантирует то, что мы можем получить любые данные из системы в виде XML. Как уже говорилось выше, при помощи шаблонизатора мы можем собрать эти данные нужным образом, оформить их как это необходимо и вывести на страницу сайта.
Однако с точки зрения шаблонизатора неважно, откуда поступают эти данные: запрос происходит по протоколам, то есть, по сути, данные и так приходят извне. Поэтому логично предположить, что можно точно так же подключить данные из каких-либо внешних XML-источников, таких как сторонние RSS-ленты, курсы валют, поисковые результаты, другие сайты на UMI.CMS и так далее.
Эти и другие результаты из внешних источников можно получить по протоколу UHttp.
Иногда может возникнуть необходимость сгенерировать и отдать данные в формате XML наружу. Например, это может быть необходимо при подключении плагинов с использованием Ajax или Adobe Flash, для создания нестандартной RSS-ленты, генерации Google sitemap либо еще для каких-нибудь целей.
Для этих задач существует возможность назначить альтернативную адресацию — некоторые страницы сайта (или набор страниц, объединенный по какому-либо критерию), будут отдавать XML-данные, сформированные на основании шаблонов, созданных разработчиком. В эти шаблоны он может включить любые данные из всех вышеописанных протоколов, преобразовать их так, как это ему необходимо и отдать наружу именно в том виде, в каком требуется.
Дело в том, что в тот момент, когда запрашивается страница из браузера, система также генерирует XML-документ. Этот XML-документ содержит все данные об открываемой странице (поля и хранящуюся в них информацию), а также дополнительные сведения о положении в иерархии сайта, пользователе, открывшем эту страницу и некоторые другие сведения.
Для того, чтобы отдать HTML-код в браузер и показать страницу пользователю, к этому XML-документу применяется XSL-шаблон, который и определяет то, как должен выглядеть HTML-код, построенный с учетом данных из исходного XML-документа.
Этот XML-документ также можно посмотреть непосредственно в браузере, добавив к адресу страницы ".xml". То есть разработчик всегда может узнать точно, к чему именно применяется шаблон.
Однако информация, хранящаяся в запрошенной странице, относится только к этой странице: например, ее контент, заголовок или описание. Эта страница «ничего не знает» о том, должно ли в итоге выводиться на ней меню, лента новостей, блок с товарами или что-то иное. Для того, чтобы вывести эти данные, мы должны получить их у системы, запросив дополнительные XML-документы — такие как, например, результаты работы макросов, выборки из базы данных, свойства других страниц и все что можно получить по протоколам системы.
Рисунок 1: страница сайта на UMI.CMS
Чтобы подключать эти XML-данные для вывода их в HTML-код, используются все те же XSL-шаблоны для страниц сайта. В шаблонах используется всего одна функция XSLT — функция document(), которой разработчик указывает XML-ресурсы, расположенные по адресу имя_протокола://набор_параметров. Например:
Таким образом, на любой странице сайта можно выводить не только ее контент или иные ее свойства, а любые данные, которые могут быть получены по протоколам. Разработчик в шаблонах сам определяет, что именно будет на определенных страницах сайта, в соответствии со своими задачами.
Чтобы правильно написать XSLT-шаблоны, разработчик может вызывать в окне браузера исходные данные, не обращаясь в документацию, работая непосредственно с той информацией, которую он хочет обрабатывать в шаблонах. Например, чтобы посмотреть результат, который вернет макрос, выводящий меню, достаточно набрать в адресной строке: http://адрес_сайта/udata/content/menu
И разработчик увидит xml-представление для меню сайта в виде списка страниц с идентификаторами, названием и реальным порядком, определяемым структурой сайта:
<udata module="content" method="menu" generation-time="0.006117">
<items>
<item id="1" link="/" xlink:href="upage://1">Добро пожаловать</item>
<item id="2" link="/talks/" xlink:href="upage://2">Форум</item>
<item id="12" link="/vse_novosti/" xlink:href="upage://12">Все новости</item>
<item id="33" link="/butterfly/" xlink:href="upage://33">Фотогалерея</item>
<item id="43" link="/market/" xlink:href="upage://43" status="active">Каталог товаров</item>
</items>
</udata>
Таким образом, написание шаблонов не представляет сложности и практически исключает необходимость отладки.
Грамотное использование этого подхода позволяет очень быстро накопить набор готовых решений (для оформления отдельных блоков на страницах сайта или даже для целых страниц целиком), которые в дальнейшем можно использовать из проекта в проект, лишь меняя стили CSS и основные шаблоны внешнего вида страниц.
Одним из недостатков этого подхода можно назвать необходимость совершать дополнительные запросы, что может отнимать ресурсы и увеличивать время, необходимое для генерации страниц. Это может быть особенно актуально, если обращаться к внешним данным, а не к данным из системы.
Именно для таких случаев в UMI.CMS добавлена возможность использовать кеширование для запросов по протоколам. В этой ситуации система не будет совершать реальных вызовов, а будет брать данные из кеша практически мгновенно, значительно экономя использование ресурсов.
Вторым недостатком можно назвать реальный «соблазн» попытаться воплотить бизнес-логику непосредственно в шаблонах. В этой ситуации, скорее всего, результатом будет потеря производительности, масштабируемости и возможности повторного использования шаблонов в других проектах. К счастью, язык XSLT не вполне подходит для подобного использования и закономерные трудности, возникающие на этом пути, обычно помогают понять, что происходит что-то не то.
Реализация подхода к сайту как набору XML-сервисов в UMI.CMS использует универсальный способ представления, получения данных и вывода их на итоговую страницу сайта. Кроме того, разработчику предоставлена возможность в любой момент получить наглядное представление тех данных, с которыми он работает.
Расширяя стандартный функционал системы при помощи пользовательских макросов и используя шаблонизатор для агрегации и вывода информации, разработчик получает в свое распоряжение практически ничем не ограниченную свободу в управлении как логикой системы, так и выводом данных.