Создание CMS Гибкая система управления сайтом

Создание программы можно сравнить с постройкой здания, но в отличие от построенного здания, программа постоянно требует внесения изменений в ответ на часто меняющиеся потребности её пользователей. Веб-сайт не исключение – его соответствие потребностям посетителей определяет его прибыльность, поэтому программное обеспечение, управляющее содержимым сайта, должно быть максимально гибким и легко изменяющимся, дабы не осложнять, а наоборот, способствовать развитию сайта.

Нынешние системы управления содержимым сайта (CMS) придерживаются модульной архитектуры, что позволяет в какой-то мере достичь гибкости. К сожалению, этой гибкости недостаточно, чтобы легко изменять структуру содержимого сайта: даже незначительные изменения решаются либо поиском другого модуля, либо созданием нового. Причина в том, что в таких системах модули определяют структуру содержимого (например, модуль новостей, фотографий, комментариев и др.) и часто содержимое разных модулей очень сложно объединить и построить осмысленную связь между ними. Например, чего только стоит возможность размещать фотографии из фотогалереи в новостях! А если речь пойдёт о более специфических возможностях? Из-за применения не гибких технологий приходится с опасением выслушивать желания заказчиков сайтов, и заказчик бывает в недоумении, что на его сайте нельзя просто сделать то, что для него кажется вполне естественным.

В своё время прыжок к гибкости совершила система под названием Drupal. В Drupal единица содержимого представляет собой узел (node): и статья, и новость, и фотография, и всё остальное являются узлами, благодаря чему стало возможным объединение разного по типу содержимого в одну структуру. Более того, категоризация, называемая таксономией (taxonomy), позволила структурировать содержимое по смыслу. В системе Drupal структура сайта уже не определяется исключительно модулями, её стало легче изменять по своему усмотрению. Но трудности остаются, так как довольно сложно, оперируя одной категоризацией, конструировать сложно структурированные сайты. Нет желаемой свободы для воплощения всех идей. Творчески настроенный разработчик оказывается вынужденным создавать собственный модуль или вмешиваться в программный код найденных модулей частично соответствующих требованиям.

Сложные не шаблонные сайты сейчас создаются с нуля с программированием системы управления непосредственно для них. В этом помогают каркасные системы – framework’и, их сейчас предостаточно, но будет ли готовый сайт обеспечен гибкостью? Framework – отличное решение для программиста ускоряющее создание сайта с задуманным функционалом, но framework ничего не дает конечному пользователю и самое главное администратору сайта. Вряд ли программист будет закладывать функционал в сайт для быстрого и гибкого изменения структуры сайта без программирования, т.е. в разделе администрирования, ведь это требует немалые временные и финансовые затраты. Допустим, сайт сделан и работает, но со временем владельцу понадобилось добавить новые свойства у группы товаров в каталоге, естественно, чтобы и поиск по ним работал и любые другие функции реализованные для каталога. Здесь без программиста не обойтись.

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

Содержимое первостепенно!

В центре всего – содержимое. Единицей содержимого является объект, множество объектов с однотипными свойствами образуют класс, точнее наоборот, классом определяются объекты с конкретными свойствами. Понятия объекта и класса должны быть знакомы не только программистам, а каждому разумному человеку, потому что мы воспринимаем окружающий мир объектным, в наших умах выстраивается объектная модель огромного мира. Подобно тому, как мы организуем информацию в своих умах, должно быть организовано в системе управления содержимым, именно так будет достигнута супер гибкость. Здесь не нужно касаться вопросов искусственного интеллекта.

Система Boolive отличается отнюдь не тем, что применяет объектно-ориентированные технологии, главная особенность в том, что для создания классов данных и их объектов не нужно ничего программировать! Логика системы организует и управляет данными, моделируя их объектный смысл. Добавление новости на сайте – это создание нового объекта класса «новость». И в любой момент, пользователь, наделенный соответствующими правами, может изменить класс «новость», добавив например новое свойство. Создание сайта превращается в создание нужных классов, выстраивания между ними связей, при этом системой поддерживается все важные понятия объектных технологий: наследование классов, разновидность отношений между объектами, полиморфизм и другое, но с доступным для непосвященного в программирование смыслом. И всё доступно посредством веб интерфейса. Создание класса – это всего лишь определение свойств, которые будут у объектов данного класса, никакой логики программировать не надо. Важной особенностью является гибкость и легкость изменения уже созданных объектов и классов без программирования.

Данные (содержимое) управляется централизовано. Чтобы на сайте создать каталог или ленту новостей не нужно устанавливать соответствующие модули в систему. Нужно просто создать требуемые классы «каталог» и «лента новостей». А смысл наделяется уже от того, как данные будут использованы. Новость, комментарий, фотография, категория, раздел, пользователь, группа и многое другое является объектами. От того что всё управляется централизовано, как по законам вселенной, можно с легкостью установить отношение между новостью и фотографией, поместить новость в форум и она одновременно станет темой форума. Любые действия с группировкой пользователей, организации комментариев (лентой, иерархией или совсем оригинально), структуризацией фотогалереи и использования фотографий из фотогалереи для связывания с другими объектами. Полная свобода для творчества.

Разграничение доступа

Другой особенностью является разграничение доступа к данным. И тут тоже невероятная гибкость! Существующие системы в основном используют принцип «пользователь» → «группа» → «список разрешенных действий». В системе Boolive всё иначе. С данными можно выполнять всего четыре простых действия: создание, изменение, чтение и удаление. Условие выполнения действия – это любое логическое выражение, это может быть комбинацией условий, например, проверка текущего пользователя и его статуса, можно сделать условие на текущее время, чтобы фото «для взрослых» показывать только ночью, например. Смысл в том, что условие не привязано к пользователям или их группам. Условие – это проверка состояния системы, а состояние системы это вся модель данных, к примеру, доступ к статье (чтение) для незарегистрированных пользователей можно сделать, если у статьи положительный рейтинг.

От того, что всё является объектами, а действия выполняются над объектами, разграничение можно определить на любой объект: хоть на раздел форума, хоть на конкретную тему, хоть на заголовок темы. К теме форума, например, прикрепляются файлы, можно свободно разграничить доступ ко всем файлам, а можно непосредственно к файлу выбранной темы. Соблюдается также иерархическая зависимость между данными. Если нельзя «читать» форум, то не будет доступа и к его темам и прикрепленным к ним файлам, даже при наличии связей с темой от других объектов системы.

Выборка содержимого

Имея гибкие возможности по созданию данных любой структуры, любой сложности, возникает вопрос, как же реализовать ещё и поиск по ним такой же гибкий и универсальный? А это уже сделано! В системе реализован механизм, что даже не требуется знать, как именно данные храниться в базе данных, главное иметь представление о самих данных. Все данные системы, всё содержимое взаимосвязано и называется моделью данных – это как примитивная «матрица» (из фильма Матрица). Мы можем получить любой объект из модели данных. Объект можно получить по его идентификатору, но чаще всего, как и в реальной действительности, мы опираемся на относительные параметры, например «найти первую фотографию из галереи Природа». Примерно с таким же смыслом строятся запросы на получение нужных объектов из модели данных. Сейчас запросы строятся на программном уровне, когда будет разработана административная часть, запросы можно будет формировать с помощью удобного веб интерфейса. Запросы или по другому «выборки» являются важнейшим соединительным звеном между данными и их отображением.

Отображение содержимого

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

Для каждого объекта имеется шаблон, но это не значит, что количество шаблонов равно количеству объектов. Поиск шаблона для объекта выполняется в два этапа, сначала проверяется наличие шаблона непосредственно для отображаемого объект (точное соответствие), если нет, то уже ищется шаблон по классу отображаемого объекта, т.е. шаблон для новостей будет использоваться каждой новостью, не имеющей собственный шаблон. Но здесь ещё учитывается наследование классов! Если не будет найден шаблон для новостей, то будет искаться шаблон по классу «материал» (если новость наследует материал). Как и в языках программирования в объектной модели системы Boolive имеется корневой класс, его имя «сущность». Если и для класса «материал» не будет найден шаблон, то уже точно будет использован шаблон класса «сущность», которым отобразится объект в самом простом виде. Без труда можно сделать новостную ленту, где каждая новость будет отображаться оригинальным образом, либо за минимум действий сделать общее отображение всех объектов. Так отображаются не только объекты новостей, статей, комментариев – любой объект даже не связанный с наполнением сайта может быть отображен.

В системе есть специальный класс «Раздел», из объектов которых формируется базовая структура сайта и разметка страниц. Например, имеются объекты этого класса, образно назовем их: «корень», «публичный», «управление». Когда запускается создание страницы по запросу от пользователя – делается выборка объекта «корень» и начинается его отображение, а в логике его шаблона из учета свойств этого объекта и в зависимости от URL делается выборка объекта «публичный», либо «управление» и производится его отображение. А там далее уже будет выборка меню, непосредственно материала, блоков и всего прочего соответствующего запросу. Шаблон объекта «корень» – это html с пустым тегом body, внутрь body уже вставляется html код от объекта «публичный» или «управление». Далее, в шаблонах «публичный» или «управление» определяется разметка (схема) страницы, т.е. где будет меню, шапка, футер и другое. Вы, наверно, догадались, что «публичный» – это сам сайт, а «управление» – это раздел администрирования. Можно создавать любое количество разделов и подразделов, если требуется, то можно сделать несколько разных по функционалу разделов администрирования – для программистов, менеджеров, секретарш.

Вспомните про разграничение доступа. Достаточно определить условие на «чтение» объекту «управление», чтобы разграничить доступ к административному разделу и это можно проделать с любым разделом, подразделом, блоком и т.п.

Вдаваться в подробности, как происходит определение, при каком URL что отображать, сейчас не буду – в общем, это те же процессы создания, изменения, удаления объектов, только с особым интерфейсом для удобства выстраивания всей структуры сайта. Вот она гибкость от централизации содержимого – через изменение содержимого, изменяется любой компонент системы!

Данные свободно могут быть представлены в любом формате, для этого используются соответствующие модули.

Заключение

Всё тип-топ :) Цель статьи – в общих чертах показать, чем же отличается система Boolive от тысячи других и каким же образом достигается супер гибкость.

Описываемые возможности в организации данных, поиск с абстрактными условиями и сортировками, базовый функционал разграничения доступа (сами условия пока упрощены) и аутентификация пользователей, принципы шаблонизации и ряд других системных особенностей уже реализованы. Важные детали реализации расписаны в предыдущих статьях и будут ещё написаны новые.

Для пилотной версии с минимумом красивых штучек в функционале, остается сделать интерфейс администрирования, чем сейчас занимаюсь, ну и некоторые другие функции. Работа сложная, расходуется уйма калорий…

И ещё: оцените текущий дизайн раздела администрирования: http://boolive.ru/files/admin/ (не для IE6 и хуже!)

Комментарии

  1. Merx пишет:

    Неужели наконец-то появится идеальная cms :)
    Дизайн админки красивый

  2. lesa пишет:

    Дизайн красивый.. но что-то мне на него смотреть мешает..
    может слишком светлый.. может цвета сливаются (монитор яркий).. закладки\списки слева практически сливаются с фоном..

    Успехов.. следим.. перенимаем.. учимся =)

  3. Владимир пишет:

    На будущее учтём, что есть очень яркие мониторы :)

  4. Yaroslav пишет:

    Сайт очень качественный. Вам бы награду за него или орден почета. :)

  5. VitNikifor пишет:

    Проект жив ? ;)
    Автору респект ! Довольно интересная концепция. Ждемс релиз кандидат на пробу :)

  6. Владимир пишет:

    Живее живых)) Промежуточные результаты не спешим разглашать, пока :)

  7. Xploit пишет:

    Радует факт - начался набор команды. Если будет интересно пишите ICQ: 300841. Опыт 5 лет работы.

  8. patrik пишет:

    Хотел посмотреть, но скачать исходники незя…
    Владимир, можно как-то заглянуть в душу вашего творения?

  9. Владимир пишет:

    Стучитесь в аську :) Исходники временно прикрыты из-за засекреченной причины

  10. Андрей пишет:

    Админка пока в нерабочем состоянии, поэтому увидеть как все это работает - трудно)))). Но в теории как я понял вы хотите на бедного админа, который не всегда знаком с HTML возложить еще и знание ООП.

    ИМХО: вам лучше пойти не в сторону гибкости, а в сторону простоты. Или делать 2 интерфейса - прогера и админа. В общем удачи вам в ваших начинаниях.

  11. Владимир пишет:

    С декабря в сторону просты стали двигаться, от неё уже к гибкости. Затишье в блоге - работаем :)

  12. abraxys пишет:

    Очень похоже на MDA. Я имею ввиду модель и концепция. Кстати, очень давно ищю CMS систему, построенную на основе MDA (Model Driven Architecture), но к сожалению не нашел (наверное плохо искал).

    Можно немножко поумничаю, так сказать, сос своей колокольни?

    Сама идея довольно проста: мы оперируем 3 базовыми понятиями некая сущность (класс, таблица БД), атрибут данной сущности (поле класса, поле таблицы БД) и отношение 2х сущностей по какому либо атрибуту.

    Далее буду оперировать понятиями класс, поле, отношение. Есть некий класс Thing, ему соответствует таблица в БД thing. У этого класса есть 3 поля: ThingId (thing_id), ThingName (thing_name), ThingCreationDate (thing_creation_date). Это базовый класс всей модели.

    Далее, допустим, мы хотим добавить понятие “новость”. Для этого нужно ввести еще один класс News. Для новости так же важно знать когда ее создали, ее название, а так же, предположим еще 2 специфических свойства - текст данной новости, и тип новости. Так зачем же нам создавать еще одну таблицу, в которой будут присутствовать некоторые поля, которые уже есть в базовой thing (thing_name, thing_creation_date)? Не проще ли создать таблицу, в которой будут присутствовать только новые, специфичные именно для новости поля (news_text, news_type)? Проще!

    Поэтому мы просто наследуемся от thing и создаем новый класс(таблицу БД) news со следующими полями: news_id, news_text, news_type. News связываем с Thing отношением один-к-одному. Все!

    Это конечно все клево, но вот только как создавать теперь экземпляр новости, как его удалять и как модифицировать? Для этого мы сгенерируем набор простых хранимых процедур-мапперов:

    insert_news(news_id, news_name, news_creation_date, news_text, news_type)
    update_news(news_id, news_name, news_creation_date, news_text, news_type)
    delete_news(news_id, news_name, news_creation_date, news_text, news_type)

    Если судить в контексте Oracle, то мы можем сгенерировать пакет процедур-мапперов. Так же мы генерируем набор классов-мапперов на любом языке программирования, только уже в контексте прикладном (но это нам сейчас не важно).

    Далее… Мы смотрим на поле news_type и подсознательно чувствуем, что чем-то оно нам не нравится… Правильно! Тип-то может иметь несколько значений, причем эти значения более менее постоянные, хотя их набор может быть расширен. В контексте нашей модели, мы создаем новый класс на одном уровне с Thing и обзываем его BaseDir (base_dir в БД соответственно) с полями BaseDirId (base_dir_id) и BaseDirName (base_dir_name). От него наследуем NewsType, с одним единственным полем NewsTypeId (news_type_id). Соответственно генерируем мапперы

    insert_news_type(news_type_id, news_type_name)
    update_news_type(news_type_id, news_type_name)
    delete_news_type(news_type_id, news_type_name)

    ну а в классе news переименовываем поле NewsType в NewsTypeId (news_type - news_type_id) и добавляем отношение с классом news_type типа много-к-одному по полю news_type_id.

    Ну а далее полет фантазий безграничен! Во первых, нужно добавить поле thing_internal_type_id в thing. Это поле должно ссылаться на описание типа класса (т.е. атомарный экземпляр модели). Управление видимостью полей (также как и их наличием в процедурах-мапперах) можно реализовать на основе use case. Далее можно реализовать перекрытие полей для задания им в потомках определенных характеристик и т.д. Реализовать различные системы отображения, редактирования экземпляров наших классов на основании модели этих самих классов.

    По сути, больше ничего не нужно, так как это дает такую гибкость… и кстати, производительность. А главное при условии успешной реализации самой концепции, для создания любой конфигурации не требуется знание программирования и БД, т.е. работать с такой системой смогут любые категории пользователей.

  13. Андрей пишет:

    Ну со своей колокольни посмею выразить замечания по поводу практичности такого подхода именно на php+mysql

    1. >>Не проще ли создать таблицу, в которой будут присутствовать только новые, специфичные именно для новости поля (news_text, news_type)? Проще!

    Не проще, т.к. это скажется на производительности, потому, что чтобы получить дату или имя новости каждый раз при запросе в базу придется связывать базовую таблицу и таблицу новостей. Также неудобно это при дебаге, когда нужно будет заглянуть в БД через phpmyadmin, посмотрев на новости и найти допустим нужную по заголовку.

    2. >>News связываем с Thing отношением один-к-одному. Все!

    Верность данного подхода на счет связывания 1 к 1 - очень спорная штука. Одни используют такую связь, другие нет. Но хочу заметить, что согласно упрощению моделей БД, выдвинутыми Коддом отношения 1 к 1 нужно упрощать, соединяя две таблицы в одну.

    3. Для всех классов потомков вы все-равно создаете таблицы, так зачем вообще нужен гемморой связей с предками, если ни прироста производительности ни скорости разработки данный подход не дает?

  14. abraxys пишет:

    1) Производительность, в данном варианте, штука довольно спорная. Ну придется вам связать, допустим, 3 таблицы в одном SQL по PK, ну и что? Производительность сильно упадет?

    2-3) Не судите об архитектуре только по примеру. Зачем делать то же самое поле в новой таблице, если оно уже есть в базовой таблице?

    В общем спорить нет ни времени, ни желания, вам наверно виднее, т.к. толком не работал ни с PHP ни с MySQL.

  15. Андрей пишет:

    На счет производительности. Я конечно понимаю что в БД очень хорошо развиты алгоритмы индексации, аналитические алгоритмы выборки и много еще чего, что убыстряет в сотни раз связи между таблицами. Но если без этого всего взять грубо пример то получим, что чтобы найти выборку из двух связанных таблиц, допустим, в каждой из которых по 3 записи, то СУБД должна перебрать 3*3=9 записей. Не существенно если таблицы в теории даже не перевалят за пару сотен записей. А если вдруг в каждой из таблиц окажется не по 3, а по 3000 записей, то БД должна будет перебрать 9 000 000 записей, вместо 3000. Вот тут разницу погасить не смогут даже самые прогрессивные аналитические алгоритмы БД.
    Для уменьшения количества связей в запросах крупные проекты используют метод, называемый “Избыточность данных”. Когда, допустим, надо выбирать коммент и имя пользователя кто этот коммент написал. То при этом не связывают по ID пользователя таблицу пользователей и комментариев, а вместо этого в записи комментария к полю userid, являющуюся внешним ключом, добавляют username, которое хранит имя этого пользователя.

Комментировать


(обязательно)


(обязательно) E-mail адрес не будет отображаться на сайте