Попробовав на практике некоторые свободно-распространяемые CMS (вроде Joomla), пришёл к выводу что нужно делать что-то своё.
Кое-какой опыт программирования имелся, а также участия в сопровождении относительно большого проекта, так что приблизительно представлял, чего именно я хочу и как этого добиться.
При разработке архитектуры старался учитывать следующие требования:
- Удобство программирования
- Отделение логики сайта от базы движка
- Независимость от используемой БД
- По возможности универсальная панель администратора
- Настройка дизайна без ограничений
- Возможность создания "мультисайтов".
В тоже время на некоторые приоритеты свободных CMS я позволил себе наплевать:
- Полноценное конфигурирование из панели управления
- Подключаемые модули и плагины
Отказ от настройки сайта из панели управления и использования подключаемых модулей
Я считаю, что данный функционал - самое большое припятствие для разработчика движка. Зачем тратить половину времени на программирование функций, которые будут использоваться едва ли не один-два раза на протяжении всей жизни сайта? Всё равно не получится сделать это на сто процентов - к примеру все шаблоны дизайна для Joomla всё равно на одно лицо, а якобы "модули" - наспех прикрученные сторонние форумы и магазины, несоблюдающие соглашений по кодированю, принятых в основной системе.
Удобство программирования
Если я отказываюсь от модулей и гибкости настроек, значит нужно чтобы изменение и добавление функционала со стороны кода проходило максимально удобно.
Одно из самых неудобных для меня занятий в кодировании - это написание запросов к БД и разбор результатов. Одновременно, как раз из этих частей состоит 80% всей логики любого сайта (остальные 20% занимает контроль прав). Поэтому было решено все эти неудобства загнать в одну небольшую библиотеку и больше никогда не трогать. В общем я доволен, что решил так сделать, потому что библиотека получилась небольшая и удобная в использовании.
Пример получения сообщения форума из БД:
my $msg = $context->{db}->get('forum_message');
$msg->id($messageId);
warn $msg->body;
# после обращения к любому свойству
# $msg содержит актуальный объект "сообщение форума"
Пример получения списка тем форума из БД:
my $set = $context->{db}->get('forum_topic', 'set');
$set->{_filter}->set({published => {value => 1},});
# отдаём массив записей в шаблонизатор
$context->{response}->addTo('forumTopics', $set->_simple);
Настройка дизайна без ограничений
Пока в качестве шаблонизатора используется TemplateToolkit. Не всё в нём нравится, но лучше пока не искал.
Независимость от используемой БД
Скорее всего полностью от особенностей БД уйти нельзя (все используют нестандартные операторы), но оградиться можно, если максимально использовать функции библиотеки DBI (для last_insert_id и подобного).
Отделение логики сайта от базы движка
Так как я отказался от независимых модулей, то просто разбил логику сайта на блоки в Perl-модулях. Получилось похоже ядро Linux'a - используемые модули жёстко загружаются на старте приложения. В принципе, нужно было сделать более правильно, но моего знания Perl'a не хватает на динамическую подгрузку модулей, а это не настолько важно, чтобы отвлекаться сейчас.
Возможность делать "мультисайты"
В другом моём блоге я упоминал бесплатный хостинг на Joomla. Он был сделан очень просто - по имени домена третьего уровня подгружался соответствующий конфиг сайта. Получалось на одном движке работало много сайтов. Хотелось бы чтобы и на новом движке было возможно подобное.
Универсальная панель администратора
Сейчас это фактически более дружественное подобие phpMyAdmin'a. Позволяет редактировать, добавлять и удалять записи в БД. Что самое важное - почти не зависит от конфигурации базы. Пользовательский интерфейс сделан на JxLib, получилось весьма удобно и экономно в плане времени разработки. Панель взаимодействует с движком через ограниченный набор методов. Формат обмена - JSON. Т.е. получился почти внешний API движка.
Общее описание архитектуры
XN - основной объект движка. Создаётся на старте приложения. Создаёт
XDM,
ServerConfig,
TemplateToolkit и ожидает запрос. По приходу запроса создаёт
Process и передаёт ему глобальные объекты.
Process - обработчик запроса. Создаёт
Response. Проверяет данные запроса и на основании их вызывает нужные обработчики для получения данных. Обработчики готовят данные и передают их в
Response. После завершения обработчиков командует
Response'у отправлять ответ.
Response - формирователь ответа. Принимает данные и в зависимости от параметров запроса, вызывает
TemplateToolkit, или формирут
JSON-ответ.
XDM - менеджер БД. По запросу предоставляет
DBObject, подключенный к требуемой БД.
DBObject - позволяет обработчику взаимодействовать с БД как с объектом (как показано в примерах выше).
ServerConfig - считывает конфигурацию для
TemplateToolkit,
XDM,
DBObject.
Все объекты порождены от
XBase для унифицированной обработки ошибок.
Движок работает как FCGI-приложение (c apache, или nginx).