CMS. Теория
Здесь должно было бы быть какое-то вступление, но я так ничего и не смог придумать. Я понимаю, то нужно как-то объяснить о чем буду дальше писать в этом блоге, но красивые фразы не получаются. Поэтому я решил, что нет смысла на это тратить время и просто сообщаю, что речь пойдет о CMS, но которая пока существует только в моей голове. Мы попробуем потренироваться и (без лишних амбиций) просто понять как вообще работают такие «штуки».
Вступление
За несколько лет моей активной работы с WordPress я понял не только его сильные стороны, но и слабые. Именно поэтому если бы я взялся за свою систему, то прежде всего постарался бы избежать слабых сторон WordPress.
Сразу предупреждаю тех, кто решил, что я вдруг перешел в стан противников WordPress. Это не так. Я считаю, что WordPress на сегодня один из лучших «движков». Заложенные в него основы позволяют легко выполнять задачи, для которых он и создавался. Я могу критиковать WordPress с разных точек зрения, но в большей части из-за его узкой специализации. К сожалению WordPress - это вещь в себе - если нужно решить какую-то нестандартную задачу, то сделать это можно, но ценой повышенной ресурсоемкости.
Ниже я привожу тезисы, которые на мой взгляд, имеют особую важность.
Гибкость
«Движок» должен уметь работать с любой структурой данных, а не только той, которую заложили разработчики. Например у нас есть набор записей. Каждая запись может быть определенного типа: черновик, личная, публичная, запароленная, заметка to-do и т.д. При этом мы хотели бы самостоятельно создавать типы заметок, а в шаблоне (админ-панели и т.п.) самостоятельно решать какие из них следует выводить. Очевидно, что если мы жестко пропишем эти типы в «движке», то мы должны будем включить серьезную поддержку (функции, данные, файлы) для всех этих типов. На мой же взляд, «движок» должен содержать лишь минимальный механизм для управления данными.
Если сравнивать с WordPress, то нечто подобное попытались реализовать с помощью таксономии. Но при этом всё-равно жестко прописаны функции рубрик, меток. Часть функций никогда не будет востребована, а другая часть будет присутствовать всегда, прежде всего из-за проблем совместимости с предыдущими версиями.
К моментам гибкости хочу отнести еще и способ работы «движка». На первый взгляд кажется, что нужно предусмотреть как можно больше функций для пользователей на «все случаи жизни». Нужен вывод списка - пожалуйста, нужно выпадающий - без проблем, а хотите просто массив - еще проще. Всё это замечательно, но в реальности мы сталкиваемся с тем, что большинство функций никогда не используются. Срабатывает принцип Парето, когда 80% пользователей используют не более 20% возможностей. Откройте свой WordPress-шаблон и увидите, что для вывода списка записей нужно от силы 1-2 десятка функций. Но, поскольку оставшиеся 80% существуют и подгружаются не зависимо от вашего желания, то мы неизбежно сталкиваемся с проблемой производительности и нехватки памяти.
Я же думаю, что нет смысла делать вывод списка (для примера) рубрик, да еще и с html-форматированием. Что мешает выполнить один запрос (с учетом своих нужд) к БД и получить единый массив? После этого совершенно не сложно выполнить обход массива в цикле и выполнить html-форматирование по своим потребностям. С точки зрения php-программирования это элементарные вещи.
Что же касается расширенных возможностей, то есть смысл выполнять дополнительные функции в виде отдельных модулей-файлов и подключать их только когда они действительно необходимы.
Скажем, что происходит в момент получения страницы в WordPress? Помимо инициализации кучи массивов, объектов, переменных и констант, подключаются модули базы данных, функции форматирования, рубрики, метки и т.д., и т.п. (Убедиться в этом можно заглянув в файл wp-settings.php - см. функции «require».) Грубо говоря, подключается практически всё. На мой взгял это совершенно не оптимально.
Работа шаблона
Шаблоны в WordPress - это php-файлы и с этой точки зрения ничего лучше нет. Но они вынуждены работать с учетом особенности устройства WordPress. Поэтому с одной стороны мы получаем огромную мощь PHP, а с другой - ограничения рамками самого WordPress.
Возьмем простой пример: вывод главной страницы. Часто нужно вывести не последние записи, а какой-то их набор. Эта примитивная задача для простого php-скрипта, в WordPress решается только обходными маневрами. Проблема в том, что в момент инициализации, WordPress сам выполняет необходимые запросы к БД и создает глобальный массив, где и содержатся все записи для вывода. И только после этого управление передается шаблону. Таким образом в шаблоне мы должны еще раз сформировать уже нужный нам запрос и опять же получить его в массиве, потому что вывод записей осуществляется в т.н. цикле TheLoop.
Некоторые задачи решаются с помощью query_posts, где можно задать некоторые условия, например номер рубрики. Но у WordPress есть деления по типам страниц, в зависимости от которых используются разные файлы шаблона, и вот при использовании query_posts происходит переопределение типа, что в свою очередь может привести к дальнейшим ошибкам.
Все это можно избежать, если предусмотреть, чтобы нужные записи определялись либо в самом шаблоне, либо через его контролер (об этом далее). То есть мы вообще исключаем ситуацию, когда «движок» выполняет запрос к БД и получает какие-то там данные до того, как они были реально востребованы.
Минимализм с помощью фреймворка (Framework)
Любая система содержит некий набор функций, который выполняет роль «ядра». С его помощью осуществляются (грубо говоря) операции «ввода/вывода»: подключение БД, основные операции с БД, анализ/парсинг входящего URL, подключение базовых файлов/классов и т.п.
Можно, конечно начинать делать с нуля, но на мой взгляд это бессмысленное занятие, потому что уже существуют несколько неплохих фреймворков, которые можно без особых сложностей взять за основу. Из наиболее распространенных следует выделить два: CodeIgniter (http://www.codeigniter.com/) и CakePHP (http://www.cakephp.org/).
Основные требования к фреймворку:
- Небольшой объем
- Документация и легкость осваивания
- Работа с различными БД
- Простота настроек
- Скорость работы
- Расширяемость за счет своих модулей
- Поддержка PHP 4 и 5
- Поддержка MySQL 4 и 5
Еще есть одна важная храктеристика - не мешать. То есть когда нам нужно будет отступить от идеологии фреймворка, это никак не сказывается на работе «движка».
Я склоняюсь к CodeIgniter. Прежде всего из-за двух вещей: скорость работы (считается, что это самый быстрый фреймворк), а также из-за его удачной структуры. Поскольку я никогда не работат ни с CodeIgniter, ни с CakePHP, то сравнил насколько быстро и просто можно с нуля разобраться что к чему.
Об CakePHP у меня сложилось довольно сложное впечатление, прежде всего из-за того, что в нем слишком всё запутано и понять что за что отвечает сложновато. Поэтому, чтобы работать с CakePHP потребуется много времени на его изучение.
CodeIgniter, напротив сложилось впечатление легкости и управляемости. Мне потребовалось совсем немного времени, чтобы запустить рабочую страницу, и, при этом, я совершенно не путался ни в файлах, ни в названиях классов, переменных и т.д. Замечу, что при этом я пользовался справкой, входящей в комплект поставки фреймворка, хотя в Интернете можно найти дополнительные подсказки.
Сравнивая эти фреймворки я естественно, обратился за информацией на другие сайты и у меня сложилось впечатление, что CakePHP преподносится не сколько как фреймворк, сколько как «пред-CMS», где уже содержатся все необходимые модули. И действительно в CodeIgniter содержится примерно в два раза меньше php-файлов и «весят» они в три раза меньше, чем в CakePHP. При этом оба они содержат примерно одинаковое количество модулей (больше 30)...
Если у вас есть какие-то свои аргументы за/против, то можете оставить их в комментариях.
Model-View-Controller (MVC). Модель-Вид-Контролер
Современые фреймворки работают по принципу MVC. Данная схема позволяет разделить вывод данных, то есть окончательный вывод в браузере от внутреннего представления и управления. На самом деле про Model-View-Controller написано немало (можно погуглить), но понять что это такое можно только на практике. На мой же взгляд MVC - это скорее теория, потому что неизбежно возникнут ситуации, когда нужно будет формировать конечный html-код например в «контролере». Другое дело, что можно/нужно стремится следовать этой идеологии - как минимум это улучшает и понимание кода, и его поддержку в будущем.
Админ-панель
Этот пункт следует особенно выделить, потому что WordPress популярен прежде всего именно из-за своей админки. И главное её достоинство - это простота и удобство использования для неподготовленного пользователя.
К достоинствам следует отнести и то, что можно без особых сложностей создавать свои страницы администрирования, например к плагинам. Ну и совсем уж молчу про виджеты.
Вместе с тем, любой кто хоть раз пытался модифицировать админку под себя, вздрогнет от ужаса, вспомнив этот процесс. Мне кажется, что во всем мире нет человека, знающего все тонкости и закуточки админ-панели. Слишком уж там намешано и перепутано.
Как я вижу «нормальную» админ-панель? Прежде всего сама по себе админка должна быть выполнена как некий «стандартный» механизм для подключения других модулей администрирования. То есть базовая админ-панель не должна содержать функции, скажем, для добавления записей. Вместо этого она должна только лишь формировать внешний вид, меню и подключать, если это указано, другие модули администрирования, например модуль для создания записей.
При этом нужно решить вопросы управления данными. Можно сразу же в модуле администрирования прописать вызовы к БД, но лучше сделать их на уровне CMS. Объясняю для чего. Предположим у нас есть функция add_page. Если она расположена в CMS, то мы можем вызвать её как из админ-модуля, так и из XML-RPC. Последний позволит управлять системой с помощью блог-клиентов. Если же мы пропишем add_page в админ-модуле, то нам придется либо её еще раз дублировать для XML-RPC, либо подключать сам модуль. Все это естественно нерационально, да и путаницу может внести изрядную.
При таком подходе, будет проще решить и вопросы с управлением пользователями. Мы знаем, что сейчас используется схема ролей, но как показала практика не всё так и безоблачно в этом подходе. Наиболее оптимальной всё-таки будет схема групп, которые часто используются на форумах. То есть администратор сайта создает нужные группы, указывает для них разрешения (базовые + доступ к админ-модулям) и при регистрации пользователь причисляется в нужную группу. В качестве расширения можно предусмотреть и дополнительные настройки/отметки, например пользователя можно забанить.
При этом должна быть единая база пользователей. В WordPress'е мы столкнулись с ситуацией, когда пользователи могут быть зарегистрированными и незарегистрированными. При этом разница между ними по-сути гипотетическая. Я бы сделал так.
Если пользователь хочет зарегистрироваться, то он просто указывает свой email, имя и пароль. Если он не хочет регистрироваться, то он указывает те же самые данные, но уже в поле коммментария. Таким образом его данные однозначно можно идентифицировать, например при подсчете количества комментариев. Как вы понимаете, эта же схема позволяет без лишних движений изменить группу пользователя, если он например решит стать соавтором блога. А для пользователя данная схема будет интересна еще и тем, что можно будет сделать его профиль, где он сможет указать свой сайт, аватарку, контакты и т.п.
Ну и главное, что такая схема теоретически позволит интегрировать пользователей разных форумов и нашей CMS - во всяком случае сделать это будет несколько проще, чем сейчас делается в WordPress.
Постоянная ссылка: http://maxsite.org/?p=335
Версия для печати
