Внимание! Данная запись отмечена как устаревшая и/или потерявшая актуальность! Возможно автор уже передумал и теперь придерживается другой точки зрения, нежели изложенная в тексте ниже.

Шаблоны для новичков. Урок 22. Как работает шаблон в MaxSite CMS

MaxSite CMS / Создание шаблонов MaxSite CMSПросмотров: 11487 (230)

Как выяснилось, многие не совсем понимают принцип работы MaxSite CMS — для них это что-то вроде черного ящика с загадочными хитросплетениями. Предыдущие публикации на эту тему сохранили свою актуальность, хотя с выходом D2 код изменился и стал несколько проще.

Чтобы закрыть эту тему, попробую на пальцах объяснить такие моменты. Для начала рассмотрим процесс «включения» MaxSite CMS.

MaxSite CMS использует фреймворк CodeIgniter, поэтому в момент запуска происходит инициализация ядра CodeIgniter, где подключаются библиотеки для работы с базой данных и небольшое собственное «ядро». Дальше происходит инициализация контроллера MaxSite CMS.

Входящий URL

Работа CodeIgniter (а значит и MaxSite CMS) происходит в зависимости от входящего запроса. Если это вывод одиночной записи, то в адресе будет page. Для рубрик — category и т.д. Таким образом URL разделяется на сегменты, каждый из которых несёт определённую роль. Первый сегмент может указывать на тип данных. Например в адресе http://сайт/page/about:

  • pageпредопределенный тип данных, указывающий, что нужно вывести одиночную страницу сайта;
  • about — уникальная короткая ссылка этой записи (уникальная среди записей page).

MaxSite CMS в типовом варианте рассчитана на обычные сайты и блоги, поэтому содержит базовый предопределённый набор типов данных и необходимые для их обслуживания функции. Полный комплект типов вы можете самостоятельно посмотреть в application/controllers/maxsite.php в методе _remap, но в целом это привычные page, category, users и т.п.

В контроллере MaxSite CMS происходит только проверка существующих типов и в зависимости от результата управление передаётся в соответствующий view (вьювер, «отображение»), который в свою очередь подключает текущий шаблон сайта.

Есть типы данных, которые не передаются в шаблон, а выполняют какие-то свои действия, например remote, url или install.

Также в контроллере происходит загрузка ядра MaxSite CMS — common/common.php. Это означает, что в любой части системы всегда будут доступны функции этого файла. В отличие от других CMS, у нас ядро очень компактное и содержит всего 105 функций, включая служебные.

После загрузки ядра, происходит подключение всех активных плагинов и выполняется хук init. На этом, собственно, вся инициализация и заканчивается — MaxSite CMS полностью подготовила данные и все структуры, которые будут использованы в шаблоне для вывода данных.

«Нулевой» шаблон

Для шаблона существует только одно требование — наличие index.php. Никаких других требований к шаблону нет. Таким образом вы можете без проблем создать шаблон из этого единственного файла и разместить в нём что-то вроде:

Привет!

А если вы разместите строчку

Время: {elapsed_time} | Память: {memory_usage}

— то сможете увидеть потребление PHP-памяти и время выполнения для этой страницы.

Эти спец.коды используются парсером вывода CodeIgniter. Учитывайте только, что на эти показатели влияют активированные плагины. Они подключаются до передачи управления в шаблон.

Диспетчеризация в шаблоне

Понятно, что пустой шаблон не имеет смысла, поэтому в index.php мы размещаем диспетчер типов данных в виде функции mso_dispatcher().

В default-шаблоне диспетчеризация выполняется другим кодом, в котором несложно запутаться. В D2 вся эта «кухня» убрана в ядро MaxSite CMS.

Диспетчер не просто подключает type-файл, но и выполняет задачу по поиску отсутствующего типа данных. Именно благодаря диспетчеру, добавить произвольный аля-тип проще-простого — помещаем в type-каталог одноименный php-файл.

И тут мы подходим к одному важному моменту — диспетчер не выполняет установку типа данных, он только подключает его файл. Типы данных определяются и задаются в контроллере MaxSite CMS. Поэтому для всех других типов система выставляет универсальный тип page_404, сигнализирующий, что тип данных системе не известен.

Например для адреса http://сайт/book будет выставлен тип page_404, потому что MaxSite CMS не знает как именно обслужить такой запрос и есть ли вообще функции для этого дела.

В шаблоне же, диспетчер, увидев этот тип попытается проанализировать первый сегмент адреса и увидев book, предположит, что для него есть одноименный php-файл в каталоге type. И если есть, то подключит его.

Ну а что именно будет в book.php, зависит уже от самого шаблона и этого файла.

Как добавить свой тип данных?

При текущем диспетчере добавлять свой тип данных не имеет особого смысла — вполне достаточно анализа сегментов URL.

Напомню, что для проверки типа данных используется функция is_type(), а для получения сегмента адреса — mso_segment().

if (is_type('home')) 
{ 
    ... это главная страница ... 
}
 
if (mso_segment(1) == 'book') 
{ 
    ... первый сегмент равен book ...
}
 
if (is_type('book')) 
{ 
    ... всегда будет fasle, поскольку такой тип не известен ... 
}

Вместе с тем, создать свой тип данных очень просто. В каталоге контроллера нужно разместить одноименный php-файл. Например, чтобы сделать тип book делаем файл application/controllers/book.php

<?php if (!defined('BASEPATH')) exit('No direct script access allowed'); 
 
    $this->_view_i('book');

Теперь проверять тип данных можно с помощью is_type('book').

Работа type-файла

Диспетчер шаблона подключает type-файл, в котором уже определяется алгоритм вывода данных. Если мы посмотрим на шаблон D2, то увидим, что каталог type пустой. Откуда же тогда берутся данные?

В прошлом шаблоны базировались только на type-файлах шаблона Default. Если в шаблоне нет type-файла, то происходило подключение этого файла из default.

В новых версиях MaxSite CMS, type-файлы находятся в shared-каталоге и диспетчер (функция mso_dispatcher) сама решает откуда подключить type-файл. Поскольку в D2 используется типовой вывод данных, то в нём и нет type-файлов.

Вместе с этим фактом, я всё-таки кратко остановлюсь на принципе работы type-файла. Для примера буду ориентироваться на тип pageapplication/maxsite/shared/type/page/page.php.

В начале type-файл должен получить данные для вывода и, если они есть, то сформировать сам вывод. Получение данных из БД осуществляется с помощью функции mso_get_pages(). В зависимости от параметров она возвращает массив записей для вывода. Если записей нет (например неверная ссылка), то возвращается пустой массив и выводится сообщение о ненайденной странице (404).

Важный момент: данные получаются до их вывода в браузер.

Сам вывод данных размещается между двух файлов:

  • main/main-start.php
  • main/main-end.php

То есть вначале подключается main-start.php, после выводятся полученные данные из базы, и в конце подключается main-end.php.

Такой вариант позволяет выделить верстку сайта в отдельные файлы, оставив type-файлу только его часть работы.

Чтобы упростить верстку и переместить её в один файл, используется буферизация вывода. В main-start.php она включается, а в main-end.php результат вывода сохраняется в отдельную переменную и подключается файл main.php, где, собственно, и происходит вывод в браузер.

В D2 находится только main.php, а результат работы type-файла находится в переменной $CONTENT_OUT. Файлы main-start.php и main-end.php в shared-каталоге, где подключаются автоматом.

Впрочем, это еще не всё. Файл main-end.php представляет собой «концовку» type-файла и позволяет подключать разные main-файлы. Например, если нужно сделать main-файл без сайдбара, то в своём шаблоне делаем main/no-sidebar/main.php, где убираем HTML/PHP-код вывода сайдбара. Выбор main-файла — при редактировании записи.

Примерно также можно задать модульную сетку под произвольный тип данных: main/type/ТИП/main.php. В таких случаях выбор main-файла происходит автоматом.

Main-файлы

В D2 все «служебные» файлы вынесены в shared-каталог. Остаются только те, с которыми должен работать вебмастер. Смысл появления main-файлов в том, чтобы упростить вёрстку и позволить создавать разные модульные сетки под разные типы данных или для разных записей. На сегодняшний день можно создавать раздельные main-файлы для главной, рубрик, записей, архивов и т.д. В каждом main-файле можно организовать свой набор подключаемых компонентов и свои css-стили. То есть сайт один, а его внешний вид и структура может меняться.

Type_foreach-файл

Рассказ будет неполным без упоминания type_foreach-файлов.

MaxSite CMS строится по принципу «заменяющей функциональности». То есть существует некий функционал, который может быть замещён своим. Например вывод заголовка и информации записи жестко прописан в type-файлах. Когда нужно изменить порядок информации, то пришлось бы каждый раз править этот файл, что не совсем удобно. Механизм type_foreach-файлов позволяет заменять различные участки кода на свои варианты.

В нашем примере достаточно разместить type_foreach/info-top.php, чтобы заменить типовой вывод заголовков записей.

Type_foreach-файлов достаточно много и есть только один способ узнать какой файл за какой отвечает кусок кода — это просмотреть нужный type-файл. MaxSite CMS постоянно развивается и type_foreach-файлы могут как появляться, так и меняться по коду. Так что документировать их будет достаточно проблематично. Особенно следует отметить, что некоторые type_foreach-файлы немного по разному работают в Default-шаблоне и в shared-каталоге.

В целом же сегодняшние шаблоны могут прекрасно обходится только type_foreach-файлами без правки type-файлов. Скажу больше: направление развития MaxSite CMS сейчас в том, чтобы обеспечить еще большую гибкость под разные задачи. Например info-top можно будет подключать по типу данных: info-top-page.php — для одиночных записей, а info-top-category.php для рубрик.

В заключении

Шаблон D2 смотрится как простой набор файлов/каталогов, которые работают и подключаются неочевидным способом. Цель такого подхода в том, чтобы исключить весь сложный код из шаблона, но при этом оставить возможность менять его произвольным образом, если возникнет такая необходимость. Я уже отмечал, что в других CMS создание шаблона целиком ложится на плечи вебмастера, включая сложный программный код. В MaxSite CMS я стараюсь максимально разделить работу программиста и верстальщика, но при этом обеспечить обоих большим качественным функционалом. Даже «примитивный» D2 по своим возможностям многократно перекрывает возможности других CMS. Для некоторых — это вообще недостижимый уровень.

««« Урок 23 | Урок 21 »»»

Комментариев: 8 RSS

1Пономаренко Вячеслав15-02-2013 15:50

Максим, большое спасибо за этот урок. Наконец в одном месте собрано почти все по новому шаблону.

Но как самому нетерпеливому, мне бы хотелось задать несколько вопросов:

1. Правильно ли я понимаю что "тип данных" это просто свой личный синоним одного из штатных типов? Т.е. я как бы создаю новый объект который наследует свойства от page или category? Просто некий логический разделитель (такой же как и рубрики, метки, метаполя)?

2. Вы не слова не написали про "тип страниц". По логике это тоже самое что и тип данных (хотя везде написано что их путать нельзя). Значит тип данных умеет нечто такое что не умеет тип страниц? Может быть какой-то из них лишний компонент? Если уж они дублируют логику своего поведения.

3. Про type-файлы. Берем шаблон MAX-EI-EI - type/home - есть папка units - эелементы из нее подключаются автоматом, или только при явном указании в модуле программы?

4. Про type_foreach. Как я понял образцы которые можно использовать в своем шаблоне лежат в shared/blanks/type_foreach - далее подобрать подходящий и необходимо как то настраивать в коде замещение им - или оно на автомате происходит если он есть в папке шаблона?

Вопросов еще много, но я старался задать только относящиеся к теме урока.

Заранее спасибо за разъяснения.

С уважением, Вячеслав

2MAX15-02-2013 16:05

1. Правильно ли я понимаю что "тип данных" это просто свой личный синоним одного из штатных типов? Т.е. я как бы создаю новый объект который наследует свойства от page или category? Просто некий логический разделитель (такой же как и рубрики, метки, метаполя)?

Тип данных на уровне контролера — это просто предопределенный первый сегмент URL. В системе реализована его обработка и вывод данных. Как и что выводить определяется уже в type-файле. Никакого наследования или объекта типа нет и не может быть. Можно условно сказать, что тип данных определяет вариант алгоритма вывода данных.

2. Вы не слова не написали про "тип страниц". По логике это тоже самое что и тип данных (хотя везде написано что их путать нельзя). Значит тип данных умеет нечто такое что не умеет тип страниц? Может быть какой-то из них лишний компонент? Если уж они дублируют логику своего поведения.

Сами написали, что это разные вещи и тут же их смешиваете. grin Это абсолютно разные вещи.

3. Про type-файлы. Берем шаблон MAX-EI-EI - type/home - есть папка units - элементы из нее подключаются автоматом, или только при явном указании в модуле программы?

Не нужно гадать. Разве вы не видите my_home.php?

4. Про type_foreach. Как я понял образцы которые можно использовать в своем шаблоне лежат в shared/blanks/type_foreach - далее подобрать подходящий и необходимо как то настраивать в коде замещение им - или оно на автомате происходит если он есть в папке шаблона?

Это старые type_foreach-файлы к default-шаблону. Некоторые из них несовместимы с shared. Кроме того в этих type_foreach-файлах может использоваться старый код, который не работает в D2. Для определения нужно смотреть type-файл. Пока это единственный верный способ.

3Пономаренко Вячеслав16-02-2013 08:54

Тип данных на уровне контролера — это просто предопределенный первый сегмент URL. В системе реализована его обработка и вывод данных. Как и что выводить определяется уже в type-файле. Никакого наследования или объекта типа нет и не может быть. Можно условно сказать, что тип данных определяет вариант алгоритма вывода данных.

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

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

Верно я понял ?

А можно попросить какую тему в примерах разобрать не следующем уроке ?

С уважением, Вячеслав.

4MAX16-02-2013 09:37

Что-то вы меня совсем запутали. Я не знаю, что такое «переключатель вывода». Изъясняйтесь в понятных терминах. Я абстракцию не понимаю.

5Пономаренко Вячеслав16-02-2013 10:32

Боюсь что правильные термины мне .. сложно подобрать :(

Я написал, как понял.. как я сам себе объясняю отличие типов данных от типа страниц, и для чего они в конечном счете нужны :(

был бы какой-то готовый шаблон который бы показал бы на примере с кодом Вами описанный тип данных book.. но боюсь что это несбыточное желание..

Придеться начинать штудировать лекции с самого начала похоже. Где-от я пропустил важный момент для чего были созданы типы данных и типы страниц.

6MAX16-02-2013 12:31

Сами придумали себе проблему, сами и решайте. Мне нечего добавить.

7Пономаренко Вячеслав16-02-2013 18:24

ВОТ!

http://max-3000.com/uploads/maxsite-cms-shema.gif

что после типа данных, что после типа страниц, мы все одно идем к вьюверу..

т.е. они практически делают одно и тоже.. но почему-то выделены по отдельности..

получается, что тип данных может позволять "объединять" вывод разных типов страниц..

а в прочем Вы правы, я наверное слишком зациклился на этом, есть куда более интересные загадки - например почему page_out не универсален для вывода записей любого типа данных, а зашит по умолчанию только на page

С уважением, Вячеслав

8MAX17-02-2013 08:42

Как обычно вы всё перепутали. Неужели так сложно внимательно прочитать статью и мои комментарии? Если непонятно, см. исходный код. Не нужно ничего придумывать.

Оставьте комментарий!

Комментарий будет опубликован после проверки. Вы соглашаетесь с правилами сайта.

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

О сайте

Здесь вы получите самую полную информацию о создании сайтов на MaxSite CMS.

Рейтинг@Mail.ru