Компоненты
Большинство функционала среднестатистического сайта можно разделить на компоненты по его назначению. Например, каталог товаров, форум, обратная связь, поиск по сайту - это все компоненты. Кроме этого, конечно, может существовать функционал, который нельзя отнести к какому-либо компоненту, но обычно доля такого функционала не велика.
Платформа TAO построена таким образом, чтобы компоненты были максимально изолированы друг от друга, код компонента был компактен и располагался в одном месте, не будучи разбросанным по различным каталогам проекта. Такой подход дает нам очевидное преимущество: компонент можно перенести с одного проекта на другой простым копированием файлов. На этом же принципе работает и библиотека стандартных компонентов. Подробнее о структуре компонентов в статье Структура компонентов.
Компоненты находятся в каталоге app/components, но для того, чтобы они заработали, каждый компонент должен быть подключен в файле www/index.php после подключения модуля CMS, но до вызова CMS::Run().
Core::load('CMS'); // Подключаем компонент "Новости" Core::load('Component.News'); // Подключаем компонент "Каталог товаров" Core::load('Component.Catalog'); CMS::Run();
Последовательность подключения компонентов влияет на маршрутизацию адресов (об этом далее).
Вообще говоря, код компонента может состоять из одного единственного модуля с функцией initialize если его назначение - выполнить какие-то действия при загрузке. Но это не характерно. Основные действия выполняются в CMS::Run(), поэтому компонент должен содержать еще кое-что. Главным образом - контроллер (возможно, даже не один) и роутер.
Контроллер
Контроллер - это модуль, который выполняет какие-либо действия по указанию диспетчера. Эти действия оформлены в коде контроллера как функции-экшены (actions). Расмотрим простейший контроллер из умозрительного компонента "Новости". Он умеет выполнять всего два действия: показывать список новостей и показывать одну новость. Обычно контроллер наследуется от базового контроллера CMS_Controller.
class Component_News_Controller extends CMS_Controller implements Core_ModuleInterface { public function view_list($page_number) { // .... } public function view_item($id) { // .... } }
Для того, чтобы ядро знало какой контроллер (и экшен в нем) вызывать, необходим роутер.
Роутер
Роутер - механизм, который выполняет две функции:
- На основании HTTP-запроса (прежде всего - URL страницы) определяет какой контроллер (и какой экшен в нем) запустить и какие параметры ему передать.
- Обратная предыдущей функция: формирует URL страницы для выполнения той или иной функциональности. Этот пункт не является обязательным.
В классе роутера обязательно должна присутствовать функция route(), в которую в качестве аргумента передается объект HTTP-запроса. На основании этого запроса роутер должен решить - его ли это запрос или нет. Если запрос ему не знаком, то функция route должна вернуть false. В противном случае, функция возвращает массив с информацией о том, какой контроллер и какой экшен в нем запустить, и какие параметры передать.
На сайте таких роутеров может быть несколько. Как правило - по одному на компонент.
Общая схема работы TAO.CMS
1. Компоненты загружаются через Core::load(). В функции initialize() каждый из них создает экземпляр роутера и регистрирует его в системе.
2. При вызове CMS::Run() диспетчер по очереди опрашивает все зарегистрированные роутеры (запускает в каждом функцию route) до тех пор пока не встретит тот, который вернет информацию о контроллере. После этого опрос роутеров прекращается.
3. Диспетчер загружает контроллер, информацию о котором вернул роутер, запускает нужный экшен и получает от него ответ.
4. В зависимости от полученного ответа формирует HTTP-отклик. Это может быть либо текст страницы, либо редирект, либо еще что-то, предусматриваемое протоколом HTTP.
Итак, теперь на примере рассмотрим простейший компонент.