WordPress as CMS (часть 2)

Рубрика: WordPress -> Лаборатория
Четверг, 19 июля 2007 г.
Просмотров: 2628
Подписаться на комментарии по RSS
]]>
]]>

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

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

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

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

Файл style.css:

  1.  /*
  2.  Theme Name: NULL-тема
  3.  Theme URI: http://maxsite.org/
  4.  Description: Тема для исследований
  5.  Version: 1.0
  6.  Author: MAX
  7.  Author URI: http://maxsite.org/
  8.  */
  9.  body {
  10.   margin: 0px
  11.   auto; width:
  12.   900px;
  13.   font-size: 10pt;
  14.   font-family: Verdana, Arial, "sans-serif";
  15.  }
  16.  pre {
  17.   font-size: 8pt;
  18.   width: 100%;
  19.   height: 300px;
  20.   overflow: auto;
  21.   background: #F0F0F0;
  22.   margin: 20px 0;
  23.   border: 1px solid gray;
  24.  }

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

Файл func.php:

  1.  <?php
  2.  if ( !function_exists('pr') ) {
  3.   function pr($var) {
  4.   echo '<pre>';
  5.   if ( is_scalar($var) ) echo $var;
  6.   else print_r ($var);
  7.   echo '</pre>';
  8.   }
  9.  }
  10.  ?>

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

Файл header.php:

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

Файл main.php:

  1.  <?php
  2.   if (have_posts()) :
  3.   while (have_posts()) :
  4.   the_post();
  5.   echo '<h3><a href="'; the_permalink(); echo '">';
  6.   the_title(); echo '</a></h3>';
  7.   echo '<p>'; the_time('j F Y, H:i ');
  8.   the_category(', '); echo '</p>';
  9.   the_content('[Далее...]');
  10.   # wp_link_pages();
  11.   # comments_template();
  12.   endwhile;
  13.   else:
  14.   echo '<h1>Извините, ничего не найдено...</h1>';
  15.   endif;
  16.   next_posts_link('&laquo; Раньше');
  17.   echo ' | ';
  18.   previous_posts_link('Позже &raquo;');
  19.  ?>

Файл index.php:

  1.  <?php
  2.   require_once('func.php');
  3.   pr($wp_query);
  4.   require('./wp-blog-header.php');
  5.   require_once('header.php');
  6.   echo '<a href="' . get_bloginfo('siteurl') . '">Главная</a>';
  7.   require('main.php');
  8.  ?>
  9.  </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');» добавим такой код:

  1.  query_posts("posts_per_page=3");
  2.   pr($wp_query);

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

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

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

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

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

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

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

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

  1.  if ( is_home() ) {
  2.   # 1-й проход рубрика 1
  3.   query_posts("cat=1&posts_per_page=3");
  4.   echo '<a href="' . get_bloginfo('siteurl') . '">Главная</a>';
  5.   require('main.php');
  6.   # 2-й проход рубрика 2
  7.   query_posts("cat=2&posts_per_page=3");
  8.   echo '<hr>';
  9.   require('main.php');
  10.  }
  11.  else
  12.  {
  13.   echo '<a href="' . get_bloginfo('siteurl') . '">Главная</a>';
  14.   require('main.php');
  15.  }

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

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

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

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

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

Вы можете получать новые комментарии к этой записи по RSS или оформить подписку на все комментарии сайта. Или даже на все новые записи сайта. Не знаете, как это сделать?
  1. 2007-07-21 в 09:14:17 | iww

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

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

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

  2. 2007-08-13 в 01:46:57 | Alexey Maurov

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

  3. 2008-08-16 в 07:44:58 | Денис Чекалов

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

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

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

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

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

Если вы уже зарегистрированы как комментатор или хотите зарегистрироваться, укажите пароль и свой действующий 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

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