MaxSite CMS для чайников. Шаблонная практика
Пятница, 8 января 2010 г.
Просмотров: 847
Подписаться на комментарии по RSS
Давайте сегодня закрепим полученные знания и немного поэкспериментируем. За основу возьмем Clouds. Создадим новый каталог в шаблонах «clouds-my» и скопируем в него все файлы из «clouds». В нашем каталоге в файле info.php сразу поправьте название шаблона (ключ «name»). Переключите в админ-панели шаблон. Все дальнейшие действия будем делать в «clouds-my».
Начнем с новых типов данных. На нашем форуме недавно был вопрос о том, как сделать отображение личных записей. Как известно в MaxSite CMS у любой записи могут быть т.н. статусы: черновик (draft), опубликовано (publish) и личное (private). Предположим все личные записи должны отображаться в виде отдельного адреса и быть видны только автору.
Для начала нужно создать несколько личных записей. Они не отображаются в общей ленте и видны только когда вы залогинены.
Сделаем свой type-файл
Пусть наши личные записи отображаются по адресу: http://сайт/private, а для отображения конкретной записи в конце указываем её номер: http://сайт/private/номер.
Если вы усвоили предыдущий материал, то знаете, что нам нужно сделать каталог «type» и в него поместить файл private.php. Для начала нам достаточно небольшого каркаса:
- <?php if (!defined('BASEPATH')) exit('No direct script access allowed');
- mso_cur_dir_lang('templates');
- $pages = mso_get_pages(array(), $pagination);
- if (!$pages and mso_get_option('page_404_http_not_found', 'templates', 1) ) header('HTTP/1.0 404 Not Found');
- require(getinfo('template_dir') . 'main-start.php');
- echo NR . '<div class="type type_private">' . NR;
- if ($pages)
- {
- foreach ($pages as $page) :
- extract($page);
- echo NR . '<div class="page_only">' . NR;
- mso_page_title($page_slug, $page_title, '<h1>', '</h1>', true);
- echo '<div class="info">';
- mso_page_date($page_date_publish,
- array( 'format' => 'D, j F Y г.', // 'd/m/Y H:i:s'
- 'days' => t('Понедельник Вторник Среда Четверг Пятница Суббота Воскресенье'),
- 'month' => t('января февраля марта апреля мая июня июля августа сентября октября ноября декабря')),
- '<span>', '</span><br>');
- mso_page_edit_link($page_id, 'Edit page', ' [', ']');
- echo '</div>';
- echo '<div class="page_content type_home">';
- mso_page_content($page_content);
- mso_page_content_end();
- echo '<div class="break"></div>';
- echo '</div>';
- echo NR . '</div><!--div class="page_only"-->' . NR;
- endforeach;
- mso_hook('pagination', $pagination);
- }
- else
- {
- echo '<h1>' . t('404. Ничего не найдено...') . '</h1>';
- echo '<p>' . t('Извините, ничего не найдено') . '</p>';
- echo mso_hook('page_404');
- }
- echo NR . '</div><!-- class="type type_private" -->' . NR;
- require(getinfo('template_dir') . 'main-end.php');
- ?>
Уверен, что для вас не составит труда понять что к чему, поскольку мы все это детально уже разобрали.
Первый запуск
Если набрать в браузере http://сайт/private мы должны увидеть сообщение, что ничего не найдено. Действительно, ведь мы используем дефолтные параметры для mso_get_pages(), которые не подходят под нашу задачу.
Статус записи
Статус записи в mso_get_pages() задается параметром page_status. Меняем:
- $pages = mso_get_pages(
- array(
- 'page_status' => 'private',
- ), $pagination);
Сохраняем, обновляем в браузере и опять получаем 404-страницу. А всё дело в том, что функция mso_get_pages() не в курсе какой у нас тип данных. Точнее она использует тот, который определен системой, в нашем случае это page_404. Чтобы в этом убедиться перед mso_get_pages() выполним:
- pr(getinfo('type'));
Функция mso_get_pages() использует текущий тип данных для генерации запросов к БД. Для обычной записи - это один вариант, для рубрик - другой и т.д. Стандартно существуют такие варианты:
- home - главная/лента записей
- page - одиночная страница
- category - записи рубрики
- tag - метки/мета
- archive - архив по дате
- search - поиск
- author - страница автора
Каждый из этих вариантов по разному интерпретирует входящие параметры. Например второй сегмент в «page» указывает на короткую ссылку записи. Для «home» вообще не учитываются сегменты. Ну и понятно, что для типа «page_404» возращается пустой массив.
Таким образом нам нужно определить по какому варианту мы будем выводить наши личные записи. Очевидно, что лучше всего нам подходит «home». Для явного указания типа данных в mso_get_pages() используется параметр «custom_type». Проверим.
- $pages = mso_get_pages(
- array(
- 'page_status' => 'private',
- 'custom_type' => 'home',
- ), $pagination);
Обновляем страницу и вуаля!, все заработало.
Ссылки на страницы
Обратите внимание на то, как формируются ссылки на одиночные страницы - с «page». Вы уже поняли, что за вывод ссылок отвечает функция mso_page_title() и, похоже, именно в ней зарыт нужный нам ключик.
Обратитесь к предыдущему материалу, чтобы посмотреть как объявлена эта функция. Мы видим, что есть параметр $type. Давайте укажем его как «private» (по-умолчанию он «page»). Меняем в коде:
- mso_page_title($page_slug, $page_title, '<h1>', '</h1>', true, true, 'private');
Обновляем в браузере и сразу получаем нужные нам адреса.
Однако у нас может быть еще одна проблема если вы, как автор, будете использовать разбивку страниц с помощью cut. В таких ссылках на «далее» всё-равно окажется «page». Чтобы исправить это недоразумение укажем в mso_get_pages() параметр «link_page_type» равным «private».
Только авторам
Теперь нам нужно сделать так, чтобы записи отображались исключительно их авторам. Для этого в mso_get_pages() служит параметр «page_id_autor». В нем нужно указать номер автора. Очевидно, что автор должен вначале залогиниться на сайте, с тем, чтобы мы могли узнать его id.
В MaxSite CMS можно узнать номер залогиненного юзера (не комюзера!) так
- getinfo('users_id')
Если же залогиненн кто-то другой, то функция вернет пустую строку. То есть наша задача состоит в том, чтобы передать в mso_get_pages() номер юзера, а если номера нет, то выводить 404-страницу. Меняем:
- if ($users_id = getinfo('users_id'))
- {
- $pages = mso_get_pages(
- array(
- 'page_status' => 'private',
- 'link_page_type' => 'private',
- 'custom_type' => 'home',
- 'page_id_autor' => $users_id,
- ), $pagination);
- }
- else $pages = false;
Здесь мы получаем номер юзера в $users_id и сразу же проверяем условие, чтобы у него было какое-то значение. Если условие выполнено, то получаем записи, где указываем номер юзера. Если условие не выполнено, то ставим $pages = false, что равносильно 404-странице.
Вывод одиночной страницы
Последняя наша цель - вывод одиночной страницы. Тут мы условились, то будем смотреть второй сегмент URL, который содержит короткую ссылку записи. И имено в таком виде у нас сейчас и формируются ссылки. То есть наш алгоритм получается таким:
- Смотрим наличие второго сегмента.
- Если его нет, то выводим как сейчас список страниц.
- Если есть, задаем вывод указанной страницы.
Для получения произвольного сегмента используется функция mso_segment(). Для генерации одиночной страницы мы указываем custom_type = page. Для того, чтобы убрать деление страниц на «далее» указываем cut равным false. Ну и соответственно подставляем разные опции для mso_get_pages().
- if ($users_id = getinfo('users_id'))
- {
- if (mso_segment(2))
- {
- $par = array(
- 'custom_type' => 'page',
- 'page_id_autor' => $users_id,
- 'cut' => false,
- );
- }
- else
- {
- $par = array(
- 'page_status' => 'private',
- 'link_page_type' => 'private',
- 'custom_type' => 'home',
- 'page_id_autor' => $users_id,
- );
- }
- $pages = mso_get_pages($par, $pagination);
- }
- else $pages = false;
Обратите внимание, что мы не передаём в mso_get_pages() (в варианте одиночной страницы) короткую ссылку (slug) по той причине, что эта функция, если явно не указывать slug, автоматически получает его из второго сегмента.
Пагинация
Если у нас много страниц, то внизу появится блок пагинации. Если попытаться перейти на следующую страницу, то мы получим 404-ошибку. Почему так происходит? Очень просто: для формирования списка страниц мы ориентируемся на второй сегмент. Но в случае пагинации, этот сегмент уже занят и равен «next». Таким образом в нашем случае мы фактически пытаемся получить страницу «next» и, не находя её, получаем 404-страницу.
Таким образом нам нужно просто исключить из условия анализа второго сегмента признак пагинации.
- if (mso_segment(2) and mso_segment(2) != 'next') ...
Теперь наша пагинация работает как положено.
Ссылка в заголовке
На одиночной странице нам больше не нужна ссылка на заголовке. Можно, конечно оставить как есть, всё-равно эту страницу будет видеть только её автор, но, как-то это нехорошо. Тем более, что добавить одну строчку условия не составит для нас большого труда. Меняем:
- if (mso_segment(2) and mso_segment(2) != 'next')
- mso_page_title($page_slug, $page_title, '<h1>', '</h1>', false);
- else
- mso_page_title($page_slug, $page_title, '<h1>', '</h1>', true, true, 'private');
То есть смотрим есть ли второй сегмент и если есть, то это одиночная страница и ссылку не выводим.
Заключение
Как видите, создание своих type-файлов довольно простая вещь. Вся пляска происходит вокруг mso_get_pages() с тем чтобы задать правильные условия для вывода.
Я намеренно не предлагаю скачать готовый файл private.php, чтобы вы самостоятельно проделали все операции и разобрались в них.



Комментариев: 3
]]>
На сайте использую старый index (index_old) из шаблона предыдущей версии. Поэтому пришлось добавить строчку is_type('private') и добавить файл в каталог controllers. После этого заработало! Теперь можно использовать блог как "памятка" для некоторых личных записей.
Подумалось, а если создать через админку тип страниц "private" (аналогично blog, static) - будет ли какой-то конфликт между выводом записей? И вообще, тип "private" уже "прошит" в админке?
Вроде бы понятно, как создать закрытый блог для некоего сообщества: создать "группу пользователей", создать новый "тип страниц", после проверок выводить нужные записи.
Спасибо!
]]>
Я рад, что кто-то понял как делать свои типы.
is_type() - отличное решение, хотя, если речь идет о конкретном шаблоне, то можно ограничиться проверкой в index.php сегмента. Тогда к контролеру не нужно будет кидать свой файл.
Тип страниц и статус записи - разные вещи. Статус жестко зашит в систему и его нельзя переопределить. А вот использовать тип страниц можно. Разница только в том, что для получения страниц мы задаем не статус, а нужный тип. Тоже хорошая идея.
]]>
Не смог разобраться как сделать вывод кнопки "Далее..." в списке статей - в дефолтном шаблоне этого вывода нет.