Вероятно всё те же случайности, которые привели Томаша из Праги в захолустье Чешской провинции, дабы он встретил свою судьбу в лице Терезы*, привели меня к тому, что исконно изменило все мои взгляды на процесс, который в целом не представляет особой технической сложности в плане реализации, но в то же время является основной сложностью в иделогическом и эргномическом плане, поскольку непосредственно от правильности применимой к нему политики зависит не только частота приступов мигрени у программистов, и испоконвечных утяготителей и усложнителей их жизни - дизайнеров, - но и успешность в плане дальнейшего сопровождения и возможного усовершеноствования проекта в целом.
Безусловно, я сейчас говорил о методиках разделения информационной системы на реализацию и представление (пользовательский интерфейс, и, собственно, ядро (kernel) системы).
Если говорить об используемых мной технологиях эдак, скажем, год назад, то это, в лучшем случае, были системы шаблонирования Smarty и тому подобное, что в каком-то плане довольно удобно и полезно, однако всё равно представляет собой ряд ограничений, так низкий уровень возможной спецификации данных дизайнерами и в целом не имеющими квалификации в программировании людьми представляло собой большую ограниченность. Другими словами, за поставку данных в формате user-friendly чаще всего целиком и полностью отвечает программист, при этом дизайнер, либо разработчик интерфейсов, выступают лишь потребителями данных, без каких-либо дополнительных возможностей, конечно, если они не владеют специальными знаниями и технологиями, такими как средства server-side (python, php, ruby, т.д.) либо client-side (js, ммм...
) разработки. Всё это довольно замедляло работы над проектами, в ситуации, когда необходимо было разработать довольно простой модуль, функционал которого чаще всего ограничивался визуализацией некоторых данных БД либо результатов работы некоторого интегрированного в систему пакета, с чем мог бы справится и разбирающийся в базовых понятиях структуры системы (не кода, а скорее логики функционирования) обыватель, но что было невозможным из-за обязательного участия программиста в этом процессе.
И вот недавно (да, время - это конечно большая утрата) открытая мной для меня же (
) технология XSL преобразований кардинально повлияло на форму и вектор направления моих мыслей, и на подход в реализации дружественности для не-программистов так же.
Я, в целом, давно знал о существовании данной технологии, и даже что-то писал на досуге, но всю несомненную полезность и flexibility оной, осознал лишь после того, как начал в корне пересматривать принцип работы разработанной в контексте одного проекта, а на сегодняшний день перешедшей в статус OpenSource, CMS платформы, которая на тот момент была довольно логично и правильно сделана в плане расширяемости, дружественности для сторонних разработчиков и, собственнно, конечных пользователей (users), поскольку в основе лежала идеология XML-обмена данными - как внутри системы, так и за её пределами - в контексте общения с внешними серверами, но это уже другая история.
Однако было в ней одно громадное "НО!", о котором мне громко в форме едкого сарказма (как умеют OpenSource разработчики, словно в поговорке: "в чужом глазу...") напомнили ребята с форума PHPClub. "НО" же это заключалось именно в том, что в системе почти не было явного разделения на "код" -> "представление", и это стало настоящей проблемой, степень важности которой не была оценена на начальных этапах проектирование, и которая в следствии стала значительным образом тормозить дальнейшее развитие системы как в плане реализации/безопасности/красивости, так и интереса к ней среди других решений в среде OpenSource-сообщества.
Однако, как я уже говорил, плюсом системы было то, что изначально все настройки, рычажки и прочие элементы не относящиеся к прямой реализации были представленны ввиде сторого структурированных и специфицированных XML-данных, что и послужило палочкой, которая выручалочка.
Поскольку основной задачей стало сделать так, чтобы дизайнеры не догадывались о существовании чего-то кроме XML/XSL (если конечно им этого не захочется), однако могли бы при этом спокойной получать данные в удобном для них формате, создавая пользовательские интерфейсы; при этом так же имея возможность более advanced'ного общения с системой, к примеру:
- Возможность посредством XML-структур, входящих в файл конфигурации модуля, производить запрос данных из БД.
- Возможность доступа к определённого рода функциям PHP, запрошенным в файле конфигурации модуля
- Возможность быть в некоторых ситуациях полностью независимым от программииста
И вот с банкой кофе ("Nescafe Classic"), чайником и изрядным уровнем энтузиазма я закрылся на балконе-веранде, и пришёл к совершенно новому для меня подходу к разделению кода и данных.
Если возвращатся к системе CMS, упомянутой выше, то нужно (для большей степени понимания) ввести три понятия: "блок", "пакет", "модуль".
Эти базисный единины в её контексте представляли фундамент движка. Так "пакет" испключительно поставляет функционал, не принимая участия в формировании UI-представления данных, в свою очеред "модуль" наоборот является базовой единицей реализации функционала "пакета" и визуализации данных, разделяясь в свою очередь на подразделы, относительно их функций и семантики. И не относящаяся к "пакетам", но в то же время не совсем "модуль" сущность "блок" так же представляет собой элемент пользовательского интерфейса, при этом не имея всех возможностей модулей, как в структуре так и в функционале, что очевидно.
В окончательном варианте, файловая структура поставк модуля имеет следующий вид:
-- module
-- parts
-- main-part
-- actions
-- action.inc ; сервер-логика для обработки событий форм
-- xsl
-- main.xsl ; файл подключаемый в качестве XSL(T) по-умолчанию
-- ... ; список таблиц XSL, поставляемых с этим разделом
-- main.xml ; основной XML-файл реализации
-- others
-- client-logic
-- css
-- images
-- info.xml
Во время запроса пользователем некоторого модуля системы, происходит проверка текущего активного раздела, при условии отсутствия которого будет обработан `main-part`.
Процесс обработки заключается в следующих этапах:
- Обработка XML-файла с данными для обработки на серверной стороне (запросы к БД, импорт методов, прочее).
- Включение в результирующий массив данных результатов проводки по всем, привязанным к данному разделу некоторого модуля либо модуля в целом, обработчикам (wrappers) которые были назначены программистами.
- Процессинг связанной с исходным XML файлом таблицей преобразований XSL.
- Добавление данных в массив временных данных, с последующим возвратом их пользователю на последней стадии формирования контента.
Исходный информационный файл XML для настройки и определения запрашиваемых и поставляемых данных для каждого раздела модуля имеет следующую структуру:
<?xml version='1.0'?>
<input>
<transform>
<item src='${part_dir}/xsl/main-diff.xsl'/>
</transform>
<infoset>
<title></title>
<css></css>; Inline-объявление либо перечисление узлов <item>
<script></script>; Inline-объявление либо перечисление узлов <item>
<!--Некоторые дополнительные параметры страницы-->
<params>
<key>value1</key>
</params>
</infoset>
<!-- Exaple URL-parts exporting as XSL-variables -->
<var number='1' import-as='product_id' type='number'/>
<var number='2' import-as='product_title' type='string'/>
<var number='3' import-as='user_id' type='number'/>
</urlset:url>
<dbset:dataset>
<set id='1'>
<tables join='left'> ; "join" - опциональный атрибут
<item name='some_db_table1' variable='d'/> ; variable - опциональный атрибут
<item name='some_db_table2' variable='d1'/> ; опциональный атрибут
</tables>
<columns>
<item name='title' from='d' variable='product_title'/>
<item name='uid' from='d1' variable='user_id'/>
</columns>
<where>
<case type='default'>
<term object='SUMM(d1.count)*SUMM(d1.cost)'/>
<term object='SUMM(d2.salary)*SUMM(d2.salary)'/>
<action type='greater or equal'/>
</case>
<case type='or'>
<term object='(SUMM(d1.count)*SUMM(d1.cost))/SUMM(d2.salary)*SUMM(d2.salary)'/>
<term object='1.2'/>
<action type='less'/>
</case>
</where>
<order by='some_db_table1.title' way='ascend'/> ;Optional tag
<limit count='20'/> ; Optional tag
<group by='some_db_table1.uid'/> ; Optional tag
</set>
</dbset:dataset>
<!-- Разработчики могут задавать следующую структуру данных:
<dbset:dataset>
<query>INLINE DATABASE QUERY
<columns>
<item name='selected-column-name' import-as='NAME IN XSL VARIABLE ENVIRONMENT'/>
</columns>
</dbset:dataset>
-->
<functions-import>
<item name='{php_environment_function}' as='{xsl_environment_name}'/>
;...
</functions-import>
<vars-import>
<item name='{php_environment_variable}' as='{xsl_environment_variable}'/>
</vars-import>
<wrappers>
<item name='{php_valid_function_or_method_name}' step='0'/>
</wrappers>
</input>
Данная структура полностью описывает формат возможных данных для процессинга XSLT-процессором, применяя таблицы трансформации.
Стоит отдельно упомянуть такие элементы как <functions-import/>, <variables-import/> и <wrappers/>.
В теле элемента <functions-import/> перечисляются те функции среды PHP, которые должны быть импортированы в среду XSL, и соответственно <vars-import/> вложенными тегами <items/> описывает переменные среды PHP, которые будут доступны для обращения в среде XSL.
То есть это как-бы расширения стандарта XSL, подобно аналогичному - EXSLT, которое служит для увеличения уровня автономности и самобытности дизайнера (что, конечно, в любом случае не является желательным по ряду обстоятельств
).
Расширение стандарта поддерживается подключением в качестве пре-процессоров XSL внешних wrapper-методов, которые обспечивают предварительную подготовку и замену всех "самодельных" конструкций, на необходимые аналоги (обращение к импортированным функциям, переменным). Очевидно, что число wrapper'ов не ограничено ни чем, что, собственно, не ограничивает расширение стандарта.
При этом учтён тот факт, что некоторые такие методы следует применять в условиях последовательности, а посему введён такой параметр как `step`, которые говорит обработчику в какой последовательности применять wrapper-методы.
Однако это решает лишь проблему с модулями, при этом остаются открытыми проблемы обработки различной степени приоритетности ошибок системы, организация основного пользовательского интерфейса - страницы, применение XSL-преобразований в контексте блоков, и привязка блока к некоторой зоне страницы.
В целом ничего принципиально отличного, в сравнении с подходом реализации пользовательского интерфейса модулей не производится (если говорить блоках).
Однако прежде чем говорить о блоках, следует обсудить структуру страницы.
Я всегда был приверженцем проработки всех возможных ситуаций и вариантов, и конечно же все считал, что пользователю в определённый момент наскучит базовое оформление страницы, да и даже если не базовое - наскучит, посему всегда считал невозможным применение термина CMS к продуктам, в основе которых лежат идеи не только того, что пользователь потом "всё равно будут платить за дизайн", или "все должны будут выучить эту технологию", "..мы делаем систему для "нормальных людей", а они эту технологию почти все знаю...", не говоря уже об интернационализации и прочем.
Посему, как мне кажется, одной из главных деталей архитектурной реализации системы является правильное построение механизма универсализации структуры пользовательского интерфейса, и максимального абстрагирования от конкретной темы/структуры/методологии.
В целом это конечно поле для разгула фантазии, и конкретная реализация будет зависеть лишь от вкусов и стиля разработчика. Однако и тут есть некоторые моменты, которые должны быть в любой реализации, так как составляют основу логической структуры темы оформления, а именно:
- Декларирование в настройках темы её структуры, в смысле активных областей для добавления блоков.
- Специальные контейнеры для отображения стека системных сообщений некоторого типа, с применением (опционально) к ним стилевого оформления, характерного данной теме.
- Абстрагирование от количества доступных модулей/пакетов в системе.
- Абстрагирование от текущих интернациональных настроек системы.
- Предоставление пользователю возможность собственноручно настраивать некоторые детали оформления, путём правки значений в файле настроек.
Так, в контексте не один раз упомянутой выше технологии XSL, системой в тему оформления портируются следующие структуры данных и методы:
Структуры:
1)
<handlers>
<set type='errors'> ; 'errors' | 'messages' | 'attempts'
<item code='error_code'>Short system error description</item>
</set>
</handlaers>
2)
<infoset>
<!--структура аналогична структуре вложенного в узел <input> элемента<infoset>, за исключением изъятия элементов <css>,<scripts>-->
</infoset>
Методы:
get_panel_content(< %идентификатор_панели%>) - получение блоков, которые относятся к данной панели, некоторой темы.
get_css_nodes() - отрисовка и возврат всех относящихся к данному документу таблиц стилей
get_scripts_nodes() - отрисовка и возврат всех относящихся документу скриптов
flush_error_handler(< %handler%>) ; handler='errors'|'messages'|'attempts'
Что ж, это было что-то вроде небольшого обзора, представления своих взглядов на решение проблемы, которые я использую в настощиее время. В целом многие идеологические моменты в реализации подсказаны Drupal, но исключительно идеологические, поскольку структура друпала совершенно обратна данной, и ориэнтирована скорее на разработчиков, нежели на нечто среднее с уклоном в сторону дизайнера и UI-интерфейс builder'а.

Оставить комментарий
You must be авторизироватся для добавления комментария.