Черствый category php. Самый простой и логичный ЧПУ для PHP

Проверяет принадлежит ли текущий (или указанный) пост к указанной категории (можно указать несколько категорий). Условный тег.

Проверяется прямая принадлежность поста к категории, т.е. содержит ли указанная категория текущий/указанный пост. Если, например, пост принадлежит родительской категории или дочерней к указанной, то функция вернет false.

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

in_category() можно использовать внутри Цикла WordPress или за пределами Цикла WordPress, но на отдельной странице поста (single.php). Или можно использовать где угодно, если указать какой именно пост нужно проверить.

✈ 1 раз = 0.003672с = очень медленно | 50000 раз = 1.00с = очень быстро | PHP 7.1.5, WP 4.8.1

Хуков нет.

Возвращает

true, если условие выполняется и false, если нет.

Использование

if(in_category($category, $post)){ // ... } $category(строка/массив/число) (обязательный)

ID, название или ярлык (slug) категории, которую нужно проверить принадлежит ли ей пост.

Можно указать несколько параметров в массиве вперемешку.
По умолчанию: нет

$post(число/объект) ID или объект поста. По умолчанию текущий пост определяется автоматически внутри Цикла WordPress или на странице поста.
По умолчанию: нет

Примеры

#1 Проверка текущего поста внутри Цикла WordPress.

in_category часто используется внутри Цикла, чтобы проверить относится ли пост к указанной категории, если "да", то сделать какие-либо действия:

If (in_category("pachyderms")) { // действия, если пост относится к категории "pachyderms" } elseif (in_category(array("Tropical Birds", "small-mammals"))) { // действия, если пост относится к одной из категорий "Tropical Birds", "small-mammals" } else { // если никакие из предыдущих условий не выполнены. }

П.С. Лучше указывать не названия, а ID категории для проверок

#2 Проверка текущего поста за пределами Цикла.

На странице поста (обычно это файл шаблона single.php) проверку можно выполнять за пределами Цикла:

If (in_category("fruit")) { include "single-fruit.php"; } elseif (in_category("vegetables")) { include "single-vegetables.php"; } else { // Ниже начинается Цикл WordPress if (have_posts()) : while (have_posts()) : the_post(); // ... }

#3 Проверка принадлежности поста к текущей или вложенной в текущую категории

Бывают случаи, когда нужно проверить относиться ли пост к дереву категорий. Например, мы указываем в проверке ID категории 60, а пост принадлежит категории 70, которая является дочерней к категории 60. Но in_category() вернет в данном случае false, а иногда нужно чтобы вернула true.

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

If(in_category(array("Малина", "Яблоки", "Бананы", "Груши", "Сливы"))) { // Действие если выполнено условие }

Такой подход проверки, совершенно не гибкий, потому что если мы добавим новую подкатегорию к категории "Фрукты", нам так же нужно будет добавить её и в массив, для проверки.

Чтобы избежать таких сложностей можно воспользоваться такой проверкой:

// Проверка принадлежности поста к категории "Фрукты" или любой вложенной в эту категорию категории. if (in_category(11) || post_is_in_descendant_category(11)) { // Здесь все "фрукты" }

Также, менее желательный, но вариант - указать названия:

Post_is_in_descendant_category(get_term_by("name", "fruit", "category"))

А вот сама функция post_is_in_descendant_category() :

Function post_is_in_descendant_category($cats, $_post = null){ foreach ((array) $cats as $cat) { // get_term_children() accepts integer ID only $descendants = get_term_children((int) $cat, "category"); if($descendants && in_category($descendants, $_post)) return true; } return false; }

#4 Древовидная проверка принадлежности к термину

Проверим входит ли пост в термин произвольной таксономии (будем проверять и дочерние термины к указанному):

If(has_term(11, "taxonomy", $post->ID) || post_is_in_descendant_term(11, "taxonomy", $post->ID)){ // Текущая запись в термине 11 или в его дочернем термине }

Функция post_is_in_descendant_term() :

Function post_is_in_descendant_term($term_ids, $taxonomy = "category", $post = null){ foreach((array) $term_ids as $term_id){ $descendants = get_term_children((int) $term_id, $taxonomy); if ($descendants && has_term($descendants, $taxonomy , $post)) return true; } return false; }

Приветствую всех читателей блога WordPress Inside в 2011 году, поздравляю с наступившими и наступающими праздниками, желаю много здоровья, счастья и радости на следующие 360 дней. Как и обещал в своей статье про планы на будущий 2011 год занимаюсь по чуть-чуть улучшением всех своих основных блогов — обновляю системы, ставлю последние версии плагинов и копаюсь в шаблонах ради оптимизации и исправления ошибок. Работал это крайне сложная, я бы даже сказал очень кропотливая — находишь одну неточность, решаешься ее исправить и перед тобой 5 отдельных проектов, для каждого из которых нужно внести правки. Ну, раз я уже запланировал все это сделать, назад дороги нет, заодно в процессе получаю дополнительный опыт и уже нашел штук 5-6 тем для новых постов в блог:) Сегодня поговорим о категориях и функциях для их отображения.

В одной из прошлых статей блога я публиковал хак который помогает . Данное решение использовалось для функции вывода списка категорий в сайдбаре с помощью функции wp_list_categories. На выходе вы получали записи вроде этой:

Безопасность

Если уж для seo атрибут title имеет хоть какое-то значение, то куда полезнее там было бы разместить просто название категории, а не весь этот ненужных текст. Собственно, указанная выше ссылка на хак помогала решить эту проблему. Но вот ни задача, все это было справедливо (работало) для , которая позволяла предварительно обработать полученный список не выводя его сразу же. Но что делать с другими функциями для вывода категорий? — вот в чем вопрос.

Например, я сегодня совершенно случайно обнаружил, что куча ненужного текста в атрибут title ссылки пишется и при отображении списка категорий для конкретного поста.

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

Функция get_the_category

Синтаксис функции get_the_category достаточно прост:

cat_name; ?>

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

ID ) ; var_dump ($categories ) ; ?>

ID); var_dump($categories); ?>

Для этого в качестве параметра функции нужно передавать id поста, что и происходит в коде.

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

cat_name . " " ; } ?>

cat_name . " "; } ?>

Ну, и напоследок, немного поразмыслив получился хак для вывода списка категории для поста без использования функции the_category, которую мы успешно заменяем на get_the_category. Если вы хотите добавить код непосредственно в то место шаблона, где выводятся категории, например, файл archive.php, то пишем что-то вроде:

Можно, в принципе разместить код для отображения категорий в файле функций, а потом в файлах шаблона поменять the_category на новую функцию, например, под названием my_thecat(). Конечно, не забудьте предварительно перед заменой добавить соответствующий код в файл функций functions.php:

function my_thecat() { global $post ; foreach ((get_the_category($post -> ID ) ) as $category ) { echo " cat_ID ) . "" title="" . $category -> cat_name . "">" . $category -> cat_name . "; " ; } }

function my_thecat() { global $post; foreach((get_the_category($post->ID)) as $category) { echo "cat_ID)."" title="".$category->cat_name."">".$category->cat_name."; "; } }

Потестировал, все работает. Остается лишь один вопрос — насколько это все полезно и крайне необходимо. Если у вас один блог с постоянным дизайном, который вы хотите сделать самым лучшим, то можно потратить пару минут и внести соответствующие изменения. В случае если у вас таких блогов много, думаю, особой seo выгоды манипуляция с title не принесет в плане, проще купить ссылок в Rotapost на все эти проекты — кстати эксперимент по подъему тИЦ в системе успешно и позитивно завершен, скоро будет отчет об этом.

Вывод категорий кастомных записей

В комментариях подсказывают, что примеры, указанные выше, не работают для кастомных (пользовательских) типов записей. Я с этой задачей не сталкивался, поэтому могу вам лишь посоветовать погуглить решение в англоязычных блогах по ключу wordpress custom post type show category или же воспользоваться подсказкой пользователя Stinker (из комментариев). В месте вывода категорий нужно просто вставить код:

Где categoria_video — это таксономия пользовательской записи (она же кастомная). А теперь более подробно от куда и что. Например у нас есть:

// Тип записи Видео if ( ! function_exists ( "video_cp" ) ) { function video_cp() { $labels = array ( "name" => _x( "Видео" , "Post Type General Name" , "video" ) , "singular_name" => _x( "Видео" , "Post Type Singular Name" , "video" ) , "menu_name" => __( "Видео" , "video" ) , "parent_item_colon" => __( "Родительский:" , "video" ) , "all_items" => __( "Все видеоматериалы" , "video" ) , "view_item" => __( "Просмотреть" , "video" ) , "add_new_item" => __( "Добавить новое видео" , "video" ) , "add_new" => __( "Добавить видео" , "video" ) , "edit_item" => __( "Редактировать видео" , "video" ) , "update_item" => __( "Обновить видео" , "video" ) , "search_items" => __( "Найти видео" , "video" ) , "not_found" => __( "Не найдено" , "video" ) , "not_found_in_trash" => __( "Не найдено в корзине" , "video" ) , ) ; $args = array ( "labels" => $labels , "supports" => array ( "title" , "editor" , "excerpt" , ) , "taxonomies" => array ( "categoria_video" ) , // категория, которую мы создадим ниже (она же таксономия) "public" => true , "menu_position" => 5 , "menu_icon" => "dashicons-id-alt" , ) ; register_post_type( "video" , $args ) ; } add_action( "init" , "video_cp" , 0 ) ; // инициализируем } if ( ! function_exists ( "categoria_video" ) ) { // Категории для вакансий function categoria_video() { $labels = array ( "name" => _x( "Категории Видео" , "Taxonomy General Name" , "categoria_video" ) , "singular_name" => _x( "Категория Видео" , "Taxonomy Singular Name" , "categoria_video" ) , "menu_name" => __( "Категории" , "categoria_video" ) , "all_items" => __( "Категории" , "categoria_video" ) , "parent_item" => __( "Родительская категория Видео" , "categoria_video" ) , "parent_item_colon" => __( "Родительская категория Видео:" , "categoria_video" ) , "new_item_name" => __( "Новая категория" , "categoria_video" ) , "add_new_item" => __( "Добавить новую категорию" , "categoria_video" ) , "edit_item" => __( "Редактировать категорию" , "categoria_video" ) , "update_item" => __( "Обновить категорию" , "categoria_video" ) , "search_items" => __( "Найти" , "categoria_video" ) , "add_or_remove_items" => __( "Добавить или удалить категорию" , "categoria_video" ) , "choose_from_most_used" => __( "Поиск среди популярных" , "categoria_video" ) , "not_found" => __( "Не найдено" , "categoria_video" ) , ) ; $args = array ( "labels" => $labels , "hierarchical" => true , "public" => true , ) ; register_taxonomy( "categoria_video" , array ( "video" ) , $args ) ; } add_action( "init" , "categoria_video" , 0 ) ; // инициализируем }

// Тип записи Видео if (! function_exists("video_cp")) { function video_cp() { $labels = array("name" => _x("Видео", "Post Type General Name", "video"), "singular_name" => _x("Видео", "Post Type Singular Name", "video"), "menu_name" => __("Видео", "video"), "parent_item_colon" => __("Родительский:", "video"), "all_items" => __("Все видеоматериалы", "video"), "view_item" => __("Просмотреть", "video"), "add_new_item" => __("Добавить новое видео", "video"), "add_new" => __("Добавить видео", "video"), "edit_item" => __("Редактировать видео", "video"), "update_item" => __("Обновить видео", "video"), "search_items" => __("Найти видео", "video"), "not_found" => __("Не найдено", "video"), "not_found_in_trash" => __("Не найдено в корзине", "video"),); $args = array("labels" => $labels, "supports" => array("title", "editor", "excerpt",), "taxonomies" => array("categoria_video"), // категория, которую мы создадим ниже (она же таксономия) "public" => true, "menu_position" => 5, "menu_icon" => "dashicons-id-alt",); register_post_type("video", $args); } add_action("init", "video_cp", 0); // инициализируем } if (! function_exists("categoria_video")) { // Категории для вакансий function categoria_video() { $labels = array("name" => _x("Категории Видео", "Taxonomy General Name", "categoria_video"), "singular_name" => _x("Категория Видео", "Taxonomy Singular Name", "categoria_video"), "menu_name" => __("Категории", "categoria_video"), "all_items" => __("Категории", "categoria_video"), "parent_item" => __("Родительская категория Видео", "categoria_video"), "parent_item_colon" => __("Родительская категория Видео:", "categoria_video"), "new_item_name" => __("Новая категория", "categoria_video"), "add_new_item" => __("Добавить новую категорию", "categoria_video"), "edit_item" => __("Редактировать категорию", "categoria_video"), "update_item" => __("Обновить категорию", "categoria_video"), "search_items" => __("Найти", "categoria_video"), "add_or_remove_items" => __("Добавить или удалить категорию", "categoria_video"), "choose_from_most_used" => __("Поиск среди популярных", "categoria_video"), "not_found" => __("Не найдено", "categoria_video"),); $args = array("labels" => $labels, "hierarchical" => true, "public" => true,); register_taxonomy("categoria_video", array("video"), $args); } add_action("init", "categoria_video", 0); // инициализируем }

Спасибо пользователю Stinker за подсказку, возможно, вам она пригодится.

P.S. Постовой. В одном из блогов рунета была найдена замечательная подборка тем wordpress портфолио из 17-ти бесплатных качественных шаблонов.

Возвращает массив объектов содержащих информацию о категориях.

Параметры передаваемые этой функции очень похожи на параметры передаваемые функции wp_list_categories() и могут быть переданы как в виде массива, так и в виде строки запроса: type=post&order=DESC .

✈ 1 раз = 0.005625с = очень медленно | 50000 раз = 11.98с = медленно | PHP 7.1.11, WP 4.9.5

Использование

$categories = get_categories($args);

Шаблон использования

$categories = get_categories(array("taxonomy" => "category", "type" => "post", "child_of" => 0, "parent" => "", "orderby" => "name", "order" => "ASC", "hide_empty" => 1, "hierarchical" => 1, "exclude" => "", "include" => "", "number" => 0, "pad_counts" => false, // полный список параметров смотрите в описании функции http://wp-kama.ru/function/get_terms)); if($categories){ foreach($categories as $cat){ // Данные в объекте $cat // $cat->term_id // $cat->name (Рубрика 1) // $cat->slug (rubrika-1) // $cat->term_group (0) // $cat->term_taxonomy_id (4) // $cat->taxonomy (category) // $cat->description (Текст описания) // $cat->parent (0) // $cat->count (14) // $cat->object_id (2743) // $cat->cat_ID (4) // $cat->category_count (14) // $cat->category_description (Текст описания) // $cat->cat_name (Рубрика 1) // $cat->category_nicename (rubrika-1) // $cat->category_parent (0) } } taxonomy(строка) Название таксономии, которую нужно обрабатывать. Добавлено с версии 3.0.
По умолчанию: "category" type(строка)
  • post - категории для постов (по умолчанию);
  • link - разделы ссылок.
    По умолчанию: "post"
child_of(строка) Получить дочерние категории (включая все уровни вложенности), указанной категории. В параметре указывается ID родительской категории (категория, вложенные категории которой нужно показать). parent(число) Получает категории родительская категория которых равна указанному в параметре ID. Отличие от child_of в том, что будет показан один уровень вложенности.
По умолчанию: "" orderby(строка)

Сортировка полученных данных по определенным критериям. Например, по количеству постов в каждой категории или по названию категорий. Доступны следующие критерии:

  • ID - сортировка по ID;
  • name - сортировка по названию (по умолчанию);
  • slug - сортировка по алт. имени (slug);
  • count - по количеству записей в категории;
  • term_group - по группе.

По умолчанию: "name"

Order(строка)

Направление сортировки, указанной в параметре "orderby":

  • ASC - по порядку, от меньшего к большему (1, 2, 3; a, b, c);
  • DESC - в обратном порядке, от большего к меньшему (3, 2, 1; c, b, a).

По умолчанию: "ASC"

Hide_empty(логический)

Получать или нет пустые категории (не имеющие записей):

  • 1 (true) - не получать пустые,
  • 0 (false) - получать пустые.

По умолчанию: true

Hierarchical(логический) Если параметр установлен в true , то в результат будут включены пустые дочерние категории, дочерние категории которых имеют записи (непустые).
По умолчанию: true exclude(строка/массив) Исключить какие-либо категории из списка. Нужно указывать ID категорий через запятую или в массиве. Если этот параметр указан, параметр child_of будет отменен.
По умолчанию: "" include(строка/массив) Вывести списком только указанные категории. Указывать нужно ID категорий через запятую или в массиве.
По умолчанию: "" number(число) Лимит. Число категорий, которые будут получены. По умолчанию без ограничений - будут получены все категории. pad_counts(логический) Если передать true, то число которое показывает количество записей в родительских категориях будет суммой своих записей и записей из дочерних категорий.
По умолчанию: false

Примеры

#1 Выпадающий список

Для того, чтобы создать выпадающий список из категорий мы можем воспользоваться другой специальной для этой цели, функцией wp_dropdown_categories() :

Wp_dropdown_categories(array("hide_empty" => 0, "name" => "category_parent", "orderby" => "name", "selected" => $category->parent, "hierarchical" => true, "show_option_none" => __("None")));

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

Поэтому, в некоторых случаях будет логичнее создать выпадающий список с помощью функции get_categories() . Вот пример (предполагается что нам нужно вывести подкатегории (дочерние) категории 10):

#2 Список категорий и их описание

Этот пример покажет нам как можно вывести списком ссылки на категории, где сразу после каждой ссылки будет идти описание категории (указывается при создании/редактировании категории):

"name", "order" => "ASC")); foreach($categories as $category){ echo "

Category: term_id) . "" title="" . sprintf(__("View all posts in %s"), $category->name) . "" " . ">" . $category->name."

"; echo "

Description:". $category->description . "

"; echo "

Post Count: ". $category->count . "

"; } ?>

Код get categories : wp-includes/category.php WP 5.2.2

"category"); $args = wp_parse_args($args, $defaults); $taxonomy = $args["taxonomy"]; /** * Filters the taxonomy used to retrieve terms when calling get_categories(). * * @since 2.7.0 * * @param string $taxonomy Taxonomy to retrieve terms from. * @param array $args An array of arguments. See get_terms(). */ $taxonomy = apply_filters("get_categories_taxonomy", $taxonomy, $args); // Back compat if (isset($args["type"]) && "link" == $args["type"]) { _deprecated_argument(__FUNCTION__, "3.0.0", /* translators: 1: "type => link", 2: "taxonomy => link_category" */ sprintf(__("%1$s is deprecated. Use %2$s instead."), "type => link", "taxonomy => link_category")); $taxonomy = $args["taxonomy"] = "link_category"; } $categories = get_terms($taxonomy, $args); if (is_wp_error($categories)) { $categories = array(); } else { $categories = (array) $categories; foreach (array_keys($categories) as $k) { _make_cat_compat($categories[ $k ]); } } return $categories; }

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

Задумывался я уже как с месяц и наконец, пришел к выводу: надо выносить проект дальше, нежели записи в блоге, и дать ему какое-то имя.

С подбором имени были некоторые проблемы, ибо все красивые домены давно заняты, либо скуплены перекупщиками. По итогам нескольких дней подбора имен, я нашел достойное название моему проекту!

Встречайте: MOGUTA.CMS

Я уже зарегистрировал домен moguta.ru , и в скором времени все новости по проекту начнут публиковаться именно там.

Кроме этого с сегодняшнего дня стала доступна группа вконтакте: MOGUTA.CMS

Но это еще не все!

Приглашаю к сотрудничеству

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

Какие плюсы вы получите, вступив в команду:

  1. Реальный обмен опытом;
  2. Возможность творить;
  3. В итоге: готовую, быструю, современную CMS для разработки интернет магазина;
  4. Общественное уважение.

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

Поэтому если ты школьник, студент, или просто умный парень – не упускай возможности, вступай в ряды разработчиков, и со временем наша команда будет занимать свое почетное место на рынке CMS. (Достаточно оптимистично! 🙂)

Вернемся к уроку…

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

Иногда простое кажется сложным, именно по этому выложу несколько фрагментов кода, которые я надеюсь вам пригодятся для реализации php категорий в виде дерева.

Итак, структура должна состоять из id категории (id), из названия категории (name) и конечно id родительской категории (parent_id). В MySQL это выглядит так:

CREATE TABLE IF NOT EXISTS `category` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `parent_id` int(11) NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=0 ;

Минимальная и понятная структура таблицы для хранения категорий.

INSERT INTO `category` (`id`, `name`, `parent_id`) VALUES (1, "Телефоны и планшеты", "0"), (2, "Автомобили", "0"), (3, "Samsung", "1"), (4, "Apple", "1"), (5, "LG", "1"), (6, "Ford", "2"), (7, "Lexus", "2"), (8, "BMW", "2"), (9, "Galaxy Tab 4", "3"), (10, "Galaxy S6", "3");

Там где значение parent_id=0, у данной категории нет родительской категории.

Тут все понятно и просто. Теперь присутпим к выводу списка категорий. Но для правильного вывода списка, нам нужно сначала получить весь список php категорий, а уже потом с помощью рекурсии сформировать наше дерево. Следующая функция предназначена для получения этого списка:

Function get_cat() { //запрос к базе данных $sql = "SELECT * FROM category"; $result = mysql_query($sql); if(!$result) { return NULL; } $arr_cat = array(); if(mysql_num_rows($result) != 0) { //В цикле формируем массив for($i = 0; $i < mysql_num_rows($result);$i++) { $row = mysql_fetch_array($result,MYSQL_ASSOC); //Формируем массив, где ключами являются адишники на родительские категории if(empty($arr_cat[$row["parent_id"]])) { $arr_cat[$row["parent_id"]] = array(); } $arr_cat[$row["parent_id"]] = $row; } //возвращаем массив return $arr_cat; } }

//получаем массив каталога $result = get_cat();

Теперь нужна функция с рекурсией

Function view_cat($arr,$parent_id = 0) { //Условия выхода из рекурсии if(empty($arr[$parent_id])) { return; } echo "

    "; //перебираем в цикле массив и выводим на экран for($i = 0; $i < count($arr[$parent_id]);$i++) { echo "
  • " .$arr[$parent_id][$i]["name"].""; //рекурсия - проверяем нет ли дочерних категорий view_cat($arr,$arr[$parent_id][$i]["id"]); echo "
  • "; } echo "
"; }

Теперь осталось только вывести каталог на экран с помощью рекурсивной функции

View_cat($result);

И в общем то и всё. Таким образом мы можем получить полное дерево категорий с бесконечными подкатегориями.