MaxSite CMS для чайников. Type-файлы

Рубрика: MaxSite CMS -> Для чайников
Четверг, 7 января 2010 г.
Просмотров: 704
Подписаться на комментарии по RSS
]]>
]]>

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

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


Type-файл home.php

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


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

Строчка

  1.  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() можно опустить второй параметр. Это несколько упрощает результирующий код и делает его более читабельным.


Разный вывод

Строчка

  1.  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-тэгов под разные блоки. Для примера рассмотрим строчку:

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

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

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

  1.  div.type {}
  2.  div.type_home {}

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


Цикл вывода

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

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

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

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

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


Цикл вывода

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

  1.  foreach ($page_top as $page)
  2.  {
  3.   extract($page);
  4.    
  5.   mso_page_title($page_slug, $page_title, '<h1>', '</h1>', true);
  6.   echo '<div class="page_content">';
  7.   mso_page_content($page_content);
  8.   mso_page_content_end();
  9.   echo '<div class="break"></div>';
  10.   echo '</div>';
  11.  }

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

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

Обратите внимание, что мы нигде не задавали переменные $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. Если какой-то параметр не указывается, то берётся значение по-умолчанию (он указан через знак равно). Назначение каждого параметра понятно из его имени.

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

  1.  mso_page_title(
  2.   $page_slug = '',
  3.   $page_title = 'no title',
  4.   $do = '<h1>',
  5.   $posle = '</h1>',
  6.   $link = true,
  7.   $echo = true,
  8.   $type = 'page')


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

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


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

  1.  mso_page_content_end()


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

  1.  mso_page_date(
  2.   $date = 0,
  3.   $format = 'Y-m-d H:i:s',
  4.   $do = '',
  5.   $posle = '',
  6.   $echo = true)


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

  1.  mso_page_cat_link(
  2.   $cat = array(),
  3.   $sep = ', ',
  4.   $do = '',
  5.   $posle = '',
  6.   $echo = true,
  7.   $type = 'category',
  8.   $link = true)


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

  1.  mso_page_tag_link(
  2.   $tags = array(),
  3.   $sep = ', ',
  4.   $do = '',
  5.   $posle = '',
  6.   $echo = true,
  7.   $type = 'tag',
  8.   $link = true)


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

  1.  mso_page_edit_link(
  2.   $id = 0,
  3.   $title = 'Редактировать',
  4.   $do = '',
  5.   $posle = '',
  6.   $echo = true)


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

  1.  mso_page_comments_link(
  2.   $page_comment_allow = true,
  3.   $page_slug = '',
  4.   $title = 'Обсудить',
  5.   $do = '',
  6.   $posle = '',
  7.   $echo = true,
  8.   $type = 'page')

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


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

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

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


Пагинация

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

  1.  mso_hook('pagination', $pagination);

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


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

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


Концовка

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


Вернемся к mso_page_foreach

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

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

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

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

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

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

В функции 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()

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

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

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

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

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

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

  1.  pr($pages);

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


Функция _pr()

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


Функци _sql()

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

  1.  pr(_sql());

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


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

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

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

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

]]>twitter.com Google Buzz google.com bobrdobr.ru del.icio.us technorati.com linkstore.ru news2.ru rumarkz.ru memori.ru moemesto.ru]]>

Комментариев: 2

Вы можете получать новые комментарии к этой записи по RSS или оформить подписку на все комментарии сайта. Или даже на все новые записи сайта. Не знаете, как это сделать?
  1. 2010-01-07 в 21:00:54 | Cuprum
    ]]>]]>

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

  2. 2010-01-07 в 22:11:27 | leventov

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

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

Не регистрировать/аноним

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

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



grin LOL cheese smile wink smirk rolleyes confused surprised big surprise tongue laugh tongue rolleye tongue wink raspberry blank stare long face ohh grrr gulp oh oh downer red face sick shut eye hmmm mad angry zipper kiss shock cool smile cool smirk cool grin cool hmm cool mad cool cheese vampire snake excaim question

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