Правильный ответ — да, легко!
Практически всегда описывая устройство CleverStyle CMS у кого-то возникал вопрос, а как же настраивать внешний вид, ведь нет никаких шаблонов.
Нужно признаться, я немного лукавил, говоря что внешний вид можно изменить с помощью CSS. Изменить то можно, но не кардинально.
Шаблонизатора как не было, так и нет, и даже не планируется. Вместо этого для генерации простого HTML используется BananaHTML, а сам интерфейс ложится на плечи Веб-Компонентов и Polymer в частности.
Как я докатился до такой жизни
Шаблонизаторы по разным причинам мне не нравились всегда. В связи с этим в CleverStyle CMS есть понятие темы оформления, которая отвечает за общий облик сайта, но нет шаблонов отдельных страниц.
Во-первых если делать шаблоны отдельных страниц — вы не будете поддерживать всевозможные модули созданные сторонними разработчиками, потому будут использоваться стандартные шаблоны.
Во-вторых шаблоны не позволяют так легко наследовать, и при этом радикально менять внешний вид при необходимости (об этом речь далее).
Первоклассная поддержка Веб-Компонентов
Веб-Компоненты появились не так давно, и есть достаточно много нюансов с их использованием, тем не менее, их удалось решить.
В связи с этим изначально было потрачено достаточно много времени на то, чтобы понять кто виноват — я, как разработчик, полифиллы, или вообще сторонние библиотеки.
Оказалось, что периодически были виноваты все.
В текущей версии CleverStyle CMS, наверное, самая надежная и в связи с этим удобная среда для использования веб компонентов.
В поставку (на момент написания статьи) входят патченные версии:
- jQuery: исправлено поведение $.fn.offset() для элементов внутри теневого дерева (pull request), исправляет работу всплывающих подсказок и целой кучи других jQuery плагинов
- WebComponents.js: исправлена обработка относительных путей в css файлах при наличии
<base>
(pull request) - UIkit: модифицированы стили для работы внутри теневого дерева (Скрипт для конвертации, подходит к любым стилям)
- Polymer: патч, позволяющий наследовать компоненты с теми же именами (обсуждение)
В общем, поддержка Веб-Компонентов из коробки весьма основательная, но вся суть этого поста будет в последней модификации.
Наследовать Веб-Компоненты с теми же именами
Это не исправление проблем совместимости или багов, в отличии от остальных патчей, а новая полезная функциональность.
Выглядит в целом так:
<polymer-element name="test-element" extends="test-element">
<template></template>
<script>
Polymer("test-element", {
ready : function () {
this.parent_method();
}
});
</script>
</polymer-element>
<polymer-element name="test-element">
<template></template>
<script>
Polymer("test-element", {
parent_method : function () {
alert("I'm your parent!")
}
});
</script>
</polymer-element>
С первого взгляда, возможно, не очевидно, но это позволяет вам создавать интерфейсы исключительно из Веб-Компонентов, а потом наследовать и переопределять их при необходимости.
Как это работало раньше: без патча вы можете наследовать существующие пользовательские элементы (Custom Elements) или элементы самого браузера, но не можете переопределить уже зарегистрированные элементы, с ним же вы можете унаследовать элементы, которые будут объявлены позже, таким образом сохраняя нужное имя элемента.
Для чего всё это?
Создавая элементы интерфейса в виде Веб-Компонентов вы полагаетесь на определённые имена тэгов, и было бы очень удобно, если бы вы могли патчить их на лету.
Так как Polymer является всего лишь оберткой, мы можем откладывать регистрацию элементов до появления наследуемого элемента а так же переименовывать его во избежание конфликтов.
Как следствие можно менять представление совершенно без ограничений, не изменяя начальный код, всего лишь наследуя и модифицируя веб-компоненты.
Таким образом вы можете перевернуть страницу вверх ногами, добавить сторонний виджет комментирования, догрузить данные, которых не было в верстке изначально через API и показать пользователю именно то, что вы хотели.
В контексте CleverStyle CMS
Изачально это было придумано и реализовано для CleverStyle CMS (подробнее в документации), но при желании использования в своих проектах соберите Polymer из этой ветки.
В рамках CleverStyle CMS есть понятие зависимостей между компонентами. Предположим, у вас есть модуль магазина (весьма реальный пример, разработка ведется в отдельной ветке), интерфейс сделан с использованием Веб-Компонентов и вы хотите изменить страницу отображения товара.
meta.json модуля Shop:
{
"package" : "Shop",
"category" : "modules",
"version" : "0.88.1+build-118",
"description" : "Shop functionality",
"author" : "Nazar Mokrynskyi",
"website" : "cleverstyle.org/cms",
"license" : "MIT License",
"db_support" : [
"MySQLi"
],
"provide" : "shop",
"require" : [
"System=>1.13",
"fotorama"
],
"optional" : [
"Comments",
"Plupload",
"TinyMCE",
"file_upload",
"editor",
"simple_editor",
"inline_editor",
"payment"
],
"multilingual" : [
"interface",
"content"
],
"languages" : [
"English",
"Русский",
"Українська"
]
}
Компонент может зависеть от чего-то, конфликтовать, и сам предоставлять некоторую функциональность, необходимую другим компонентам, всё это отражается в порядке подключении JS/CSS/HTML файлов компонентов (а нам нужно подключить хакнутую версию перед оригинальной).
Но тут возникает один нюанс, в CleverStyle CMS не может быть двух компонентов, которые предоставляют одну и ту же функциональность, они будут конфликтовать, с другой стороны множественные патчи Веб-Компонентов (методом, описанным выше) разрешены.
Здесь приходит на выручку фича, появившаяся в версии 1.17, которая позволяет указать, что это не самостоятельная функциональность, а расширение функциональности другого компонента:
{
"package" : "Shop_item",
"category" : "modules",
"version" : "0.0.1+build-1",
"description" : "Shop item hack",
"author" : "Nazar Mokrynskyi",
"license" : "MIT License",
"provide" : "shop/item"
}
Именно provide: shop/item показывает что происходит расширение функциональности shop, подробнее о зависимостях и конфликтах.
После этого можно объявлять в Shop_item наследование отображения товара:
<polymer-element name="cs-shop-item" extends="cs-shop-item">
<!--А здесь уже что вам угодно-->
</polymer-element>
При этом исходный код страницы с товаром не меняется и выглядит весьма дружелюбно для поисковых систем (а учитивая минимальность кода даже очень):
<section data-date="0" data-id="1" data-in_stock="24" data-price="20" data-soon="0" is="cs-shop-item">
<div id="images">
<img alt="" src="http://cscms.org/storage/public/Plupload/2015-01-03/18/2_031854a812c6b264b.jpg">
<img alt="" src="http://cscms.org/storage/public/Plupload/2015-01-03/18/2_035654a812ec26d24.jpg">
<img alt="" src="http://cscms.org/storage/public/Plupload/2015-01-03/18/2_035654a812ec1c834.jpg">
</div>
<div id="videos">
<a href="https://www.youtube.com/watch?v=rHBxJCq99jA"> </a>
<a href="https://www.youtube.com/watch?v=bmtbg5b7_Aw"> </a>
</div>
<h1>Boots</h1>
<div id="description">
<p>Nice boots</p>
</div>
<div id="attributes">
<table>
<tr>
<td>Size</td>
<td>2</td>
</tr>
</table>
</div>
</section>
Заключение
Используете вы CleverStyle CMS или нет, все патчи открыты и доступны, так что я рекомендую всем попробовать и выразить свое мнение в комментариях.
За Веб-Компонентами будущее!
Автор: nazarpc