Мой сайт о WordPress и PHP
 
Rss2Email
19 июля 2007

WordPress as CMS (часть 2)

Читали 3602 раза
Рубрика: Лаборатория
Навигация: Главная » WordPress » Лаборатория

В прошлый раз мы выяснили, что WordPress заполняет структуру $wp_query во время своей инициализации.

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

Поскольку мы не можем отключить автоматическое заполнение $wp_query или хотя бы заполнить их минимальными данными, то единственное, что приходит на ум - повторно заполнить $wp_query, но уже теми данными, которые нам нужны.

Но, чтобы продложить исследования, мы должны определиться с NULL-шаблоном.

Файл style.css:

/*
Theme Name:   NULL-тема
Theme URI:    http://maxsite.org/
Description:  Тема для исследований
Version:      1.0
Author:       MAX
Author URI:   http://maxsite.org/
*/

body {
	margin: 0px
	auto; width:
	900px;
	font-size: 10pt;
	font-family: Verdana, Arial, "sans-serif";
}

pre {
	font-size: 8pt;
	width: 100%;
	height: 300px;
	overflow: auto;
	background: #F0F0F0;
	margin: 20px 0;
	border: 1px solid gray;
}

Файл comments.php - полностью пустой.

Файл func.php:

<?php
if ( !function_exists('pr') ) {
	function pr($var) {
		echo '<pre>';
		if ( is_scalar($var) ) echo $var;
			else print_r ($var);
		echo '</pre>';
	}
}
?>

Напомню, что с помощью этой функции мы выводим значение любой переменной.

Файл header.php:

<html><head><title>NULL</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="<?php bloginfo('stylesheet_url'); ?>" type="text/css" media="screen">
</head><body>

Файл main.php:

<?php
	if (have_posts()) :
		while (have_posts()) :
			the_post();
			echo '<h3><a href="'; the_permalink(); echo '">';
				the_title(); echo '</a></h3>';
			echo '<p>'; the_time('j F Y, H:i ');
				the_category(', '); echo '</p>';
			the_content('[Далее...]');
			# wp_link_pages();
			# comments_template();
		endwhile;
	else:
		echo '<h1>Извините, ничего не найдено...</h1>';
	endif; 

	next_posts_link('&laquo; Раньше');
	echo ' | ';
	previous_posts_link('Позже &raquo;');
?>

Файл index.php:

<?php
	require_once('func.php');

	pr($wp_query);
	require('./wp-blog-header.php');
	require_once('header.php');

	echo '<a href="' . get_bloginfo('siteurl') . '">Главная</a>';
	require('main.php');
?>
</body></html>

Итак WordPress первым делом будет обращаться к файлу index.php. (Кстати, это минимальный шаблон на WordPress.) Дальше мы подключаем наш файл функций func.php. Я вынес наши функции в отдельный файл, чтобы не путаться в дальнейшем. Единственная функция, которую мы пока используем, это pr() - я её сделал универсальной, чтобы выводить переменные разных типов (скалярные или комплексные).

Дальше мы сразу смотрим переменную $wp_query. Как вы уже знаете она оказывается уже заполненной. Если пробежаться по её полям, то можно определить, что нам нужно выполнить как минимум одну задачу - заполнить $wp_query только одной записью. Таким образом мы значительно уменьшим нагрузку и избавимся от лишнего.

Делается это очень просто. Идем в админ-панель и в настройках выставляем (чтение) показывать не более 1-й записи. Сохраняем и перегружая страницу видим, что $wp_query действительно оказалась заполненной только для одной записи.

Теперь мы можем заново заполнить $wp_query, но уже как нам нужно. Для этого используется функция query_posts(). Эта функция уничтожает старую $wp_query и заполняет её заново, но у же с учетом указанных параметров.

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

После «require_once('header.php');» добавим такой код:

	query_posts("posts_per_page=3");
	pr($wp_query);

После обновления, видим что действительно, на странице отображается только три последние записи. Правда возник один нюанс.

Попробуйте пролистать "Раньше/позже" и вы увидите, что записи не меняются. Поскольку у вас выведены два окна $wp_query (начальный и измененный нами), то сравнивая их, несложно заметить, что query_vars['paged'] в нашем случае оказался незаполненным. Очевидно, что именно это значение и берется для пагинации страниц.

То есть нам нужно взять изначальное значение и передать его в наш запрос:

query_posts("posts_per_page=3&paged=" . $wp_query->query_vars['paged']);

Теперь у нас всё работает, кроме одного. Нажмите на заголовок любой записи и увидите, что отображается не единичная запись, а та же лента записей. Почему так происходит? Посмотрите на измененную $wp_query и сравните с исходной. У нас оказался тип страницы ([is_home], [is_single] и т.п.) неверным. То есть наш запрос «сбросил» флаги типа страниц в начальное состояние. Теперь, казалось бы, нам нужно просто передать исходные флаги в наш запрос. На самом деле этого делать не следует.

Особенностью WordPress'а является использование типов страниц. В зависимости от этого типа, WordPress по разному заполняет $wp_query и использует для вывода разные шаблоны. Например для главной страницы используется home.php.

Если мы рассматриваем WordPress как CMS, то такая типизация как раз играет нам на руку. Добавив несколько условий, мы можем организовать разный вывод для разных типов данных.

В нашем примере, мы изменили вывод для главной страницы, но изменять его для других страниц мы не хотим. Следовательно, всё, что нам нужно сделать, так это указать условие, при котором мы меняем нужный нам запрос.

if ( is_home() ) {
  query_posts("posts_per_page=3&paged=" . $wp_query->query_vars['paged']);
  pr($wp_query);
}

Всего лишь одно условие и, вуаля!, наш шаблон работает практически идеально. :)

Теперь давайте всё-таки доведем первоначальную задачу по выводу на главной странице двух рубрик по три записи. Для этого в наш запрос мы можем передать номер рубрики «cat=N». Поскольку, всё остальное нам уже понятно, то привожу сразу готовый код для двух рубрик. Номера, естественно, вы уже сами ставьте.

if ( is_home() ) {

	# 1-й проход рубрика 1
	query_posts("cat=1&posts_per_page=3");
	echo '<a href="' . get_bloginfo('siteurl') . '">Главная</a>';
	require('main.php');

	# 2-й проход рубрика 2
	query_posts("cat=2&posts_per_page=3");
	echo '<hr>';
	require('main.php');
}
else
{
	echo '<a href="' . get_bloginfo('siteurl') . '">Главная</a>';
	require('main.php');
}

Как видите, код получается совсем простой.

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

Но об этом в следующий раз. ;)

google.com bobrdobr.ru del.icio.us technorati.com linkstore.ru news2.ru rumarkz.ru memori.ru moemesto.ru

3 комментария к “WordPress as CMS (часть 2)”

  1. iww:

    Хорошая статья !

    Попробуйте пролистать "Раньше/позже" и вы увидите, что записи не меняются. Поскольку у вас выведены два окна $wp_query (начальный и измененный нами), то сравнивая их, несожно заметить, что query_vars['paged'] в нашем случае оказался незаполненным. Очевидно, что именно это значение и берется для пагинации страниц.

    Пропустил буковку

  2. Alexey Maurov:

    Полезно, многие заказчики просят как раз главную страницу не в виде хронологической ленты, а как в разобранном примере.

  3. Денис Чекалов:

    Статья хорошая, но рассчитана на специалиста. Для новичка много непонятного. А самое главное, - здесь у Вас рассказывается о нуль-шаблоне, а вот как все это реализовать в заданном шаблоне, немного неясно. :? :

    К слову, разве нельзя обойтись в данном случае без query?


Оставьте комментарий! (Вы согласны с правилами)

 

:mrgreen: :neutral: :twisted: :arrow: :shock: :smile: :???: :cool: :evil: :grin: :idea: :oops: :razz: :roll: :wink: :cry: :eek: :lol: :mad: :sad: :!: :?:

При добавлении кода (html, php) заменяйте < на &lt; и > на &gt;.
Внимание: антиспам - зверь! Копируйте своё сообщение перед отправкой. На всякий случай.