- SEO-блог Остров МЫСЛЕЙ - http://isle-blog.ru -

Программирование WordPress: категории

Posted By admin On 9 Ноябрь 2009 @ 15:34 In Wordpress | 27 Comments

Для юзабилити, а так же хорошей оптимизации и удобной навигации блога является вывод списка Категорий блога. Рассмотрим простой тег (tag) шаблона (темплейта от англ. template) get_posts [1]), это позволит нам создать практически любой сложности Карту блога, которой будет посвящен следующий топик.

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

Итак, первым делом, нам нужно получить встроенные переменные из функции get_categories [2], выведем все аргументы, что эта функция содержит:

<?php
$args = array(
 'type'						=> 'post',
 'child_of'					=> 0,
 'parent'					=> 0,
 'orderby'					=> 'name',
 'order'					=> 'ASC',
 'hide_empty'				=> true,
 'include_last_update_time'	=> false,
 'hierarchical'				=> 1,
 'exclude'					=> ,
 'include'					=> ,
 'number'					=> ,
 'pad_counts'				=> false
);
?>

Теперь рассмотрим все варианты, которые могут иметь аргументы функции get_categories, а также их значения.

  • type = 'post' / 'link' — nип категории может возвратить результат "пост" или "ссылка". По умолчанию — 'post'.
  • child_of = '0' / '1' — показывает "детскую" (нижний уровень) категорию с идентификатором ID.
  • parent — показывает "родительскую" (верхний уровень) категорию с идентификатором ID [WP 2.8.4].
  • orderby = 'name' / 'ID' — сортировка по имени или ID (номеру идентификации). По умолчанию — 'ID'.
  • order = 'asc' / 'desc' — сортировка категорий от первой к последней или наоборот (ascending — возрастающий; descending — убывающий). По умолчанию — 'asc'.
  • hide_empty = '0' / '1' — тумблер, включающий / выключающий отображение категорий в которых еще нет постов. По умолчанию — '1'.
  • include_last_update_time = '0' / '1' — тумблер, включающий / выключающий отображение последнего обновления категории. По умолчанию — '0'.
  • hierarchical = '0' / '1' (false, tru) — тумблер, включающий / выключающий отображение пустых подкатегорий. По умолчанию — tru (1) — вкл.
  • exclude — убирает из общего списка wp_list_categories, перечислять список категорий через запятую.
  • include = 'list' / 'non' — показывать только перечисленные категории, противоположна exclude. По умолчанию — 'list'.
  • number — возвращает номер категории.
  • pad_counts — подсчитывает количество ссылок или постов ('post', 'link'), включая или не включая "детские" (вложенные, внутренние) категории.

После того, как мы определились какие же параметры и как нам нужно применить при выводе Категорий блога, присвоим все их значения переменной, например, $categories:

<?php $categories = get_categories($cat_args); ?>

С форматом вывода все ясно, но это лишь для одной категории, а чтобы вывести все категории блога, применим один из циклов PHP, например, foreach, заодно и присвоим при каждом проходе цикла аргументы новой переменной, назовем ее $cat:

<?php
  foreach ($categories as $cat) {
    echo $cat->category_nicename;
    echo $cat->cat_name;
    echo ' ('.$cat->category_count.')';
    echo '<br />';
 }
?>

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

<?php
  //Настройки вывода категорий.
  $isle_cat_count_display = 0; //0 - выкл., 1 - вкл.

  //Цикл вывода всех категорий.
  foreach ($categories as $cat) {
    if ($isle_count_display == 1)
      $isle_cat_count = "(".$cat->category_count.")";
    else $isle_cat_count = "";
    echo $cat->category_nicename;
    echo $cat->cat_name;
    echo $isle_cat_count.'<br />';
 }
?>

Таким образом мы можем разделить весь код на две части: настройки и вывод категорий, но в идеале нужно было бы код делить на три части:

  • Настройки вывода Категорий.
  • Обработка вывода категорий — присвоение переменным готовых результатов с оформлением в цикле. При этом нужно все переменные сложить в один массив (одно- двух- или многомерный, в зависимости от количества и сложности выводимых данных).
  • Вывод готовых данных из массива в html-шаблоне.

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

В большинстве случаев для быстрого создания списка Категорий в сайдбаре на первых порах вполне сгодится встроенная функция CMS WordPress wp_list_categories():

<?php
$args = array(
  'show_option_all'		=> ,
  'orderby'				=> 'name',
  'order'				=> 'ASC',
  'show_last_update'	=> 0,
  'style'				=> 'list',
  'show_count'			=> 0,
  'hide_empty'			=> 1,
  'use_desc_for_title'	=> 1,
  'child_of'			=> 0,
  'feed'				=> ,
  'feed_type'			=> ,
  'feed_image'			=> ,
  'exclude'				=> ,
  'exclude_tree'		=> ,
  'include'				=> ,
  'current_category'	=> 0,
  'hierarchical'		=> true,
  'title_li'			=> __( 'Categories' ),
  'number'				=> NULL,
  'echo'				=> 1,
  'depth'				=> 0
);
?>

Пояснения:

  • show_option_all — показывает ссылки на все Категории, если установлен стиль "список" (list). По умолчанию не показывает ссылки на все Категории.
  • orderby = "ID, name, slug, count, term_group" — сортирует Категории по: уникальному номеру идентификации (ID), алфавиту (name), количеству постов в Категории (count) или по группам. По умолчанию orderby = "name".
  • order = "ASC, DESC" — сортирует Категории по возрастанию (ascending) или убыванию (descending). По умолчанию order = "ASC".
  • show_last_updated = "1 (True), 0 (False)" — показывает последнее обновление поста. По умолчанию show_last_updated = "0 (False)".
  • style = "list, none" — стиль показа Категорий: список, без списка. Если установлена метка "без списка", то категории выводятся на новой строке каждая, с html-тегом "<br />". По умолчанию style ="list".
  • show_count = "1 (True), 0 (False)" — тумблер, включающий / выключающий показ количества постов в Категориях. По умолчанию show_count = "0 (False)".
  • hide_empty = "1 (True), 0 (False)" — тумблер, включающий / выключающий показ "пустых" Категорий, в которых нет еще постов. По умолчанию hide_empty = "1 (True)".
  • use_desc_for_title = "1 (True), 0 (False)" — устанавливает для категорий описание (Description) в html-тег "title" (<a title="Description: ..." href="...). Например, при наводе мыши на ссылку Категории в подсказке будет надпись "Смотреть все посты в Категории 'название категории'."). По умолчанию use_desc_for_title = "1 (True)".
  • child_of — показывает внутренние Категории ("детские"). Не имеет метки по умолчанию.
  • feed — показывает ссылку каждой Категории на фид типа RSS2.
  • feed_type — устанавливает тип фида (Атом, RSS и др.).
  • feed_image — устанавливает feedicon (картинку для фида). Этот параметр (feed_image) перекрывает парамет feed.
  • exclude — удаляет одну или несколько Категорий из списка Категорий. Нужно перечислить UID'ы (unique ID — уникальный идентификатор) через запятую. Метка параметра child_of устанавливается автоматически в значение "false" при применении.
  • exclude_tree — убирает из списка Категорий "дерево-Категорий" (WP 2.7.1).
  • include — выводит список Категорий только из установленных UID'ов Категорий, перечисленных через запятую по ASC-порядку.
  • hierarchical = "1 (True), 0 (False)" — показывает подкатегории вложенным списком (отдельный иерархический список, столбик) или просто перечисляет в одну строчку через запятую. По умолчанию hierarchical = "1 (True)".
  • title_li — выводит заголовок списка Категорий, по желанию заголовок можно обрамить дополнительными html-тегами или не выводить заголовок вовсе. По умолчанию "_Categories" ("Категории").
  • number — задает количество выводимых Категорий. По умолчанию выводятся все Категории.
  • показывает порядковый номер выводимой Категории (1, 2, 3, ...).
  • echo = "1 (True), 0 (False)" — указывает: нужно показать результат (вывести на монитор) или сохранить его в переменной для следующего вывода (WP 2.3). По умолчанию echo = "1 (True)".
  • depth = "0, -1, 1, n" — контролирует глубину вывода списка Категорий, т.е. указывает сколько уровней в иерархии Категорий будет показано в общем списке Категорий. Значения метки: 0 — все категории и подкатегории ("дети"); -1 — все Категории плавающие (flat), т.е. без отступов вправо (indent), перекрывает hierarchical; 1 — показывать только верхние Категории без вложенных (только "родители"); n — число, определяющее уровень глубины (уровень вложенности Категорий в выводимом списке). По умолчанию depth = "0".
  • current_category — устанавливает стиль "current-cat", позволяющий выделить (подсветить) текущую категорию, в которой в данный момент находится читатель (WP 2.6). Перекрывает "current" в условии if (is_current) {...}.

Пример применения:

<?php
  wp_list_categories('
    orderby=name & order=ASC
    & show_last_updated=1 & show_count=1
    & feed_image=/wp-content/themes/default/images/rss.png
    & hide_empty=1 & exclude=38
  ');
?>

Другим способом (в цикле) "текущую" категорию можно подсветить так:

<?php
  $cats = get_categories('hide_empty=0&child_of=16&depth=2');
  foreach ((array)$cats as $cat) {
    $catID = $cat->cat_ID;
    $catnm = $cat->cat_name;
    if ($category[0]->cat_ID == $catID && $tagged == '')
      $class = 'class="current"';
    else $class = 'class=""';
  echo '<li id="cat-'.$catID.'" '.$class.'><a>'.$catnm.'</a></li>';
}
?>

Источники:

Попробуем вытащить некоторые значения Категорий из БД.

<?php
  //Количество категорий (рубрик).
  $numcats = $wpdb->get_var("
    SELECT COUNT(*)
    FROM $wpdb->term_taxonomy
    WHERE parent=0 //Верхний уровень
    AND taxonomy='category'
  ");
  echo $numcats;
?>

А можно так:

<?php
$cats = 0; //Начало отсчета кол-ва Категорий.
$categories = get_categories($args);
foreach ($categories as $cat) {
  if ($posts) $cats++; //Тоже, что 'hide_empty'='true'
}
//Если Категорий больше 0, то выводим их кол-во.
if ($cats != 0) echo $cats;
?>

Если нам нужно только верхний уровень категорий (только "родительские" Категории), то прописываем строчку "WHERE parent=0" в запросе к БД, это даст тот же результат, что и "depth=1".

Попробуем узнать ID Категории по ее данным:

<?php
  //ID Категории по имени.
  $id1 = get_category_by_slug('WordPress')->term_id;
  //ID Категории текущей через встроенную функцию WP.
  $id0 = get_category();
  $id2 = $id0->term_id; //$id2 = $id0->cat_ID;
  //ID Категории текущей напрямую через функцию PHP.
  $id3 = (int) $_GET['cat_ID'];
  echo $id1.', '.$id2.', '.$id3;
?>

Многие элементы, ID или другие метки которых нужно, недавно обобщили и теперь, в зависимости от группы, используется однотипная запись "term_id" вместо уточнения каждого элемента, например, post_ID, page_ID, category_ID, comment_ID, autor_ID, user_ID, tag_ID и т.д., что значительно упрощает создание запросов в поиске нужных меток / аргументов функций. Пока еще не все элементы перекрытия совмещены, но, надеюсь, скоро будут. Для большей "эластичности" в иерархии (taxonomy) созданы новые таблицы в БД: wp_terms, wp_term_relationships, wp_term_taxonomy.

Попробуем найти всех детей и родителей для Категории с ID:

<?php
  //Найдем всех "родителей" (внешние Категории).
  $descendants = get_categories(array('child_of'=>ID));
  //Найдем всех "детей" (вложенные Категории).
  $children = get_categories(array('parent'=>ID));
  //Распечатаем массивы для одной Категории.
  echo $descendants.'<br /><br />'.$children;
  //Если нужно для всех Категорий, то задаем цикл.
  foreach ($children as $child) {echo '<li>'.$child->cat_name.'</li>';}
?>

Некоторые блогеры любят ставить иконки для каждой категории индивидуально. Это можно сделать в трех вариантах: 1 — вручную прописать в коде (или в стилях) путь к каждой иконке; 2 — можно проставить иконки автоматом для всех категорий, но под каждую Категорию нужно обязательно разместить иконку, иначе напечатается пустая рамка и будет смотреться некрасиво; 3 — можно проставить автоматом иконки для всех категорий, но с проверкой существования каждой иконки и, если иконки под Категорию с ID, не существует, то поставить дефолтную иконку, общую для всех категорий.

Вариант 1. Вывод картинки по имени категории.

<?php
  $cat = get_the_category();
  $cat = $cat[0];
  $cat_nm = $cat->cat_name;
  $scr = get_bloginfo('template_directory');
  $scr .= '/icons/'.$cat_nm.'.png';
  echo '<img src="'.$scr.'" alt="Category Icon" />
?>

Вариант 2. Вывод картинки по ID для всех Категорий (гораздо удобней).

<?php
  foreach((get_the_category()) as $cat) {
    $scr = get_bloginfo('template_directory');
    $scr .= '/icons/cat-'.$cat->cat_ID.'.png';
    echo '<img src="'.$scr.'" alt="Category Icon" />';
}
?>

Вариант 3.

<?php
  $post_thumbnail = get_post_custom_values('thumbnail');
  if ($post_thumbnail)
    echo '<img src="'.$post_thumbnail.'" alt="'.the_title().'" class="thumbnail" />';
  else {
    $url_path = str_replace(get_bloginfo('url'), '', get_bloginfo('template_directory'));
    $cat_img_path = get_bloginfo('template_directory').'/images/';
    $cat_img_name = $_SERVER['DOCUMENT_ROOT'].$url_path. '/images/isle_cat_thumbnail_';
    foreach ((get_the_category()) as $category) {
      $cat_id = $category->cat_ID;
      $cat_nm = $category->cat_name;
      $file_img = $cat_img_name.$cat_id.'.png';
      if (file_exists($file_img))
        $cat_img = $cat_img_path.'isle_cat_thumbnail_'.$cat_id.'.png';
      else $cat_img = $cat_img_path.'isle_cat_thumbnail_default.png';
      $alt = '#'.$cat_id.' '.$cat_nm.'. ';
      ?><img src="<?php echo $cat_img; ?>"
        alt="<?php echo $alt; the_title(); ?>" class="thumbnail" />
<?php } ?>

Запись

<?php $post_thumbnail = get_post_custom_values('thumbnail'); ?>

Можно записать и так:

<?php $post_thumbnail = get_post_meta($post->ID,'thumbnail',true); ?>

Именно так реализованны картинки 125х125 px на этом блоге — Остров МЫСЛЕЙ [4]. В дополнительном поле нужно ввести ключ "thumbnail" и путь к картинке, чтоб она отразилась для конкретного поста, иначе картинка будет назначена по умолчанию для всех постов конкретной Категории, если нет картинки в папке для конкретной Категории, то буден выведена дефолтная картинка, установленная для всех категорий. Данный код можно вставить в файлы шаблона Темы CMS WordPress index.php (шаблон главной страницы) и single.php (шаблон полной статьи). Если требуется разместить что-либо (какую-то информацию) или просто изменить стиль одной или нескольких отдельных Категории, то можно сделать это проще, например, таким образом:

<?php
  if (in_category(1)) echo '<div class="cat-1"></div>';
  elseif (in_category(2)) echo '<div class="cat-2"></div>';
  else echo '';
?>

И напоследок. Если нужно реализовать, например, под шапкой блога сайдбар, показывающий место нахождение читателя: Остров МЫСЛЕЙ >> Категория >> Пост, то это можно сделать, например, вот так:

<?php
  $blog_url = get_bloginfo(url);
  $blog_name = get_bloginfo(name);
  $blog_desc = get_bloginfo(description);
  $category = get_the_category();
  $cat_url = get_category_link();
  $cat_name = $category->cat_name;
  $cat_desc = $category->category_description;
  $post_name = get_the_title();
  $post_url = get_permalink();
  echo '<a href="'.$blog_url.'" title="'.$blog_desc.'">'.$blog_name.'</a> >> ';
  echo '<a href="'.$cat_url.'" title="'.$cat_desc.'">'.$cat_name.'</a> >> ';
  echo $post_name;
?>

В CMS WordPress имеются также встроенные функции для быстрой ручной подгонки is_category и in_category. Функция is_category позволяет определить, что открыто в данный момент нужная страница Категории шаблона Архива (зайти в Архив можно через Календарь). Функция in_category позволяет определить, что открыто в данный момент нужная Категория.

<?php
  //Выполнить условие, если открыта любая Категория Архива.
  if (is_category()) {}
  //... если открыта Категория с ID='id'.
  if (is_category('id')) {}
  //... если открыта Категория с именем Name='name' или Slug='slug'.
  if (is_category('name')) {}
  //... если открыта Категория с именем Name='name', Slug(NiceName)='slug' или ID='id'.
  if ( is_category(array(id,'name','slug')) ) {}
?>
<?php
  //Выполнить условие, если открыта любая Категория блога.
  if (in_category()) {}
  //... если открыта Категория с ID='id'.
  if (in_category('id')) {}
  //... если открыта Категория с именем Name='name' или Slug='slug'.
  if (in_category('name')) {}
  //... если открыта Категория с именем Name='name', Slug(NiceName)='slug' или ID='id'.
  if ( in_category(array(id,'name','slug')) ) {}
?>

Последний примерчик на дорожку... Распечатаем 5 подкатегорий в каждой родительской категории, если открыта любая родительская Категория блога.

<?php
#Проверим, находимся ли мы внутри какой-либо категории.
if (in_category()) {
  #Узнаем ID текущей категории.
  $id_current = (isset($_GET['cat_ID']) && trim($_GET['cat_ID'])!='')?(int)$_GET['cat_ID']:false;
  #Узнаем, находимся ли мы в категории-родителе.
  $descendants = get_categories(array('child_of'=>$id_current));
  if (isset($descendants) && is_array($descendants) && $descendants!=null) {
	#Если мы в родительской категории, то собираем ее дитей.
	$children = get_categories(array('hide_empty'=>0,'parent'=>$id));
	$num = 5; #Количество выводимых подкатегорий (дитей).
	$c = count($children); #Всего дитей у текущего родителя.
	$blog = get_bloginfo('wpurl'); #Адрес нашего блога.
	$j = ($c>$num)?$num:$c; unset($num,$c);
	for ($i=0;$i<$j;$i++) {
	  $name = $children[$i]->name; #Название подкатегории.
	  $descr = $children[$i]->description; #Подробное описание подкатегории.
	  $url = $children[$i]->slug; #Путь подкатегории на англ.
	  $parent = $children[$i]->parent; #Кто родитель.
	  $posts = $children[$i]->count; #Количество постов в подкатегории.
	  $href = "$blog/$parent/$url";
	  $link = '<a href="'.$href.'" title="'.$descr.'">'.$name.'</a>';
	  $cats[$name] = "<li>$link ($posts)</li>";
	}
	#Проверяем, получили ли мы массив подкатегорий,
	#если да и он не пустой, то печатаем его.
	if (isset($cats) && is_array($cats) && $cats!=null) {
	  ksort($cats); $out = '<ul>'.explode("\n\t",$cats).'</ul>';
	  echo $out;
	}
  }
} #if (in_category())...
?>

Если нужно любую из записей видеть только администратору, а от посетителей нужно скрыть, то можно любую из записей заключить в такое условие:

<?php if (current_user_can('level_10')) { ?>

Любая запись, видимая только администратору.

<?php } ?>

Продвинутым пользователям CMS WordPress:

На странице перечня всех встроенных функций Function_Reference [6]) можно найти любые поддерживаемые аргументы каждой встроенной функции, но поскольку Кодекс обновляется реже, чем выходят новые версии CMS WordPress, то последние версии API следует искать в файлах самого CMS WordPress, например, для категорий это файл /wp-includes/category.php.

Проблемы, возникающие у новичков.

Несколько раз спрашивали, почему распечатать массив можно (функция PHP — print_r()), а получить ячейку — нет, выводится ошибка:

"Cannot use object of type stdClass as array"

Дело в том, что в PHP могут быть написаны как "пользовательские функции", так и "классы". В классах создаются объекты, они распечатываются функцией print_r() на экран, но присвоить этот объект переменной нельзя простым присвоением:

$name = $children[$i]['name'];

Нужно сослаться на ячейку объекта, а не массива:

$name = $children[$i]->name;

Чтобы преобразовать одно в другое в PHP, можно записать так:

$names =(object)$mynames; либо: $names =(array)$mynames;

Ну вот, вроде, все разобрали, теперь мы умеем выводить Посты и Категории. В следующий раз попробуем создать Карту блога [18] с нужными нам свойствами, прежде всего, нужными ссылками, расположенными в удобном порядке, а в этом топике, если есть какие-то вопросы или пожелания, пишите, спрашивайте, добавлю примеров.


Article printed from SEO-блог Остров МЫСЛЕЙ: http://isle-blog.ru

URL to article: http://isle-blog.ru/wordpress/get_categories/

URLs in this post:

[1] get_posts: http://isle-blog.ru/wordpress/get_posts/

[2] get_categories: http://codex.wordpress.org/Function_Reference/get_categories

[3] http://codex.wordpress.org/Template_Tags/wp_list_categories: http://codex.wordpress.org/Template_Tags/wp_list_categories

[4] Остров МЫСЛЕЙ: http://isle-blog.ru/

[5] Conditional_Tags: http://codex.wordpress.org/Conditional_Tags

[6] Function_Reference: http://codex.wordpress.org/Function_Reference

[7] get_category_link: http://codex.wordpress.org/Function_Reference/get_category_link

[8] get_category_parents: http://codex.wordpress.org/Function_Reference/get_category_parents

[9] is_category: http://codex.wordpress.org/Function_Reference/is_category

[10] in_category: http://codex.wordpress.org/Function_Reference/in_category

[11] http://codex.wordpress.org/: http://codex.wordpress.org/

[12] Category_Templates: http://codex.wordpress.org/Category_Templates

[13] Template_Tags: http://codex.wordpress.org/Template_Tags

[14] Category:Template_Tags: http://codex.wordpress.org/Category:Template_Tags

[15] Templates: http://codex.wordpress.org/Templates

[16] Database_Description: http://codex.wordpress.org/Database_Description

[17] http://wordpress.org/tags/get_categories: http://wordpress.org/tags/get_categories

[18] Карту блога: http://isle-blog.ru/sitemap/

Copyright © 2008 SEO-блог Остров МЫСЛЕЙ. All rights reserved.