register_post_type() — позволяет зарегистрировать новый тип поста

В случае успеха функция возвращает объект зарегистрированного типа поста, в случае неудачи — объект WP_Error. Функция должна использоваться только внутри хука init.

Читайте подробнее о том, что такое типы записей (типы постов).

register_post_type( $post_type, $args = array() )
$post_type
(строка) то, как вы хотите назвать свой тип поста, это название в дальнейшем будет использоваться в параметрах многих функций, учтите это. Кроме того, нельзя использовать в качестве названий следующие зарезервированные вордпрессом слова:

  • post
  • page
  • attachment
  • revision
  • nav_menu_item
  • custom_css
  • customize_changeset
  • action
  • order
  • theme
  • author
$args
(массив) включает в себя следующие параметры:

labels
(массив) позволяет подписать элементы интерфейса данного типа записи. Подробнее в примере в конце поста.
description
(строка) описание регистрируемого типа записей. Насколько мне известно, этот параметр не используется где-либо в движке WordPress или в стандартных плагинах и темах. Но вполне может использоваться в сторонних плагинах или темах.
public
(логическое) обобщает следующие несколько параметров, устанавливая для них соответствующие значения по умолчанию
publicly_queryable
(логическое) нужно ли элементы данного типа записей сделать доступными на сайте. Подробнее про задачу этого параметра тут.
По умолчанию: значение аргумента public.
exclude_from_search
(логическое)

  • true — исключить записи данного типа из результатов поиска на сайте,
  • false — не исключать.

По умолчанию: противоположные значения параметра public.

show_in_nav_menus
(логическое) нужно ли элементы данного типа записей сделать доступными для добавления в меню сайта.
По умолчанию: значение аргумента public.
show_ui
(логическое) нужно ли добавлять стандартный интерфейс в админке для редактирования и добавления записей данного типа.
По умолчанию: значение аргумента public.

значение параметра show_ui равно true
show_in_menu
(логическое|строка) нужно ли добавлять пункты в меню админки.

  • true — пункты в меню будут добавлены (это видно на предыдущем скриншоте),
  • false — хоть интерфейс для типов постов и будет доступен по прямой ссылке в админке, в меню он не появится,
  • ссылку на страницу управления нашим типом поста мы можем добавить как вложенную для другого элемента меню верхнего уровня — для этого нужно будет указать его ID (являющийся атрибут href нужной нам ссылки), например tools.php или edit.php?post_type=page;
    show_in_menu - в качестве значения параметра указано edit.php

По умолчанию: значение аргумента show_ui.

show_in_admin_bar
(логическое) нужно ли добавлять ссылку на создание новой записи данного типа в админ панель.

параметр show_in_admin_bar равен true

По умолчанию: значение аргумента show_in_menu.

menu_position
(целое число) порядок расположения в меню в админке.

Значения параметров Расположение
1 в самом верху меню
2-3 под «Консоль»
4-9 под «Записи»
10-14 под «Медиафайлы»
15-19 под «Ссылки»
20-24 под «Страницы»
25-59 под «Комментарии» (по умолчанию, null)
60-64 под «Внешний вид»
65-69 под «Плагины»
70-74 под «Пользователи»
75-79 под «Инструменты»
80-99 под «Параметры»
больше 100 под разделителем после «Параметры»
menu_icon
(строка) абсолютный URL иконки для меню. Оптимальное разрешение изображения 16×16 пикселей.

Кроме того, в WordPress 3.8 появился встроенный пакет иконок Dashicons — вы можете использовать любую из этих иконок, просто указав её название в качестве значения параметра, например dashicons-cart.

иконка в меню для произвольного типа записей

По умолчанию используется иконка обычных записей.

delete_with_user
(логическое) при удалении пользователя на блоге, нужно ли автоматически удалять все записи данного типа, которые он опубликовал.
По умолчанию: false.
hierarchical
(логическое) должен ли данный тип постов иметь иерархию.
По умолчанию: false.
has_archive
(логическое|строка) должен ли данный тип постов иметь собственную страницу архивов. В качестве значения параметра можно указать ярлык страницы архивов.
По умолчанию: false.
rewrite
(массив|логическое) устанавливает правила для постоянных ссылок в URL. Если в качестве значения данного параметра указать false, то правила для постоянных ссылок создаваться не будут.

slug
(строка) ярлык, используемый для записей данного типа (по умолчанию — название типа поста)
with_front
(логическое) нужно ли добавлять в постоянные ссылки значение $wp_rewite->front (по умолчанию — true)
feeds
(логическое) нужно ли создавать RSS ленту для данного типа поста (по умолчанию — значение параметра has_archive)
pages
(логическое) нужно ли разрешить постраничную навигацию в постах регистрируемого типа, используя тег <!--nextpage--> (по умолчанию — true)
supports
(массив) какие метабоксы нужно добавить на страницы редактирования записей данного типа.

  • title — поле для ввода заголовка поста
  • editor — текстовый редактор
  • excerpt — метабокс «Цитата»
  • author — метабокс «Автор»
  • thumbnail — метабокс «Миниатюра записи» (кроме того, ваша тема должна их поддерживать)
  • comments — метабокс «Комментарии» (если указано, то разрешены комментарии к постам регистрируемого типа)
  • trackbacks — метабокс «Отправить обратные ссылки»
  • custom-fields — метабокс «Произвольные поля» (произвольные поля будут поддерживаться в любом случае)
  • revisions — метабокс «Редакции» (если указано, то в базе данных будут создаваться редакции постов данного типа)
  • page-attributes — метабокс «Атрибуты страницы» с возможностью выбора родительского эоемента и установления порядка menu_order
  • post-formats — метабокс «Формат», про форматы постов читайте подробнее здесь.
taxonomies
(массив) массив зарегистрированных таксономий, например category или post_tag, которые будут использоваться для данного типа записей. Присвоить таксономии можно также при помощи функции register_taxonomy_for_object_type().

Пример регистрации типа поста

Если не знаете, куда вставлять код — вставляйте в functions.php вашей текущей темы.

add_action( 'init', 'true_register_products' ); // Использовать функцию только внутри хука init
 
function true_register_products() {
	$labels = array(
		'name' => 'Товары',
		'singular_name' => 'Товар', // админ панель Добавить->Функцию
		'add_new' => 'Добавить товар',
		'add_new_item' => 'Добавить новый товар', // заголовок тега <title>
		'edit_item' => 'Редактировать товар',
		'new_item' => 'Новый товар',
		'all_items' => 'Все товары',
		'view_item' => 'Просмотр товаров на сайте',
		'search_items' => 'Искать товары',
		'not_found' =>  'Товаров не найдено.',
		'not_found_in_trash' => 'В корзине нет товаров.',
		'menu_name' => 'Товары' // ссылка в меню в админке
	);
	$args = array(
		'labels' => $labels,
		'public' => true, // благодаря этому некоторые параметры можно пропустить
		'menu_icon' => 'dashicons-cart', // иконка корзины
		'menu_position' => 5,
		'has_archive' => true,
		'supports' => array( 'title', 'editor', 'excerpt', 'thumbnail', 'comments'),
		'taxonomies' => array('post_tag')
	);
	register_post_type('product',$args);
}

Миша

В последние годы я долго не знал, что мне делать с сайтом misha.blog, ведь он практически не приносит никакого профита, но недавно я осознал, что моя миссия – способствовать распространению WordPress. Ведь WordPress – это лучший движок для разработки сайтов – как для тех, кто готов использовать заложенную структуру этой CMS, так и для тех, кто предпочитает headless решения.

Сам же я впервые познакомился с WordPress в 2009 году. Организатор WordCamp. Преподаватель в школах Epic Skills и LoftSchool.

Если вам нужна помощь с вашим сайтом или может даже разработка с нуля на WordPress / WooCommerce — пишите. Я и моя команда сделаем вам всё на лучшем уровне.

Комментарии — 35

  • luchkinds 11 марта 2014 #

    добрый день.
    страница с этим постом будет доступна по url .../product/bla-bla-bla
    а как унаследовать от стандартного поста принцип формирования адреса, в частности привести к виду .../cat1/cat2/bla-bla-bla

    заранее благодарен за ответ

    • Миша 19 апреля 2014 #

      Добрый день!
      При регистрации типа поста укажите:

      'rewrite' => array('slug' => 'product/%product%')

      Затем применим фильтр к URL этого типа постов:

      function true_product_link( $post_link, $id = 0 ){
      	$post = get_post($id);  
      	if ( is_object( $post ) ){
      		$terms = wp_get_object_terms( $post->ID, 'product' ); // тип поста ведь product?
      		if( $terms ){
      			return str_replace( '%product%' , $terms[0]->slug , $post_link );
      		}
      	}
      	return $post_link;  
      }
      add_filter( 'post_type_link', 'true_product_link', 1, 3 );

      И прошу прощения за столь долгий ответ.

      • Мария 15 марта 2020 #

        Для ссылок типа site.abc/product/cat-1/cat-1-1/product-slug/ немного переписала код. Ссылка формируется правильно, но при открытии страниц site.abc/product/cat-1/, site.abc/product/cat-1/cat-1-1/ и site.abc/product/cat-1/cat-1-1/product-slug/ WP выдаёт «Страница не найдена». В чём причина?

        		if ( $terms ) {
        		    $cat_slug = '';
        		    foreach ( $terms as $term ) {
        		        $cat_slug .= $term->slug . '/';
        		    }
        			return str_replace( '%statji-taxonomy%' , $cat_slug , $post_link );
        		}
  • Александр 25 ноября 2014 #

    Сделал, все работает, а вот на странице добавления материала нету выбора категории!!! помогите плиз.

    • Миша 26 ноября 2014 #
      function post_categories_append(){
      	register_taxonomy_for_object_type( 'category', 'НАЗВАНИЕ_ВАШЕГО_ТИПА_ПОСТА');
      }
       
      add_action( 'init', 'post_categories_append' );
      • WebNatrix 5 декабря 2015 #

        А как сделать категории только для этого модуля?

        • Миша 6 декабря 2015 #

          То есть убрать категории из записей?

  • Александр 26 ноября 2014 #

    Добавляю материал а на странице категории ничего не отображается полная новость есть а на категориях написано Archive by category "Продукты здоровья"
    Заранее спасибо

  • Александр 26 ноября 2014 #

    Странно что в столбец guid с новостями пишется вот такая хрень http://***ua/?post_type=health&p=82

  • Александр 26 ноября 2014 #

    а не http://***.ua/uncategorized/47-revision-v1/ как в норм новостях

  • Александр 26 ноября 2014 #

    мой код

     add_action( 'init', 'health_products' ); // Использовать функцию только внутри хука init
     
    function health_products() {
    	$labels = array(
    		'name' => 'Продукты здоровья',
    		'singular_name' => 'Продукт', // админ панель Добавить->Функцию
    		'add_new' => 'Добавить продукт',
    		'add_new_item' => 'Добавить новый продукт', // заголовок тега <title>
    		'edit_item' => 'Редактировать продукт',
    		'new_item' => 'Новый продукт',
    		'all_items' => 'Все продукты',
    		'view_item' => 'Просмотр продукта на сайте',
    		'search_items' => 'Искать продукты',
    		'not_found' =>  'Продуктов не найдено.',
    		'not_found_in_trash' => 'В корзине нет продуктов.',
    		'menu_name' => 'Продукты здоровья' // ссылка в меню в админке
    	);
    	$args = array(
    		'labels' => $labels,
    		'public' => true,
            //'rewrite' => array('slug' => 'health/%health%'),
    		'show_ui' => true, // показывать интерфейс в админке
    		'has_archive' => true, 
    		'menu_icon' => 'dashicons-cart', // иконка корзины
    		'menu_position' => 20, // порядок в меню
    		'supports' => array( 'title', 'editor', 'comments', 'author', 'thumbnail',)
    	);
    	register_post_type('health', $args);
    }
     
     
    function post_tag_for_pages(){
    	register_taxonomy_for_object_type( 'category', 'health');
    }
    function post_tag_for_pages2(){
    	register_taxonomy_for_object_type( 'post_tag', 'health');
    }
     
     
        add_action( 'init', 'post_tag_for_pages' );
        add_action( 'init', 'post_tag_for_pages2' );
    • Миша 26 ноября 2014 #

      С кодом на первый взгляд всё в порядке.

  • Александр 26 ноября 2014 #

    и в пост_нейм вот что пишет %d0%b0%d0%bf%d1%80-%d0%b0%d0%bf%d1%80-%d0%b0%d0%bf%d0%b2%d1%80%d0%b0%d0%bf%d1%80%d0%bf%d0%b0%d0%bf%d1%80

  • Маша 13 января 2015 #

    Здравствуйте! Если несложно (и сталкивались), подскажите, пожалуйста, ответ. На всем сайте статьи с URL-ами типа %postname%.html. Можно ли этот злосчастный ".html" дописать и к ссылкам на записи произвольного типа?

    • Миша 13 января 2015 #

      Здравствуйте!
      Да, можно, сам когда-то делал. Код к сожалению не помню. Ещё плагин был, который эт реализовывал.

      • Маша 13 января 2015 #

        Да, плагин я видела (Custom Post Type Permalinks), но хотелось попробовать сделать вручную. Провозилась день - не получилось, буду делать через плагин. Извините за беспокойство 🙂

        • Миша 14 января 2015 #

          Вроде какой-то другой плагин был, по английски так и назывался что-то типа html-for-pages. Помню, что я тупо из содержимого плагина код скопирнул в functions.php и всё заработало 🙂

          О, нашёл https://downloads.wordpress.org/plugin/html-on-pages.zip.

          • Маша 14 января 2015 #

            Спасибо, вечером попробую. А то предыдущий плагин мне все-таки не подошел (поменялись урлы у всего форума на bbPress и через плагин даже нельзя было вернуть прежний вид).

            • Миша 15 января 2015 #

              Пожалуйста, дайте знать, если всё получится.

  • Сергей 17 мая 2015 #

    Здравствуйте, мне нужно что бы после регистрации нового типа поста url вел себя так же как у обычных постов, site.ru/postname

    • Миша 18 мая 2015 #

      Здравствуйте!
      В эту пятницу я опубликую пост про WP_Rewrite, думаю там вы сможете найти ответ.

      • Сергей 18 мая 2015 #

        Спасибо, ждём

  • Сергей 18 мая 2015 #

    Михаил, добрый день.
    Подскажите, можно к своему типу поста указать родителя типа "page"?
    Т.е. я бы как обычно указывал родительскую страницу из СТРАНИЦ.
    Заранее спасибо за ответ.

    • Миша 19 мая 2015 #

      Добрый день!

      Думаю есть пара решений:

      1. Сделать записи иерархичными, а потом поискать фильтр для выпадающего списка родительских элементов — возможно туда можно включить тип page.
      2. Отдельным полем в метабоксе.
      • Сергей 19 мая 2015 #

        Спасибо за ответ.
        Способ 2 я в первую очередь попробовал, работает только для своих типов. Т.е. скажем у меня тип "product", и родителя могу выбрать только продукт, но не "page".
        А про способ 1 можно подробнее? Или ссылки где почитать. Я пока учусь, не всё понятно.

        • Миша 19 мая 2015 #

          2й способ как раз таки должен работать в любом случае — просто через WP_Query делаем выпадающий список из нужных типов.

          • Сергей 19 мая 2015 #

            Михаил, не получилось, переделал всё под свой тип поста.
            Спасибо.

          • Сергей 19 мая 2015 #

            Михаил, ещё вопрос: Как сделать url не "site.ru/тип_поста/имя_поста" а как обычно "site.ru/имя_поста" ?
            Заранее спасибо.

            • Миша 19 мая 2015 #

              В пятницу выйдет новый пост, там об этом подробно напишу.

  • Максим 6 февраля 2016 #

    А можешь прояснить одним момент. Мне не понятно. Вот мы регистрируем пост во время хука init

    add_action( 'init', 'true_register_products' );

    да и сам вп рекомендует это делать. Но в тоже время есть хук registered_post_type который срабатывает на 8 хуков раньше, чем init. И есть другая рекомендация (с точки зрения производительсности юзать "целевые хуки вместо общих". Вот и не понятно. Если все регают посты через хук init, то нафига вообще нужен хук registered_post_type?

    PS тоже самое с таксономиями. Нафига хук registered_taxonomy если вешаем мы все на init?
    Буду благодарен за развернутый ответ.

    • Миша 8 февраля 2016 #

      registered_post_type

      Этот хук срабатывает сразу ПОСЛЕ регистрации типа записи, так что это не то. Это получается, что ты хочешь повесить регистрацию нового типа записи несколько раз внутри регистрации предыдущих. Как-то так.

      С таксономиями аналогично.

  • Виталий 27 ноября 2019 #

    Здравствуйте Михаил.
    Я создал произвольный тип записи vacancy. Указал 'has_archive' => true. Далее сделал шаблон archive-vacancy.php и добавил пункт меню. При заходе на страницу архива, пункт меню выделен как текущий и у него есть класс "current-menu-item active". А вот при переходе на страницу записи, класс у пункта меню удаляется, и соответственно меню выглядит как обычный пункт.
    Подскажите, можно ли как то сделать, чтобы страница записи соотносилась со страницей архива, и определялась как текущая для соответствующего пункта меню?

    • Миша 28 ноября 2019 #

      Добрый день Виталий,

      В таких случаях бывает два решения:

      1) Проверить, если у элемента класс current-menu-parent и если да, то стилизовать под него

      2) Стилизовать ваш конкретный элемент меню, используя body classes, например:

      .single-vacancy #menu-item-17{
      	/* если находимся на странице элемента CPT, стилизуем пункт меню */
      }
      • Виталий 28 ноября 2019 #

        Михаил здравствуйте.
        Спасибо за быстрый ответ.
        Класс "current-menu-parent" как раз и не появляется, так и не понял, почему.
        Использование body classes - отличная идея, как я сам забыл про это.
        Еще раз спасибо за ответ и за очень полезный сайт

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

Если вы хотите добавить код, не забудьте обернуть его в <pre lang="php"></pre>, если же код – меньше одной строчки, то можно и в <code></code>.