Регистрирует тип поста. В случае успеха возвращает его объект WP_Post_Type
, в случае неудачи – объект WP_Error.
register_post_type( $post_type, $args = array() )
Также рекомендую свой видеокурс по созданию темы WordPress на основе готовой вёрстки.
Функцию нужно использовать внутри хука, причём этот хук должен срабатывать после хука after_setup_theme
и перед admin_init
. Идеальным вариантом является init
.
add_action( 'init', 'true_register_cpt' ); function true_register_cpt() { $args = array( 'labels' => array( 'menu_name' => 'Авиабилеты' ), 'public' => true, 'menu_icon' => 'dashicons-airplane' ); register_post_type( 'misha_aviatickets', $args ); }
Я специально добавил префикс с названием типа записи misha_aviatickets
, чтобы обратить ваше внимание не некоторые моменты, а именно:
product
, order
, потому что это может вызвать конфликты с другими плагинами, например с плагином WooCommerce. Кроме того, вот список зарезервированных слов, которые нельзя использовать: post
, page
, attachment
, revision
, nav_menu_item
, custom_css
, customize_changeset
, action
, order
, theme
, author
.wp_
.post_type
стоит ограничение по типу VARCHAR
._
или -
: a-z0-9_-
.После этого вставляем код вы знаете куда и получаем:
labels[ 'name' ]
Тут конечно много всего, поэтому давайте рассмотрим пример на авиабилетах, с которыми мы уже начали работать:
$args = array( 'labels' => array( 'name' => 'Авиабилеты', // основное название во множественном числе 'singular_name' => 'Авиабилет', // название единичной записи 'add_new' => 'Добавить авиабилет', 'add_new_item' => 'Добавить новый авиабилет', // на странице добавления записи 'edit_item' => 'Изменить авиабилет', 'new_item' => 'Новый авиабилет', 'view_item' => 'Просмотр авиабилета', // текст кнопки просмотра записи на сайте (если поддерживается типом) 'search_items' => 'Найти авиабилет', 'not_found' => 'Авиабилетов не найдено', 'not_found_in_trash' => 'В корзине нет авиабилетов', 'parent_item_colon' => 'Родительский авиабилет', // только для древовидных типов постов 'all_items' => 'Все авиабилеты', // По умолчанию: menu_name 'archives' => 'Архивы авиабилетов', // По умолчанию: all_items 'menu_name' => 'Авиабилеты', // Название в меню. По умолчанию: name. 'name_admin_bar' => 'Авиабилет', // Название в админ баре при наведении на "Добавить". По умолчанию: singular_name. 'view_items' => 'Просмотр авиабилетов', // Текст ссылки перехода на архивы типа записй в админ баре. WordPress 4.7+ 'attributes' => 'Свойства авиабилета', // Название для метабокса атрибутов записи. WordPress 4.7+ // лейблы загрузчика медиафайлов 'insert_into_item' => 'Вставить в авиабилет', 'uploaded_to_this_item' => 'Загружено для этого авиабилета', 'featured_image' => 'Изображение авиабилета', 'set_featured_image' => 'Установить изображение авиабилета', 'remove_featured_image' => 'Удалить изображение авиабилета', 'use_featured_image' => 'Использовать как изображение авиабилета', // Gutenberg, WordPress 5.0+ 'item_updated' => 'Авиабилет обновлён.', 'item_published' => 'Авиабилет добавлен.', 'item_published_privately' => 'Авиабилет добавлен приватно.', 'item_reverted_to_draft' => 'Авиабилет сохранён как черновик.', 'item_scheduled' => 'Публикация авиабилета запланирована.', ) );
Добавляем этот массив $label
и, мы получаем:
false
.public | false | true |
---|---|---|
show_ui | false | true |
publicly_queryable | false | true |
exclude_from_search | true | false |
show_in_nav_menus | false | true |
Иными словами:
$args = array( 'public' => true, // 'show_ui' => true, // 'publicly_queryable' => true, // 'exclude_from_search' => false, // 'show_in_nav_menus' => true, );
Подробнее о параметрах – ниже.
public
.true
— исключить записи данного типа из результатов поиска на сайте,false
— не исключать.По умолчанию: противоположные значения параметра public
.
public
.public
.true
— пункты в меню будут добавлены (это видно на предыдущем скриншоте),false
— хоть интерфейс для типов постов и будет доступен по прямой ссылке в админке, в меню он не появится,tools.php
или edit.php?post_type=page
;
show_ui
.
show_in_menu
.Допустим наши авиабилеты не должны поддерживать Gutenberg и редактироваться в классическом редакторе, тогда:
add_action( 'init', 'true_register_cpt' ); function true_register_cpt() { $args = array( 'labels' => array( 'menu_name' => 'Авиабилеты' ), 'menu_icon' => 'dashicons-airplane', 'show_in_rest' => false ); register_post_type( 'misha_aviatickets', $args ); }
Значения параметров | Расположение |
---|---|
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 | под разделителем после «Параметры» |
Во-первых, вы можете указать URL иконки, например get_stylesheet_directory_uri() . '/icon.png'
. Изображение должно быть 16х16.
Во-вторых, можно передать SVG-иконку, зашифровав её в base64, типа:
'menu_icon' => 'data:image/svg+xml;base64,' . base64_encode( '<svg width="20" height="20"><path fill="black" /></svg>'),
<path>
fill="black"
, чтобы WordPress смог изменять её цвет под ситуации.В-третьих, в WordPress 3.8 появился встроенный пакет иконок Dashicons — вы можете использовать любую из этих иконок, просто указав её название в качестве значения параметра, например dashicons-cart
.
В-четвёртых, можно передать значение параметра равным none
, тогда WordPress добавит CSS-класс к элементу меню .wp-menu-image empty
и вы сможете задать иконку через CSS.
false
.Каждый раз при изменении параметров ниже рекомендую заходить в Настройки > Постоянные ссылки и нажимать «Сохранить изменения», даже ничего там не меняя. Это нужно, чтобы сбросить кэш и избежать ошибок 404.
true
/false
(по умолчанию). Если передать логическое значение true
, то в качестве URL страницы архива будет использоваться название типа записи, например для нашего примера это misha.blog/misha_aviatickets
avia
, то это тоже включит архивы для этого типа записи и URL будет misha.blog/avia
.false
, то правила для постоянных ссылок создаваться не будут. Передайте true
, тогда в качестве ярлыка в URL будет использоваться название типа записи misha.blog/misha_aviatickets/ticket.html
.
$wp_rewite->front
(по умолчанию — true
)has_archive
)<!--nextpage-->
(по умолчанию — true
)false
.title
— поле для ввода заголовка постаeditor
— текстовый редакторexcerpt
— метабокс «Цитата»author
— метабокс «Автор»thumbnail
— метабокс «Миниатюра записи» (кроме того, ваша тема должна их поддерживать)comments
— метабокс «Комментарии» (если указано, то разрешены комментарии к постам регистрируемого типа)trackbacks
— метабокс «Отправить обратные ссылки»custom-fields
— метабокс «Произвольные поля» (также добавляет поддержку произвольных полей в сайдбарах Gutenberg)revisions
— метабокс «Редакции» (если указано, то в базе данных будут создаваться редакции постов данного типа)page-attributes
— метабокс «Атрибуты страницы» с возможностью выбора родительского эоемента и установления порядка menu_order
post-formats
— метабокс «Формат», про форматы постов читайте подробнее здесь.category
или post_tag
, которые будут использоваться для данного типа записей. Присвоить таксономии можно также при помощи функции register_taxonomy_for_object_type(), а зарегистрировать функцией register_taxonomy().true
– да.capabilities
автоматически. По умолчанию права генерируется такие же, как я для обычных записей, но мы можем задать произвольные права для типа записи, для этого например можем передать в качестве значения параметра либо 'aviaticket'
либо array( 'aviaticket', 'aviatickets' )
.capability_type
. Если же хотите их указать сами, то вэлкам, начнём с этих 7 ключей:
edit_post
, read_post
и delete_post
– это мета-права. Что это значит? Мета-права обычно прикрепляются уже к действию с конкретным объектом, например то, что пользователь может редактировать определённый пост (edit_post
). Но мета-права привязаны к соответствующим примитивным правам, например edit_posts
– пользователь может редактировать любые посты.edit_posts
– могут ли редактироваться посты данного типа.edit_others_posts
– могут ли посты данного типа редактироваться пользователем, который их не создавал. Если в параметре supports
отсутствует поддержка author
, то это примитивное право начинает работать как edit_posts
.publish_posts
– есть ли права на публикацию постов.read_private_posts
– есть ли права на чтение приватных постов$map_meta_cap
в значении true
(по умолчанию false
).
read
delete_posts
– удаление постов,delete_private_posts
– удаление личных постов,delete_published_posts
– удаление опубликованных постовdelete_others_posts
– удаление постов, созданных другими пользователями. Если в параметре supports
отсутствует поддержка author
, то это примитивное право начинает работать как delete_posts
edit_private_posts
– редактирование личных постов,edit_published_posts
– редактирование опубликованных постов,create_posts
– создание постов.Погнали сделаем что-нибудь!
add_action( 'init', function() { $args = array( 'capability_type' => 'avia', 'map_meta_cap' => true, 'public' => true ); register_post_type( 'aviaticket', $args ); } );
После чего попробуем распечать получившиеся права print_r( $GLOBALS[ 'wp_post_types' ][ 'aviaticket' ]->cap
и получим:
stdClass Object ( [edit_post] => edit_avia [read_post] => read_avia [delete_post] => delete_avia [edit_posts] => edit_avias [edit_others_posts] => edit_others_avias [delete_posts] => delete_avias [publish_posts] => publish_avias [read_private_posts] => read_private_avias [read] => read [delete_private_posts] => delete_private_avias [delete_published_posts] => delete_published_avias [delete_others_posts] => delete_others_avias [edit_private_posts] => edit_private_avias [edit_published_posts] => edit_published_avias [create_posts] => edit_avias )
Теперь можем добавить некоторые из этих прав администратору например:
$admins = get_role( 'administrator' ); $admins->add_cap( 'edit_published_avias' );
false
, если $capabilities
задан и не равен post
или page
.Также рекомендую свой видеокурс по созданию темы WordPress на основе готовой вёрстки.
Чтобы оставить комментарий, пожалуйста, зарегистрируйтесь или войдите.
добрый день.
страница с этим постом будет доступна по url .../product/bla-bla-bla
а как унаследовать от стандартного поста принцип формирования адреса, в частности привести к виду .../cat1/cat2/bla-bla-bla
заранее благодарен за ответ
Добрый день!
При регистрации типа поста укажите:
Затем применим фильтр к URL этого типа постов:
И прошу прощения за столь долгий ответ.
Для ссылок типа 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 выдаёт «Страница не найдена». В чём причина?
Сделал, все работает, а вот на странице добавления материала нету выбора категории!!! помогите плиз.
А как сделать категории только для этого модуля?
То есть убрать категории из записей?
Добавляю материал а на странице категории ничего не отображается полная новость есть а на категориях написано Archive by category "Продукты здоровья"
Заранее спасибо
Возможно в категориях с цикле установлен тип поста
post
. Как изменить.Странно что в столбец guid с новостями пишется вот такая хрень http://***ua/?post_type=health&p=82
а не http://***.ua/uncategorized/47-revision-v1/ как в норм новостях
мой код
С кодом на первый взгляд всё в порядке.
и в пост_нейм вот что пишет %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
Здравствуйте! Если несложно (и сталкивались), подскажите, пожалуйста, ответ. На всем сайте статьи с URL-ами типа %postname%.html. Можно ли этот злосчастный ".html" дописать и к ссылкам на записи произвольного типа?
Здравствуйте!
Да, можно, сам когда-то делал. Код к сожалению не помню. Ещё плагин был, который эт реализовывал.
Да, плагин я видела (Custom Post Type Permalinks), но хотелось попробовать сделать вручную. Провозилась день - не получилось, буду делать через плагин. Извините за беспокойство :)
Вроде какой-то другой плагин был, по английски так и назывался что-то типа html-for-pages. Помню, что я тупо из содержимого плагина код скопирнул в functions.php и всё заработало :)
О, нашёл https://downloads.wordpress.org/plugin/html-on-pages.zip.
Спасибо, вечером попробую. А то предыдущий плагин мне все-таки не подошел (поменялись урлы у всего форума на bbPress и через плагин даже нельзя было вернуть прежний вид).
Пожалуйста, дайте знать, если всё получится.
Здравствуйте, мне нужно что бы после регистрации нового типа поста url вел себя так же как у обычных постов, site.ru/postname
Здравствуйте!
В эту пятницу я опубликую пост про WP_Rewrite, думаю там вы сможете найти ответ.
Спасибо, ждём
Михаил, добрый день.
Подскажите, можно к своему типу поста указать родителя типа "page"?
Т.е. я бы как обычно указывал родительскую страницу из СТРАНИЦ.
Заранее спасибо за ответ.
Добрый день!
Думаю есть пара решений:
Спасибо за ответ.
Способ 2 я в первую очередь попробовал, работает только для своих типов. Т.е. скажем у меня тип "product", и родителя могу выбрать только продукт, но не "page".
А про способ 1 можно подробнее? Или ссылки где почитать. Я пока учусь, не всё понятно.
2й способ как раз таки должен работать в любом случае — просто через WP_Query делаем выпадающий список из нужных типов.
Михаил, не получилось, переделал всё под свой тип поста.
Спасибо.
Михаил, ещё вопрос: Как сделать url не "site.ru/тип_поста/имя_поста" а как обычно "site.ru/имя_поста" ?
Заранее спасибо.
В пятницу выйдет новый пост, там об этом подробно напишу.
А можешь прояснить одним момент. Мне не понятно. Вот мы регистрируем пост во время хука init
да и сам вп рекомендует это делать. Но в тоже время есть хук registered_post_type который срабатывает на 8 хуков раньше, чем init. И есть другая рекомендация (с точки зрения производительсности юзать "целевые хуки вместо общих". Вот и не понятно. Если все регают посты через хук init, то нафига вообще нужен хук registered_post_type?
PS тоже самое с таксономиями. Нафига хук registered_taxonomy если вешаем мы все на init?
Буду благодарен за развернутый ответ.
Этот хук срабатывает сразу ПОСЛЕ регистрации типа записи, так что это не то. Это получается, что ты хочешь повесить регистрацию нового типа записи несколько раз внутри регистрации предыдущих. Как-то так.
С таксономиями аналогично.
Здравствуйте Михаил.
Я создал произвольный тип записи vacancy. Указал 'has_archive' => true. Далее сделал шаблон archive-vacancy.php и добавил пункт меню. При заходе на страницу архива, пункт меню выделен как текущий и у него есть класс "current-menu-item active". А вот при переходе на страницу записи, класс у пункта меню удаляется, и соответственно меню выглядит как обычный пункт.
Подскажите, можно ли как то сделать, чтобы страница записи соотносилась со страницей архива, и определялась как текущая для соответствующего пункта меню?
Добрый день Виталий,
В таких случаях бывает два решения:
1) Проверить, если у элемента класс
current-menu-parent
и если да, то стилизовать под него2) Стилизовать ваш конкретный элемент меню, используя body classes, например:
Михаил здравствуйте.
Спасибо за быстрый ответ.
Класс "current-menu-parent" как раз и не появляется, так и не понял, почему.
Использование body classes - отличная идея, как я сам забыл про это.
Еще раз спасибо за ответ и за очень полезный сайт
Спасибо за информацию! Скажите, а как можно сделать привязку формы, чтобы при отправке данных со страницы они передавались в админку вордпресса... а именно, в кастомный тип записи?
Да, конечно можно!
Для этого вам достаточно воспользоваться функцией wp_insert_post().
Миша, привет!
Делаю свой плагин форм, где формы будут сохраняться в CustomPostType
Подскажи пожалуйста, существует ли не костыльный способ сделать так, чтобы при нажатии в админке на кастомную запись открывался нужный php файл моего плагина (то есть редактирование формы через мой плагин) ?
Или вариант только как то хуками цепляться и перекрывать стандартное окно админки ( редактирования кастомной записи) моим плагином?