Современная, быстрая и удобная система управления сайтом

Type-файлы в MaxSite CMS

Архив записейКомментарии: 6Просмотров: 2960

Сегодня мы наконец-то поговорим о загадочных type-файлах.

Шаблоны Clouds и Mini используют файлы типов данных из дефолтного. Когда вы будете ставить какой-то другой шаблон, то будет хорошо, если в нем также будет отсутствовать свой каталог «type». Это означает, что шаблон в полном объеме поддерживает существующие типы данных.


Type-файл home.php

Начнем свое знакомство с вывода главной страницы. Это файл home.php.


Текущий каталог языка

Строчка

mso_cur_dir_lang('templates');

задает текущий каталог для перевода. Перевод и поддержка языков в MaxSite CMS реализуется с помощью функции t(). Первым параметром функция принимает строчку для перевода, вторым - группу перевода. Если вы знакомы с WordPress, то знаете, что в нем используется единый файл перевода, который грузится всегда в момент старта. Сам перевод имеет довольно большой размер, но вся «прелесть» заключается в том, что в нем львинная доля - это перевод админ-панели. Совершенно очевидно, что для простого посетителя все они не нужны в принципе, но при этом создают лишнюю нагрузку на сервер.

Возможно вы пользуетесь сборкой WordPress, где используется разделение файла перевода на полную и lite. Я придумал этот алгоритм к версии 2.3 и насколько знаю, он в неизменном виде и сейчас существует в разных «самостоятельных» сборках WordPress.

Так вот. Разработчики WordPress давно уже плюнули на внутреннюю оптимизацию своего детища, поэтому для них лишние 2-3Мб потребляемой памяти не играют существенной роли. Но, не для меня. Поэтому в MaxSite CMS принято, что строка для перевода будет находится в какой-то своей группе. Например есть группа «templates» - это перевод фраз, встречающихся в шаблонах. «Admin» - перевод админ-панели. «Plugins» - перевод плагинов.

Кроме этого в t() можно указать «__FILE__», которое будет интерпретированно как свой собственный каталог с файлами перевода. Посмотрите для примера плагин «Admin_announce» - в нем отдельный каталог «language», в котором и находятся файлы с переводом.

Что же касается самого файла перевода, то это самый обычный php-файл, где фразы оформляются в виде массива $lang.

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

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


Разный вывод

Строчка

if (mso_get_option('home_cat_block', 'templates', '0'))

подключает файл home-cat-block.php в случае, если установлена опция home_cat_block. Эта опция называется «Блоки рубрик на главной» (в настройках шаблона). Для вывода блоков используется более сложный алгоритм и делать его в одном файле я посчитал неразумным.


Страница перед всеми записями

Далее мы смотрим опцию home_page_id_top и если она отмечена, то получаем эту самую страницу. Тут мы впервые сталкиваемся с функцией mso_get_pages(). Это одна из самых мощных и универсальных функций, поскольку именно она избавляет нас от составления сложных SQL-запросов и сразу преподносит нужные записи в удобном для вывода формате.

Для того, чтобы указать mso_get_pages() какие именно записи нам нужны, в первом параметре задаем массив опций. Второй параметр нужен для формирования пагинации - листалки страниц (он встретится ниже).

Для удобства параметры для получения страниц я вынес в переменную $par. Давайте кратко остановимся не некоторых наиболее важных.


Некоторые параметры для mso_get_pages()

Ниже список в таком формате: «параметр (значение по умолчанию) - описание».

  • limit (7) - количество записей на одной странице.
  • page_id (0) - номер страницы, которую нужно получить. В нашем случае этот номер определен в опции «home_page_id_top».
  • cut (Далее) - текст для ссылки на продолжении текста. Если нужно вообще отключить деление записи, то есть вывести её целиком, то нужно указать: 'cut' => false.
  • cat_order (category_name) - поле по которому сортируются рубрики записи. Когда у вас отмечено несколько рубрик у записи, можно указать в каком порядке они будут отображаться.
  • cat_order_asc (asc) - прямой или обратный порядок отображения рубрик записи.
  • pagination (true) - следует ли формировать данные для пагинации. Если нам нужно вывести одну страницу, то очевидно, что пагинация нам не нужна. Отключение пагинации экономит один запрос к БД.
  • cat_id (0) - номера рубрик из которых выводить записи. Например мы хотим выводить на главной только рубрики «Новости» и «О важном». Указываем их через запятую.
  • content (true) - нужно ли получать весь текст из базы. Очень часто бывают ситуации, когда нам не нужно получать текст, а только заголовок записи или какие-то другие данные. Тексты обычно большие по размеру, поэтому на них тратится больше php-памяти. Вот для таких случаев и ставим этот параметр в false.
  • type (blog) - какой тип страниц (не типов данных!) выводить. По-умолчанию мы выводим на главной только страницы типа «blog», а другие не выводятся. Тип страниц - это дополнительная группировка, что-то вроде рубрик, только в более глобальном варианте. Если вам нужно задать несколько типов одновременно, то их следует оформлять в виде массива: 'type' => array('static', 'help', 'lections').

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

Вот кстати, в WordPress'е мы обычно называем «страницей» - «постоянную страницу» - тип «static», а для типа «post» используется слово «запись». В MaxSite CMS это лишено смысла, поэтому я использую «запись» и «страница» в обычном понимании этих слов.

Полученный результат для верхней записи сохраняется в переменной $page_top. Если функция mso_get_pages() не смогла получить ни одной страницы, то она возвращает пустой массив.


Получаем основные страницы для вывода

Тут опять же задаем нужные параметры для mso_get_pages() и получаем массив страниц.


Посыл header, если страниц нет

Строчка с header() отправляет http-заголовок браузеру в случае, если не найдено страниц.


Подключение main-start.php

Теперь, когда мы получили все данные, мы можем подключить первую часть шаблона: main-start.php. Обратите внимание, как задается путь к этому файлу: через getinfo('template_dir'). Сделано это для того, чтобы наш type-файл мог работать с любым текущим шаблоном.


Непосредственно вывод данных

Дальше вы видите формирование html-тэгов под разные блоки. Для примера рассмотрим строчку:

echo NR . '<div class="type type_home">' . NR;

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

Классы (class) указаны через пробел. Эта возможность CSS позволяет обращаться к блоку (в данном случае div) двумя способами:

div.type {}
div.type_home {}

То есть вначале можно задать общий стиль для div.type, а потом подстроить для своих нужд в виде div.type_home. В MaxSite CMS очень часто встречается подобный подход, поэтому я так подробно на нем остановился.


Цикл вывода

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

Наша функция mso_get_pages() возвращает данные в виде обычного массива и в PHP есть очень удобная функция для организации цикла перебора элементов массива foreach. Поэтому в MaxSite CMS ничего не придумывается, а просто используется то, что и так нормально работает.

Рассмотрим учебный пример такого цикла:

$массив = array('первый', 'второй', 'третий');
    
foreach ($массив as $элемент)
{
	echo $элемент . '<br>';
}

Данный пример демонстрирует перебор элементов с помощью foreach(). Примерно так же мы и будем выводить записи, только наши массивы немного сложней - они многомерные (массив в массиве).


Цикл вывода

Рассмотрим подробней цикл, поскольку на таком принципе построенны почти все type-файлы.

foreach ($page_top as $page)
{
	extract($page);
   
	mso_page_title($page_slug, $page_title, '<h1>', '</h1>', true);

	echo '<div class="page_content">';
		mso_page_content($page_content);
		mso_page_content_end();
		echo '<div class="break"></div>';
	echo '</div>';
}

Строчка extract($page); преобразует элементы массива в обычные переменные. Еще один учебный пример:

$массив = array(  
			array('a' => 1, 'b' => 2, 'c' => 3),
			array('a' => 11, 'b' => 22, 'c' => 33),
			array('a' => 111, 'b' => 222, 'c' => 323)
			);
   
foreach ($массив as $элемент)
{
	extract($элемент);
  
	echo $a . ' - ';
	echo $b . ' - ';
	echo $c . '<br>';
}

Обратите внимание, что мы нигде не задавали переменные $a, $b и $c. Но зато мы экстрактнули (о!) $элемент и переменные автоматом создались на основе ключей массива.

Все примеры рабочие.

В нашем же цикле автоматом появятся переменные из массива «$page»: $page_slug, $page_title, $page_content и другие.

Если по какой-то неведомой причине вас не устраивает extract(), то получить нужные данные можно так (соответственно): $page['page_slug'], $page['page_title'] и $page['page_content']. То есть обычные ключи массива.

Переменная $page в MaxSite CMS объявлена как глобальная. Сделано это для того, чтобы в цикле вывода сторонние функции, например плагины, могли получить данные текущей записи. Именно поэтому в своих разработках никогда не используйте свою $page.

Функция mso_page_foreach()

Вы заметили, что я опустил разбор функции mso_page_foreach(). К ней мы вернемся немного позже.


Функции вывода записей

Для того, чтобы вывести данные записи в MaxSite CMS предусмотрены функции-обертки, которые несколько упрощают форматирование конечного кода. Можно например, просто вывести $page_content через echo, но тогда потеряются все хуки, по которым может меняться текст.

Ниже я привожу список функций, как они объявлены в MaxSite CMS. Если какой-то параметр не указывается, то берётся значение по-умолчанию (он указан через знак равно). Назначение каждого параметра понятно из его имени.

Формирование загловка/ссылки на страницу.

mso_page_title(
	$page_slug = '', 
	$page_title = 'no title', 
	$do = '<h1>', 
	$posle = '</h1>', 
	$link = true, 
	$echo = true, 
	$type = 'page')

Вывод текста.

mso_page_content(
	$page_content = '', 
	$use_password = true, 
	$message = 'Данная запись защищена паролем.')

Функция, которая выполняется после вывода текста. Например некоторые плагины могут здесь выводить какие-то свои данные.

mso_page_content_end()

Вывод даты. Второй параметр ($format) может быть массивом опций: format - формат даты, days - названия дней недели, month - названия месяцев.

mso_page_date(
	$date = 0, 
	$format = 'Y-m-d H:i:s', 
	$do = '', 
	$posle = '', 
	$echo = true)

Вывод рубрик записи.

mso_page_cat_link(
	$cat = array(), 
	$sep = ', ', 
	$do = '', 
	$posle = '', 
	$echo = true, 
	$type = 'category', 
	$link = true)

Вывод списка меток записи.

mso_page_tag_link(
	$tags = array(), 
	$sep = ', ', 
	$do = '', 
	$posle = '', 
	$echo = true, 
	$type = 'tag', 
	$link = true)

Ссылка на редактирование страницы. Отображается у админа и автора записи.

mso_page_edit_link(
	$id = 0, 
	$title = 'Редактировать', 
	$do = '', 
	$posle = '', 
	$echo = true)

Формирование ссылки «обсудить» если разрешен комментарий. Первый параметр можно задать массивом и в нем уже указать нужные значения. Пример такого использования как раз и приведен в файле home.php.

mso_page_comments_link(
	$page_comment_allow = true, 
	$page_slug = '', 
	$title = 'Обсудить', 
	$do = '', 
	$posle = '', 
	$echo = true, 
	$type = 'page')

Все эти функции позволяют упростить формирование html в шаблонах и сразу учитывают некоторые особенности и условия.


Полные записи или заголовки?

В цикле вывода вы увидите опцию home_full_text. Если она определена, то выполняется вывод записей в виде последовательных div-блоков. Если же home_full_text = false, то мы выводим только заголовки записей в виде списка ul-li.

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


Пагинация

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

mso_hook('pagination', $pagination);

и выводит пагинацию. В хук pagination мы передаем наш массив. Сам вывод пагинации - это удел плагинов, поэтому мы не будем их рассматривать. Отмечу лишь, что в MaxSite CMS плагинаций может быть много. Например можно их выстроить одну под другой. :)


Если страниц нет

Если вы пользуетесь Notepad2, то для вас не составит сложностей визуально отслеживать блоки {...}. Посмотрим блок else, когда страниц не найдено. В этом случае мы выводим сообщение, что ничего не найдено и выполняем хук page_404. По нему, например будет выводиться архив сайта.


Концовка

Завершает наш type-файл подключение main-end.php.


Вернемся к mso_page_foreach

Давайте теперь поговорим о mso_page_foreach(). Это специальная функция, которая позволяет произвольно настраивать вывод записей в конкретном шаблоне. Делается это через type_foreach-файлы.

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

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

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

Рассмотрим практический пример. В нашем type-файле:

if ($f = mso_page_foreach('home-top')) 
{
	require($f); // подключаем кастомный вывод
	continue; // следующая итерация
}

В функции mso_page_foreach() указывается type_foreach-файл. В нашем случае это home-top. Система проверит наличие файла шаблон/type_foreach/home-top.php и если он есть, подключит его с помощью обычного require() и сразу перейдет к следующему циклу (continue).

Таким образом, механизм type_foreach позволяет легально кастомизировать произвольный шаблон.

Заготовки для type_foreach-файлов находятся в каталоге default/type_foreach. Обратите внимание, что они все начинаются с символа «_». Когда вы будете их копировать в свой шаблон, этот символ нужно удалить. Система автоматически проверит существование всех файлов и будет их подключать по мере необходимости.

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


Функции отладки

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


Функция pr()

Функция объявлена так:

pr($var, $html = false, $echo = true)

В первом параметре указываем интересующую нас переменную. Второй позволяет конвертировать чистый html в спецсимволы, чтобы увидеть результирующий код в браузере (правда это работает только для строк). Третий - выводить ли резуальтат в браузер или вернуть по return.

К особенностям pr() относится то, что она умеет работать с любыми входящими типами переменных. Если это строка или число, то выводится обычная строка. Если это массив или объект, то выполняется форматирование, чтобы вы видели структуру.

Дополнительно вывод pr() обрамляется в тэг pre, тем самым в браузере он отображается моноширинным шрифтом.

Когда вам нужно понять как и что устроенно, то вы используете pr(). Например после получения страниц напишите

pr($pages);

и вы увидите массив всех полученных записей. С помощью этой функции вы можете узнать какие данные возвращает mso_get_pages().


Функция _pr()

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


Функция _sql()

Данная функция пригодится тем, кто составляет свои запросы к БД. Обычно мы используем Active Records, но иногда нужно контролировать генерируемый SQL. В этих случаях можно принудительно заставить CodeIgniter сформировать запрос и получить его в виде текста. Обратите внимание, что сама функция ничего не выводит, а только возвращает текст текущего запроса по return. Поэтому если вам нужно увидеть запрос, то нужно пользоваться так:

pr(_sql());

В некоторых задачах Active Records не может корректно (или как нам нужно) сформировать SQL-запрос. Можно было бы конечно тогда отказаться от него, но можно просто получить текущий по _sql(), внести необходимые изменения в его текст и выполнить обычным $CI->db->query().


Прочие type-файлы

Я не стану сейчас рассматривать остальные type-файлы, поскольку они практически идентичны нашему home.php с той разницей, что используются другие опции, type_foreach-файлы и немного другой вывод. Постарайтесь хотя бы бегло пройтись по ним, чтобы держать в голове их назначение.

Некоторые type-файлы, например файлы users более сложны, потому что используются не для вывода записей, а для организации страниц комюзеров. Если вы понимаете заключенный в них код, значит для вас открыта дорога к построению на базе своего шаблона небольшой социальной сети.

Чуть позже мы рассмотрим все эти вопросы.

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

1Аноним07-01-2010 19:00

Чую, это не последняя статья! Спасибо, Макс, очень нужный цикл.

2leventov07-01-2010 20:11

Осталось поставить ссылку на цикл в админке :)

3Zidar11-02-2011 04:22

Макс, я хочу сделать кино сайт, у меня tags(метки) это актеры. Как мне сделать ещё одни метки для режисеров и использовать функцию типо mso_page_tag_link для них.

kinosite.ru/tags/Джеймс+Камерон - выводятся записи с этим актером.

Как сделать что бы

1) kinosite.ru/director/Джеймс+Камерон - выводились все записи данного режисера

4Аноним11-02-2011 12:53

Ну скопировать в свой шаблон type/tag.php под именем director.php, где в праметрах получения страниц ($par) указать тип custom_type = tag.

5Сергей18-12-2015 10:36

Не могу ни где найти информацию, как на главной странице в анонсах и полной статье сделать вывод автора статьи, в том числе и admin то есть меня? Подскажи пожалуйста.

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

Комментарий будет опубликован после проверки

Вы можете войти под своим логином или зарегистрироваться на сайте.

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