Немного мыслей о CMS на Ruby on Rails

Опубликовано 29.01.2009

Недавнее обсуждение в ror2ru сподвигло меня к тому, чтобы наконец сесть и оформить свои мысли о создании системы управления контентом более-менее общего плана, которую можно было бы как использовать “из коробки”, так и расширять собственными плагинами.

Мои мытарства с CMS-ками разного толка начались года четыре назад, когда я осознал, что для написания на PHP собственной системы мне потребуется если не продать душу дьяволу, то как минимум заложить ее в ломбард. Готовые системы меня по разным причинам не устраивали – одни были глючные, другие было страсть как сложно расширять, третьи заточены под одну конкретную задачу. С переходом на Rails ситуация упростилась в том плане, что стало легче создавать специализированные решения, но в плане работы над типовыми проектами все только усугубилось.

Фактически, сейчас для меня выбор систем свелся к одной – Radiant. У Radiant есть два больших плюса – наличие такой штуки как Radius и наличие большого числа плагинов. Однако есть и большущие минусы. Внутренности Radiant страшны для обычного человека и чего-то в нем править иногда бывает просто жутко. Система разрабатывалась довольно давно, поэтому большинство “вкусностей” последних версий Rails не доступны. Полностью отсутствует возможность локализации административного интерфейса. Да и сам административный интерфейс включает в себя только самые базовые возможности администрирования контента, даже загрузку картинок приходится цеплять отдельным плагином.

Есть еще, конечно, adva_cms, но это скорее компиляция из нескольких типовых модулей, чем универсальное расширяемое решение. Есть Tog, Spree, Insoshi, Typo, Mephisto и прочие, но все они заточены под конкретные задачи. В итоге получается, что либо использовать специализированные движки, либо подпирать костылями Radiant и худо-бедно юзать его, либо писать CMS самому.

Рано или поздно все равно кто-то начнет писать очередную собственную CMS, поэтому я постараюсь немного облегчить ему задачу, представив хотя бы свое собственное видение того, какой должна быть современная CMS на базе Ruby on Rails.

  1. Ядро и компоненты

    Основой системы должно являться ядро – модуль, связывающий воедино все части приложения. Ядро отвечает за загрузку и конфигурирование модулей, подключение общих зависимостей и предоставление точек интеграции. Как само ядро, так и компоненты должны быть выполнены в виде плагинов, чтобы их можно было интегрировать с уже существующими приложениями. Возможен вариант когда система ставится в формате gem’а, но это применимо лишь в частных случаях, когда необходимо развертывать на одном сервере десятки и сотни однотипных приложений. Обычному разработчику проще, когда система вся под рукой и можно при необходимости взглянуть на исходный код.

    Компоненты реализуются в формате мини-приложений, оформленных в плагины. В новой версии Rails этот функционал уже встроен, а в текущей версии (2.2.2) можно использовать, например, desert. Дополнительные плагины, требующиеся для работы компонентов (will_paginate, better_nested_set и прочие) необходимо упаковывать прямо в сами компоненты, а наиболее часто употребимые – включать в ядро.

  2. Конфигурирование

    Для хранения конфигурации системы и модулей должны использоваться отдельные файлы конфигурации. Значения по умолчанию хранятся в самом компоненте и перекрываются значениями из файла конфигурации, добавленного разработчиком. Хорошим вариантом для управления конфигурацией может послужить configatron – вполне достойное решение. При желании можно реализовать хранение настроек в БД (как сейчас это сделано в Radiant) и перекрытие ими данных в конфигурационых файлах. Однако это должно быть не встрено в ядро, а реализовано отдельным компонентом.

  3. Radius

    Как вы уже поняли, я поклонник этого средства разметки. И оно не случайно – более мощного решения я пока что не встречал. С его помощью можно создавать действительно гибкий контент, фактически дать пользователю язык программирования контента. Каждый компонент должен добавлять в этот язык собственные расширения, а так же использовать расширения, добавленные другими компонентами. Средства для регистрации расширений должно предоставлять ядро.

  4. Система аутентификации и разделения прав

    Эта часть востребована практически всеми компонентами и могла бы быть включена в ядро, однако из соображений чистоты и удобства обновления ее имеет смысл вынести в отдельный компонент. API этого компонента должно быть четко описано, чтобы разработчик при необходимости мог заменить его собственной системой, привязанной к конкретному приложению.

  5. Служебные компоненты

    Есть достаточно большой класс компонентов, которые не имеют особого смысла без привязки к конкретным данным. К таковым можно отнести загрузку изображений и файлов для скачивания, комментарии, метки, рейтинги. Все это имеет смысл только в привязке, например, к странице. Система должна предоставлять средства для осуществления такой привязки через точки интеграции. Для связывания компонентов можно использовать, например, файлы конфигурации (для фанатов чистоты подхода), либо напрямую указывать зависимости в коде моделей и контроллеров. Средства для перекрытия классов предоставляет тот же desert. Необходимо, чтобы привязка служебных моделей была возможна не только для страниц, но и для данных, добавляемых пользовательскими компонентами. Это довольно легко решается через полиморфизм, как на уровне моделей, так и на уровне контроллеров и шаблонов.

  6. Версии и зависимости

    Отслеживание версий компонентов и зависимостей одних компонентов от других – это задача разработчика. Упростить этот процесс можно за счет фиксации версии ядра и предоставления инструментов для установки расширений, адаптированных по данную версию. Реализовать это можно с помощью rake-задач, которые делали бы установку плагинов из заданной метки в репозитории компонента. Допустим, для версии ядра 0.1 установка компонента версии XX должна делаться из ветки tags/0.1-XX, а для установки самой последней версии – из tags/0.1-stable. В этом вопросе я еще пока не пришел к какому-то однозначному мнению. С одной стороны, в ruby-мире уже есть готовая инфраструктура доставки пакетов – gems. С другой, делать компоненты gem’ами неудобно. Тут нужно еще подумать.

  7. Локализация

    Тут, я думаю, без вопросов. Современная система управления сайтами, заточенная под один язык – это бред. Загрузку локализаций для компонентов делает либо ядро, либо сами компоненты. Кстати, буквально сегодня нашел плагин для редактирования локализаций через web-интерфейс – translate. Можно сделать нечто подобное.

Часть этих идей я уже реализовал в системе управления порталами, однако над ними еще нужно поработать, прежде чем можно будет говорить о формировании готовой системы. Тем не менее, я настроен оптимистично и в принципе даже готов к диалогу с теми, кто может быть заинтересован в разработке такой системы. Со своей стороны я готов предоставить свои наработки.

Буду рад услышать ваши мнения в специальной ветке на ror2ru »

Подпишись и читай
Самые продвинутые ruby-программеры уже читают Rail0rz в формате RSS. Присоединяйся!