MaxSite CMS для чайников. Шаблонная практика

8 января 2010 г. Просмотров: 5698 RSS 7
MaxSite CMS » Для чайников

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


twitter.com facebook.com vkontakte.ru odnoklassniki.ru mail.ru friendfeed.com google.com yandex.ru
Комментариев: 7
  1. На сайте использую старый index (index_old) из шаблона предыдущей версии. Поэтому пришлось добавить строчку is_type('private') и добавить файл в каталог controllers. После этого заработало! Теперь можно использовать блог как "памятка" для некоторых личных записей.

    Подумалось, а если создать через админку тип страниц "private" (аналогично blog, static) - будет ли какой-то конфликт между выводом записей? И вообще, тип "private" уже "прошит" в админке?

    Вроде бы понятно, как создать закрытый блог для некоего сообщества: создать "группу пользователей", создать новый "тип страниц", после проверок выводить нужные записи.

    Спасибо!

  2. На сайте использую старый index (index_old) из шаблона предыдущей версии. Поэтому пришлось добавить строчку is_type('private') и добавить файл в каталог controllers. После этого заработало!

    Я рад, что кто-то понял как делать свои типы. smile is_type() - отличное решение, хотя, если речь идет о конкретном шаблоне, то можно ограничиться проверкой в index.php сегмента. Тогда к контролеру не нужно будет кидать свой файл.

    Подумалось, а если создать через админку тип страниц "private" (аналогично blog, static) - будет ли какой-то конфликт между выводом записей? И вообще, тип "private" уже "прошит" в админке?

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

  3. Не смог разобраться как сделать вывод кнопки "Далее..." в списке статей - в дефолтном шаблоне этого вывода нет.

  4. Две недели периодически пытаюсь запустить этот пример, т.к. очень важно научиться делать свои типы. Проблема в том , что после "и вуаля!" - ничего не происходит. Ошибка 404 не меняется на содержимое нового типа.

    Методом МАX-а тоже пробовал, кинуть файл в папку контроллеры и is_type('private').В этом случае вверху появляется надпись private, а на месте контента все равно Ошибка 404.long face

    В чем может быть причина?

    Можете выслать прямо архив рабочего сайта с этим работающим примером на мыло?

  5. А записи приватные есть?

  6. Добрый день Максим не могу понять как работать с личными записями, как мне их создавать?

  7. Как обычные записи, только указываете «Личное».

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

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

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

(войти без комментирования)

Имя и сайт используются только при регистрации

Авторизация: Loginza.

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