Начиная с версии 2.9 WordPress предоставил возможность использования произвольных типов записей. Теперь же с версии 3.0 всё стало еще приятнее с опцией создания панелей для ваших произвольных типов записей. В этой статье мы покажем вам как внедрить Произвольные Типы записей на ваш сайт на WordPress.

Создание произвольных типов записей — используем Плагин

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

Custom Post Type UI

Custom Post Type UI — это плагин, разработанный Brad Williams, который позволяет вам с легкостью создавать произвольные типы записей и таксономии. Одной из самых примечательных возможностей этого плагина является то, что он генерирует код для создания произвольных типов записей, которые в последующем можно вставить в файл functions.php темы, а из минусов то, что невозможно использовать таксономии для всех ваших типов записей.

В панели Custom Post Type UI кликните на “Add New”.

  • “Post Type Name” — это то, что будет использоваться WordPress для запросов на все записи из этого post_type.
  • “Label” — то, что будет отображаться в сайдбаре вашей Консоли, по типу стандартного меню «Записи».
  • Если раскрыть “View Advanced Options”, то можно увидеть несколько дополнительных настроек. Большинство из них интуитивно понятны, например “Public” и “Show UI”. Первая при переключении ее в True позволит вывести меню произвольного типа записи в сайдбар, а вторая (Show UI) при значении True создает панель меню.
  • “Rewrite” — то, что позволит произвольным типам записей использовать SEO Friendly WordPress URL (постоянные ссылки, ЧПУ).
  • В “Custom Rewrite Slug” вы указываете все, что вам угодно. WordPress будет использовать указанный slug для генерации постоянных ссылок. Поэтому если у нас есть домен example.com и slug — “movies”, то ваша ссылка на произвольный тип записи будет выглядеть примерно так example.com/movies .
  • Функция WordPress “Query Var” позволяет вам выполнять запросы к вашим новым типам записей. Если мы возьмем пример, приведенный выше, то чтобы получить доступ к записи с заголовком, My First Movie Post , который находится в post_type Movies , мы можем ввести example.com/?movies=my-first-movie-post . Посему переменная запроса выглядит так: ?posttypename

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

Создание произвольных типов записей — используем файл Functions.php

Если вы предпочтете создавать произвольные типы записей без плагинов, то просто добавьте следующий код в файл functions.php вашей темы:

// Создаем тип записей Movies register_post_type("movies", array("label" => "Movies", "public" => true, "show_ui" => true, "capability_type" => "post", "hierarchical" => false, "rewrite" => array("slug" => "movies"), "query_var" => true, "supports" => array("title", "editor", "excerpt", "trackbacks", "custom-fields", "comments", "revisions", "thumbnail", "author", "page-attributes",)));

Давайте проанализируем код.

register_post_type($post_type, $args): Эта функция принимает два параметра, $post_type или название типа записи, и $args, массив параметров.

label: Имя, задаваемое типу записи, которое будет отображаться в сайдбаре административной панели сайта.

show_ui : true/false. Отображает или скрывает дефолтный интерфейс для управления этим типом записей.

capability_type: По-умолчанию: post. Тип записи для проверки возможностей чтения, редактирования и удаления.

hierarchical: Является ли запись иерархической.

rewrite: true/false. По-умолчанию: true . Если параметр slug указан, то имя slug добавляется перед записью.

query_var: true/false Устанавливает переменную для запроса к произвольному типу записи.

supports: По-умолчанию: title и author . Устанавливает различные фичи, которые будут поддерживаться типом записи.

Посетите WordPress Codex для более подробной информации по register_post_type() .

выводим произвольные типы записей

Для вывода записей из вашего произвольного типа необходимо добавить следующий код в цикл. Измените “name” на имя вашего типа записей. Примечание: вам не нужно добавлять ваши произвольные типы записей в ваш файл index.php. Можно создать и там выполнить следующий запрос внутри цикла.

$query = new WP_Query("post_type=name");

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

Build an object with all post type capabilities out of a post type object

Post type capabilities use the "capability_type" argument as a base, if the capability is not set in the "capabilities" argument array or if the "capabilities" argument is not supplied.

The capability_type argument can optionally be registered as an array, with the first value being singular and the second plural, e.g. array("story, "stories") Otherwise, an "s" will be added to the value for the plural form. After registration, capability_type will always be a string of the singular value.

By default, seven keys are accepted as part of the capabilities array:

    edit_post, read_post, and delete_post are meta capabilities, which are then generally mapped to corresponding primitive capabilities depending on the context, which would be the post being edited/read/deleted and the user or role being checked. Thus these capabilities would generally not be granted directly to users or roles.

  • edit_posts - Controls whether objects of this post type can be edited.
  • edit_others_posts - Controls whether objects of this type owned by other users can be edited. If the post type does not support an author, then this will behave like edit_posts.
  • publish_posts - Controls publishing objects of this post type.
  • read_private_posts - Controls whether private objects can be read.

These four primitive capabilities are checked in core in various locations. There are also seven other primitive capabilities which are not referenced directly in core, except in map_meta_cap(), which takes the three aforementioned meta capabilities and translates them into one or more primitive capabilities that must then be checked against the user or role, depending on the context.

  • read - Controls whether objects of this post type can be read.
  • delete_posts - Controls whether objects of this post type can be deleted.
  • delete_private_posts - Controls whether private objects can be deleted.
  • delete_published_posts - Controls whether published objects can be deleted.
  • delete_others_posts - Controls whether objects owned by other users can be can be deleted. If the post type does not support an author, then this will behave like delete_posts.
  • edit_private_posts - Controls whether private objects can be edited.
  • edit_published_posts - Controls whether published objects can be edited.

These additional capabilities are only used in map_meta_cap(). Thus, they are only assigned by default if the post type is registered with the "map_meta_cap" argument set to true (default is false).

Хуков нет.

Возвращает

Объект. Object with all the capabilities as member variables.

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

get_post_type_capabilities($args); $args(объект) (обязательный) Post type registration arguments.

Заметки

  • Смотрите: register_post_type()
  • Смотрите: map_meta_cap()

Список изменений

С версии 3.0.0 Введена.

Код get post type capabilities : wp-includes/post.php WP 5.2.3

capability_type)) { $args->capability_type = array($args->capability_type, $args->capability_type . "s"); } // Singular base for meta capabilities, plural base for primitive capabilities. list($singular_base, $plural_base) = $args->capability_type; $default_capabilities = array(// Meta capabilities "edit_post" => "edit_" . $singular_base, "read_post" => "read_" . $singular_base, "delete_post" => "delete_" . $singular_base, // Primitive capabilities used outside of map_meta_cap(): "edit_posts" => "edit_" . $plural_base, "edit_others_posts" => "edit_others_" . $plural_base, "publish_posts" => "publish_" . $plural_base, "read_private_posts" => "read_private_" . $plural_base,); // Primitive capabilities used within map_meta_cap(): if ($args->map_meta_cap) { $default_capabilities_for_mapping = array("read" => "read", "delete_posts" => "delete_" . $plural_base, "delete_private_posts" => "delete_private_" . $plural_base, "delete_published_posts" => "delete_published_" . $plural_base, "delete_others_posts" => "delete_others_" . $plural_base, "edit_private_posts" => "edit_private_" . $plural_base, "edit_published_posts" => "edit_published_" . $plural_base,); $default_capabilities = array_merge($default_capabilities, $default_capabilities_for_mapping); } $capabilities = array_merge($default_capabilities, $args->capabilities); // Post creation capability simply maps to edit_posts by default: if (! isset($capabilities["create_posts"])) { $capabilities["create_posts"] = $capabilities["edit_posts"]; } // Remember meta capabilities for future reference. if ($args->map_meta_cap) { _post_type_meta_capabilities($capabilities); } return (object) $capabilities; }

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

  • 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_in_menu (логическое |строка ) нужно ли добавлять пункты в меню админки.

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

По умолчанию: значение аргумента show_in_menu . menu_position (целое число ) порядок расположения в меню в админке.

menu_icon (строка ) абсолютный URL иконки для меню. Оптимальное разрешение изображения 16×16 пикселей.

Кроме того, в WordPress 3.8 появился встроенный пакет иконок — вы можете использовать любую из этих иконок, просто указав её название в качестве значения параметра, например 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 (логическое ) нужно ли разрешить постраничную навигацию в постах регистрируемого типа, используя тег (по умолчанию — true) supports (массив ) какие нужно добавить на страницы редактирования записей данного типа.

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

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

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

    add_action ( "init" , "true_register_products" ) ; // Использовать функцию только внутри хука init function true_register_products() { $labels = array ( "name" => "Товары" , "singular_name" => "Товар" , // админ панель Добавить->Функцию "add_new" => "Добавить товар" , "add_new_item" => "Добавить новый товар" , // заголовок тега </span> "edit_item" => <span>"Редактировать товар" </span>, "new_item" => "Новый товар" , "all_items" => "Все товары" , "view_item" => <span>"Просмотр товаров на сайте" </span>, "search_items" => "Искать товары" , "not_found" => <span>"Товаров не найдено." </span>, "not_found_in_trash" => <span>"В корзине нет товаров." </span>, "menu_name" => "Товары" <span>// ссылка в меню в админке </span> ) ; $args = array ( "labels" => $labels , "public" => true , <span>// благодаря этому некоторые параметры можно пропустить </span> "menu_icon" => "dashicons-cart" , <span>// иконка корзины </span> "menu_position" => 5 , "has_archive" => true , "supports" => array ( "title" , "editor" , "excerpt" , "thumbnail" , "comments" ) , "taxonomies" => array ("post_tag" ) ) ; register_post_type("product" ,$args ) ; } </td> </tr></table><p><span class="koXPsjWcBis"></span></p></ul> <p>Создает новый тип записи или изменяет имеющийся.</p> <p>С версии 4.6 был создан новый класс WP_Post_Type и весь код функции теперь обрабатывается этим классом, а эта функция стала оберткой для него.</p> <h4>Таксономии</h4> <p>Если для нового типа записи регистрируется таксономия, то всегда регистрируйте эту таксономию при регистрации типа записи, для этого используя параметр taxonomies . Если вы этого не сделаете, тип поста и таксономии не будут опознаны как связанные при срабатывании хуков, таких как: parse_query или pre_get_posts . Это может привести к неожиданным последствиям и ошибкам.</p> <p><b>Таксономии нужно регистрировать отдельно. </b> Таксономия указывается при регистрации типа записи, однако это только связь, регистрировать её нужно отдельно, с помощью register_taxonomy() .</p> <p>Важно: после создания нового типа записи. Обязательно нужно зайти на страницу Настройки → Постоянные ссылки. Нужно это для того, чтобы правила ЧПУ были пересозданы и туда были добавлены правила нового типа записи.</p> <h5>Возвращает</h5> <p>WP_Post_Type объект (с версии 4.6).</p> <h5>Шаблон для создания нового типа записи</h5> add_action("init", "register_post_types"); function register_post_types(){ register_post_type("post_type_name", array("label" => null, "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" => "", // для родителей (у древовидных типов) "menu_name" => "____", // название меню), "description" => "", "public" => true, // "publicly_queryable" => null, // зависит от public // "exclude_from_search" => null, // зависит от public // "show_ui" => null, // зависит от public // "show_in_nav_menus" => null, // зависит от public "show_in_menu" => null, // показывать ли в меню адмнки // "show_in_admin_bar" => null, // зависит от show_in_menu "show_in_rest" => null, // добавить в REST API. C WP 4.7 "rest_base" => null, // $post_type. C WP 4.7 "menu_position" => null, "menu_icon" => null, //"capability_type" => "post", //"capabilities" => "post", // массив дополнительных прав для этого типа записи //"map_meta_cap" => null, // Ставим true чтобы включить дефолтный обработчик специальных прав "hierarchical" => false, "supports" => [ "title", "editor" ], // "title","editor","author","thumbnail","excerpt","trackbacks","custom-fields","comments","revisions","page-attributes","post-formats" "taxonomies" => , "has_archive" => false, "rewrite" => true, "query_var" => true,)); } <h3>Использование</h3> register_post_type($post_type, $args); $post_type<i>(строка) (обязательный) </i> <p>Название типа записи (максимум 20 символов). Может содержать только строчные символы, числа, _ или - : a-z0-9_- .</p> <p><b>Зарезервированные названия для типов постов </b>. Нельзя использовать следующие названия для новых типов постов, так как они используются WordPress и ваш код будет конфликтовать с текущим кодом или функциями WordPress:</p><p>Post page attachment revision nav_menu_item custom_css customize_changeset action author order theme $args<i>(массив) </i> Массив аргументов.<br><i>По умолчанию: array() (параметры по умолчанию) </i> </p><h3>Аргументы параметра $args</h3> label<i>(строка) </i> Имя типа записи помеченное для перевода на другой язык.<br><i>По умолчанию: $post_type </i> labels<i>(массив) </i> <p>Для неустановленных строк (т.е. по умолчанию), будут использованы:</p> <ul><li>Для не древовидных типов записей - названия "постов".</li> <li>Для древовидных типов записей - названия "постоянных страниц".</li> </ul><p>В массиве можно указать следующие аргументы:</p><p> "name" => "", // основное название для типа записи, обычно во множественном числе. "singular_name" => "", // название для одной записи этого типа. "add_new" => "", // текст для добавления новой записи, как "добавить новый" у постов в админ-панели. // Если нужно использовать перевод названия, вписывайте подобным образом: _x("Add New", "product"); "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 "insert_into_item" => "", // Вставить в запись "uploaded_to_this_item" => "", // Загружено для этой записи "featured_image" => "", // Миниатюра записи "set_featured_image" => "", // Установить миниатюру записи "remove_featured_image" => "", // Удалить миниатюру записи "use_featured_image" => "", // Использовать как миниатюру записи "filter_items_list" => "", // Фильтровать список записей "items_list_navigation" => "", // Навигация по записям "items_list" => "", // Список записей "menu_name" => "", // Название меню. По умолчанию равен name. "name_admin_bar" => "", // Название в админ баре (тулбаре). По умолчанию равен singular_name. "view_items" => "", // Название в тулбаре, для страницы архива типа записей. По умолчанию: «View Posts» / «View Pages». С WP 4.7. "attributes" => "", // Название для метабокса атрибутов записи (у страниц это метабокс «Свойства страницы» - «Page Attributes»). // По умолчанию: «Post Attributes» или «Page Attributes». С WP 4.7. "item_updated" => "", // Текст заметки в редакторе записи при обновлении записи. С WP 5.0. // По умолчанию: «Post updated.» / «Page updated.» "item_published" => "", // Текст заметки в редакторе записи при публикации записи. С WP 5.0. // По умолчанию: «Post published.» / «Page published.» "item_published_privately" => "", // Текст заметки в редакторе записи при публикации private записи. С WP 5.0. // По умолчанию: «Post published privately.» / «Page published "item_reverted_to_draft" => "", // Текст заметки в редакторе записи при возврате записи в draft. С WP 5.0. // По умолчанию: «Post reverted to draft.» / «Page reverted to "item_scheduled" => "", // Текст заметки в редакторе записи при запланированной публикации на будущую дату. С WP 5.0. // По умолчанию: «Post scheduled.» / «Page scheduled.» </p><p><i>Для полного списка значений см. get_post_type_labels() </i></p> <p><i>По умолчанию: если не установлено, name и singular_name примят значение аргумента label </i></p><p>Description<i>(строка) </i> Короткое описание этого типа записи. Значение используется в REST API. Значение можно получить с помощью функции get_the_post_type_description() .<br><i>По умолчанию: "" </i> public<i>(логический) </i> </p><p>Определяет является ли тип записи публичным или нет. На основе этого параметра строятся много других, т.е. это своего рода пред-установка для следующих параметров:</p> <ul><li> <ul><li>show_ui = false - не показывать пользовательский интерфейс (UI) для этого типа записей</li> <li>publicly_queryable = false - запросы относящиеся к этому типу записей не будут работать в шаблоне</li> <li>exclude_from_search = true - этот тип записей не будет учитываться при поиске по сайту</li> <li>show_in_nav_menus = false - этот тип записей будет спрятан из выбора меню навигации</li> </ul></li> <li>true <ul><li>show_ui = true</li> <li>publicly_queryable = true</li> <li>exclude_from_search = false</li> <li>show_in_nav_menus = true</li> </ul></li> </ul><ul><li>title - блок заголовка;</li> <li>editor - блок для ввода контента;</li> <li>author - блок выбора автора;</li> <li>thumbnail блок выбора миниатюры записи. Нужно также включить поддержку в установке темы post-thumbnails ;</li> <li>excerpt - блок ввода цитаты;</li> <li>trackbacks - включает поддержку трекбеков и пингов (за блоки не отвечает);</li> <li>custom-fields - блок установки произвольных полей;</li> <li>comments - блок комментариев (обсуждение);</li> <li>revisions - блок ревизий (не отображается пока нет ревизий);</li> <li>page-attributes - блок атрибутов постоянных страниц (шаблон и древовидная связь записей, древовидность должна быть включена).</li> <li>post-formats – блок форматов записи, если они включены в теме.</li> </ul><p><i>По умолчанию: array("title","editor") </i></p><p>Register_meta_box_cb<i>(строка) </i> callback функция, которая будет срабатывать при установки мета блоков для страницы создания/редактирования этого типа записи. Используйте remove_meta_box() и add_meta_box() в callback функции.<br><i>По умолчанию: нет </i> taxonomies<i>(массив) </i> </p><p>Массив зарегистрированных таксономий, которые будут связаны с этим типом записей, например: category или post_tag .</p> <p>Связать таксономии с записью можно позднее через функцию register_taxonomy_for_object_type() .</p> <p>Таксономии нужно регистрировать с помощью функции register_taxonomy() .</p> <p>Этот параметр позволяет указать, какую группу конечных точек мы хотим подключить к создаваемому типу записи (к URL записи). Например, если указать "permalink_epmask" = EP_PAGES & EP_TAGS , то наш тип записи будет иметь все дополнительные варианты URL (конечные точки), которые предусмотрены для постоянных страниц и меток.</p> <p>По умолчанию permalink_epmask = EP_PERMALINK - это означает, что в URL создаваемого типа записи (в правила ЧПУ) будут добавлены конечные точки, которые добавляются к обычным записям WordPress: пагинация, страница комментов и т.д.</p> <p>Если не нужно добавлять никаких конечных точек к новому типу записи, то нужно указать EP_NONE . Или наоборот, указываем EP_ALL , когда нужно добавить все конечные точки.</p> <p><i>По умолчанию: EP_PERMALINK </i></p><p>Has_archive<i>(строка/логический) </i> </p><p>Включить поддержку страниц архивов для этого типа записей (пр. УРЛ записи выглядит так: site.ru/type/post_name , тогда УРЛ архива будет такой: site.ru/type .</p> <p>Если указать строку, то она будет использована в ЧПУ. Например, укажем тут typepage и получим ссылку на архив типа записи такого вида: site.ru/typepage .<br> Файл этого архива в теме будет иметь вид archive-type.php . Для архивов будет добавлено новое правило ЧПУ, если аргумент rewrite включен.<br><i>По умолчанию: false </i></p><p>Rewrite<i>(массив/логический) </i> </p><p>Использовать ли ЧПУ для этого типа записи. Чтобы не использовать ЧПУ укажите false. По умолчанию: true - название типа записи используется как префикс в ссылке. Можно в массиве указать дополнительные параметры для построения ЧПУ:</p> <ul><p><b>slug </b> <i>(строка) </i><br> Префикс в ЧПУ (/префикс/ярлык_записи). Используйте array("slug" => $slug) , чтобы создать другой префикс.<br> В этом параметре можно указывать плейсхолдеры типа %category% . Но их нужно создать с помощью add_rewrite_tag() и научить WP их понимать.<br><i>По умолчанию: название типа записи </i></p> <p><b>with_front </b> <i>(логический) </i><br> Нужно ли в начало вставлять общий префикс из настроек. Префикс берется из $wp_rewite->front . Например, если структура постоянных ссылок записей в настройках имеет вид blog/%postname% , то при false получим: /news/название_поста, а при true получим: /blog/news/название_поста.<br><i>По умолчанию: true </i></p> <p><b>feeds </b> <i>(логический) </i><br> Добавить ли правило ЧПУ для RSS ленты этого типа записи.<br><i>По умолчанию: значение аргумента has_archive </i></p> <li><b>pages </b> <i>(логический) </i><br> Добавить ли правило ЧПУ для пагинации архива записей этого типа. Пр: /post_type/page/2 .<br><i>По умолчанию: true </i></li> </ul><p><i>По умолчанию: true (тип записи используется как префикс) </i></p><p>Query_var<i>(строка/логический) </i> </p><p>Устанавливает название параметра запроса для создаваемого типа записи.</p> <p>Ставим false, чтобы убрать возможность запросов.</p> <ul><li>false - отключает параметр запроса. Запись не будет доступна по URL: /?{query_var}={post_slug} .</li> <li>string - указывает название параметра зпроса. /?{query_var_string}={post_slug} .</li> </ul><p>Заметка: query_var не имеет смысла, если параметр publicly_queryable = false .</p> <p>Заметка: Этот параметр добавляет указанное значение (если не указано, то ярлык типа записи) в список разрешенных параметров WordPress, чтобы WordPress понимал этот параметр запроса, см. add_rewrite_tag() . WordPress удаляет любые параметры запроса, о которых он не знает.</p> <p>Пример:<br> Допустим мы регаем тип записи book и указали в этом параметре строку bookname . Теперь, пройде на страницу книги по ссылке /book/harry-potter , в коде обрабатывающем эту страницу get_query_var("bookname") вернет harry-potter . А если бы мы ничего не указали в этом параметре (он был бы true), то чтобы получить harry-potter , нам нужно было бы использовать get_query_var("book") .</p> <p><i>По умолчанию: true - устанавливается аргумент $post_type </i></p><p>Can_export<i>(логический) </i> Возможность экспорта этого типа записей.<br><i>По умолчанию: true </i> delete_with_user<i>(логический) </i> </p><ul><li>true - удалять записи этого типа принадлежащие пользователю при удалении пользователя. Если включена корзина, записи не удаляться, а поместятся в корзину.</li> <li>false - при удалении пользователя его записи этого типа никак не будут обрабатываться.</li> <li>null - записи удаляться или будут перемещены в корзину, если post_type_supports("author") установлена. И не обработаются, если поддержки "author" у типа записи нет.</li> </ul> // $tax_slug = get_term_parents_list($term_id, $tax_name, array("separator" => "/", "format" => "slug", "link" => false, "inclusive" => true,)); <p>Также важно, чтобы при реге типа записи, параметр hierarchical был false !</p> <h4>#3 Добавление таксономии в ЧПУ (у записи и таксы одинаковый префикс)</h4> <p>Этот пример показывает как создать запись типа Вопросы и разделы для нее. При этом ЧПУ будут:</p> <ul><li>У записи: site.ru/faq/{категория}/{ярлык-записи}</li> <li>У таксы: site.ru/faq/{категория}</li> </ul><p>Тут важно сначала регнуть таксу, а потом тип записи...</p><p>Add_action("init", "register_faq_post_type"); function register_faq_post_type() { // Раздел вопроса - faqcat register_taxonomy("faqcat", array("faq"), array("label" => "Раздел вопроса", // определяется параметром $labels->name "labels" => array("name" => "Разделы вопросов", "singular_name" => "Раздел вопроса", "search_items" => "Искать Раздел вопроса", "all_items" => "Все Разделы вопросов", "parent_item" => "Родит. раздел вопроса", "parent_item_colon" => "Родит. раздел вопроса:", "edit_item" => "Ред. Раздел вопроса", "update_item" => "Обновить Раздел вопроса", "add_new_item" => "Добавить Раздел вопроса", "new_item_name" => "Новый Раздел вопроса", "menu_name" => "Раздел вопроса",), "description" => "Рубрики для раздела вопросов", // описание таксономии "public" => true, "show_in_nav_menus" => false, // равен аргументу public "show_ui" => true, // равен аргументу public "show_tagcloud" => false, // равен аргументу show_ui "hierarchical" => true, "rewrite" => array("slug"=>"faq", "hierarchical"=>false, "with_front"=>false, "feed"=>false), "show_admin_column" => true, // Позволить или нет авто-создание колонки таксономии в таблице ассоциированного типа записи. (с версии 3.5))); // тип записи - вопросы - faq register_post_type("faq", array("label" => "Вопросы", "labels" => array("name" => "Вопросы", "singular_name" => "Вопрос", "menu_name" => "Архив вопросов", "all_items" => "Все вопросы", "add_new" => "Добавить вопрос", "add_new_item" => "Добавить новый вопрос", "edit" => "Редактировать", "edit_item" => "Редактировать вопрос", "new_item" => "Новый вопрос",), "description" => "", "public" => true, "publicly_queryable" => true, "show_ui" => true, "show_in_rest" => false, "rest_base" => "", "show_in_menu" => true, "exclude_from_search" => false, "capability_type" => "post", "map_meta_cap" => true, "hierarchical" => false, "rewrite" => array("slug"=>"faq/%faqcat%", "with_front"=>false, "pages"=>false, "feeds"=>false, "feed"=>false), "has_archive" => "faq", "query_var" => true, "supports" => array("title", "editor"), "taxonomies" => array("faqcat"),)); } ## Отфильтруем ЧПУ произвольного типа // фильтр: apply_filters("post_type_link", $post_link, $post, $leavename, $sample); add_filter("post_type_link", "faq_permalink", 1, 2); function faq_permalink($permalink, $post){ // выходим если это не наш тип записи: без холдера %products% if(strpos($permalink, "%faqcat%") === false) return $permalink; // Получаем элементы таксы $terms = get_the_terms($post, "faqcat"); // если есть элемент заменим холдер if(! is_wp_error($terms) && !empty($terms) && is_object($terms)) $term_slug = array_pop($terms)->slug; // элемента нет, а должен быть... else $term_slug = "no-faqcat"; return str_replace("%faqcat%", $term_slug, $permalink); } </p><h3>Заметки</h3> <h4>Плагин для реги типа записи</h4> <p>Есть удобный плагин, который позволяет регистрировать новые типы записей (постов) и новые таксономии: Custom Post Type UI</p> <h4>Переименование заголовков типа записи</h4> <p>Если тип записи уже зарегистрирован, но нам нужно назвать его как-то иначе, используйте следующий код.</p> <p>Этот код показывает, как переименовать стандартный тип записи "Записи" в "Статьи":</p><p> ## заменим слово «записи» на «статьи» //$labels = apply_filters("post_type_labels_{$post_type}", $labels); add_filter("post_type_labels_post", "rename_posts_labels"); function rename_posts_labels($labels){ // заменять автоматически не пойдет например заменили: Запись = Статья, а в тесте получится так "Просмотреть статья" /* оригинал stdClass Object ("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" => "Все записи", "archives" => "Архивы записей", "insert_into_item" => "Вставить в запись", "uploaded_to_this_item" => "Загруженные для этой записи", "featured_image" => "Миниатюра записи", "set_featured_image" => "Задать миниатюру", "remove_featured_image" => "Удалить миниатюру", "use_featured_image" => "Использовать как миниатюру", "filter_items_list" => "Фильтровать список записей", "items_list_navigation" => "Навигация по списку записей", "items_list" => "Список записей", "menu_name" => "Записи", "name_admin_bar" => "Запись",) */ $new = 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" => "Все статьи", "archives" => "Архивы статей", "insert_into_item" => "Вставить в статью", "uploaded_to_this_item" => "Загруженные для этой статьи", "featured_image" => "Миниатюра статьи", "filter_items_list" => "Фильтровать список статей", "items_list_navigation" => "Навигация по списку статей", "items_list" => "Список статей", "menu_name" => "Статьи", "name_admin_bar" => "Статью", // пункте "добавить"); return (object) array_merge((array) $labels, $new); } </p><p>Очень дешевые, но качественные подписчики в Инстаграме доступны по адресу https://doctorsmm.com/ . Тут Вы сможете найти любое предложение персонально для Вашего аккаунта. На сайте представлено широкое разнообразие качества добавляемых страниц и скоростной режим, а также действует таргетирование аудитории по географическому признаку.</p><h3>Заметки</h3> <ul><li>Global. Массив. $wp_post_types List of post types.</li> </ul><h3>Список изменений</h3> <table><tbody><tr><td>С версии 2.9.0 </td> <td>Введена. </td> </tr><tr><td>С версии 3.0.0 </td> <td>The show_ui argument is now enforced on the new post screen. </td> </tr><tr><td>С версии 4.4.0 </td> <td>The show_ui argument is now enforced on the post type listing screen and post editing screen. </td> </tr><tr><td>С версии 4.6.0 </td> <td>Post type object returned is now an instance of WP_Post_Type . </td> </tr><tr><td>С версии 4.7.0 </td> <td>Introduced show_in_rest , rest_base and rest_controller_class arguments to register the post type in REST API. </td> </tr></tbody></table><h3><span>Код register post type : </span> <span> wp-includes/post.php WP 5.2.3 </span></h3> <?php function register_post_type($post_type, $args = array()) { global $wp_post_types; if (! is_array($wp_post_types)) { $wp_post_types = array(); } // Sanitize post type name $post_type = sanitize_key($post_type); if (empty($post_type) || strlen($post_type) > 20) { _doing_it_wrong(__FUNCTION__, __("Post type names must be between 1 and 20 characters in length."), "4.2.0"); return new WP_Error("post_type_length_invalid", __("Post type names must be between 1 and 20 characters in length.")); } $post_type_object = new WP_Post_Type($post_type, $args); $post_type_object->add_supports(); $post_type_object->add_rewrite_rules(); $post_type_object->register_meta_boxes(); $wp_post_types[ $post_type ] = $post_type_object; $post_type_object->add_hooks(); $post_type_object->register_taxonomies(); /** * Fires after a post type is registered. * * @since 3.3.0 * @since 4.6.0 Converted the `$post_type` parameter to accept a `WP_Post_Type` object. * * @param string $post_type Post type. * @param WP_Post_Type $post_type_object Arguments used to register the post type. */ do_action("registered_post_type", $post_type, $post_type_object); return $post_type_object; } <p>О произвольных типах записей в Вордпрессе (CPT, Custom Post Types in WordPress), как создать и настроить, добавить категории и теги, как сделать вложенные URL /тип записи/рубрика/запись или http://example.com/post_type/category/post/ .<br> Тут также описывается, как расширить стандартный функционал WordPress, создав новые типы записей, которые можно использовать в различных целях: добавить собственное порфтолио, картотеку фильмов и музыки, каталог продукции, календарь событий, даже сделать свой небольшой интернет-магазин (потому что для большого лучше пользоваться готовыми решениями навроде WooCommerce) или социальную сеть, и много чего ещё в этом духе.<br> Вначале общая информация, дальше — частности.</p> <h2>О записях в WordPress: где хранятся в базе данных, и как их получить</h2> <p>Абсолютно все записи в WordPress, про которые чуть ниже, хранятся в одной таблице: wp_posts . Метаданные постов, например, данные из метабоксов , хранятся в таблице wp_postmeta .</p> <p>Приведу пример, как получить 10 записей типа post (стандартные <b>Записи </b> в панели администратора).<br> В общих чертах, данные особо запрашивать не надо. В шаблонах они уже предустановлены, например, в single.php данные по записи уже доступны для обработки в цикле</p><p>If (have_posts()) { while (have_posts()) { the_post(); // Тут используем данные из цикла, такие как the_title() и т.п. } } </p><p>Если данные нужно получить где-то вне цикла или шаблона, используется запрос WP_Query</p><p> $args = array("post_type" => "post", // Тип поста: page, attachment, ... "posts_per_page" => 10, // 10 записей за раз); $p = get_posts($args); // Данные можно раскрыть в цикле if (!empty($p)) { foreach ($p as $post) { setup_postdata($post); ?> "><?= the_title() ?> <?php } wp_reset_postdata(); } </p><p>Данные можно получить посредством SQL запроса:</p><p>Global $wpdb; $query = "SELECT * FROM {$wpdb -> posts} WHERE post_type = "post" LIMIT 10"; $p = $wpdb -> get_results($query); exit(print_r($p)); // в $p теперь массив с данными о постах </p><p>Все три способа выше дадут одинаковый результат на выходе.<br></p> <h2>Предустановленные типы записей в WordPress: post, page, attachment, revision, nav_menu_item</h2> <h3>Записи или посты (post)</h3> <p>Самая используемая единица из всех типов, что есть в WordPress — Записи (они же посты, post). Используется в роли постов блога и тому подобного. Имеет 2 предустановленных таксономии: рубрики, они же категории (category) и метки, они же теги (post_tag).<br> Таксономии служат для сортировки и упорядочивания записей.<br> Рубрики отличаются от меток тем, что имеют древовидную структуру (могут быть вложенными друг в друга).<br> Метки являются независимыми друг от друга единицами и этим чем-то похожи на Записи.<br> Также, по умолчанию, из записей формируется RSS лента сайта на Вордпрессе.</p> <p>Для Записей используются следующие файлы шаблонов (в порядке приоритета):</p> <ol><li>single-post.php</li> <li>single.php</li> <li>singular.php</li> <li>index.php</li> </ol><blockquote class="note"><p>Файлы шаблонов ищутся сверху вниз по списку в порядке приоритета. Если файл шаблона найден в теме, используется он, а поиск прекращается.</p> </blockquote> <h3>Страницы (page)</h3> <p>Страницы используются, в основном, в роли служебных страниц, посадочных страниц — лендингов, сборника энциклопедии и тому подобного. Имеют древовидную иерархию, то есть могут быть вложенными друг в друга, что отразится в адресе конечной страницы (ярлыки родительских будут присутствовать в цепочке URL), и в этой роли имеется возможность выставить им приоритет в сортировке.<br> Чтобы сделать лендинг, вы можете пойти двумя путями:<br></p> <h4>Создаём специальный шаблон страницы (page)</h4> <p>Где-нибудь внутри темы в корне или её поддиректории создать файл с произвольным названием и расширением php , например, landing.php . Внутри вы можете разместить совершенно любой шаблон, который может быть абсолютно не похож на другие страницы сайта. Но главное, это поместить вот такой код в начало файла:</p><p> <?php /* Template Name: Наш уникальный лендинг */ </p><p>Template Name — это специальная метка, которая говорит WordPress о том, что этот файл — специальный шаблон.<br> Теперь при создании и редактировании любой страницы (page) посмотрите в блоке справа с названием Атрибуты страницы, в нём в разделе Шаблон вы можете выбрать наш уникальный лендинг.</p> <p>Для Страниц (Page) используется следующая иерархия шаблонов. Как и с Записями, указываю в порядке приоритета:</p> <ol><li>{шаблон}.php</li> <li>page-{ярлык_страницы}.php</li> <li>page-{ID_страницы}</li> <li>page.php</li> <li>singular.php</li> <li>index.php</li> </ol><h3>Прикрепления, вложения или аттачменты (attachment)</h3> <p>Служебный тип, предназначенный для хранения информации о файлах (изображениях, аудио, видео и тому подобных), которые загружались через загрузчик в стандартном редакторе WordPress при редактировании Записи, Страницы или подобного: размер, вес, описание, к какому посту или странице прикреплены, и тому подобное.</p> <p>Получить вложения для последующей манипуляции над ними можно с помощью следующего кода:</p><p> $args = array("post_type" => "attachment", // Тип поста: attachment "post_status" => "inherit", // По умолчанию "publish", а с ним вложения не получить, поэтому указываем специальный статус вложения "inherit"); $p = get_posts($args); exit(print_r($p)); // На выходе будем иметь массив с вложениями </p><p>Иерархия шаблонов для аттачментов:</p> <ol><li>{mime-тип}.php</li> <li>{mime-подтип}.php</li> <li>{mime-тип-подтип}.php</li> <li>attachment.php</li> <li>single.php</li> <li>singular.php</li> <li>index.php</li> </ol><h3>Редакции, черновики или ревизии (revision)</h3> <p>Редакции, они же Ревизии — это версии черновиков записей, которые создаются автоматически, пока вы пишете статью в административной панели Вордпресса или сохраняете статью без фактической её публикации.<br> В процессе написания, для каждой статьи по умолчанию сохраняется каждая версия черновика. Можно сравнить две разные версии, и к нужной можно откатиться назад.<br> Хранить помногу версий одной и той же статьи — довольно накладно и часто бессмысленно (хотя, наверное, правильнее было бы оставлять всё по умолчанию, регулярно подчищая старые редакции с помощью плагина, например WP Optimize), поэтому число сохраняемых версий Ревизий можно изменить с помощью 2 вариантов:</p> <ol><li>Использовать фильтр wp_revisions_to_keep</li> <li>Прописать в wp-config.php //Отключаем ревизии до минимально возможного значения define("WP_POST_REVISIONS", 0); <p>Возможные значения:</p> <ul><li>true или -1: сохраняет каждую версию черновика. Вариант по умолчанию</li> <li>false или 0: отключает сохранение черновиков, кроме 1 автосохранения</li> <li>Целое число больше нуля: сохраняется указанное число версий черновиков + 1 автосохранение. Старые версии, не укладывающиеся в указанное число, автоматически удаляются</li> </ul></li> </ol><h3>Элементы навигационного меню (nav_menu_item)</h3> <p>Навигационное меню (nav_menu_item) — это тип записей, который хранит информацию об единице навигации в WordPress. Первый, и пока единственный тип записи, который используется не как остальные типы записей, данные для работы и отображения на сайте получают свои отдельные функции.<br> Также, навигационные меню по умолчанию не включены. Чтобы их включить, нужно объявить об их поддержке в :</p> <ol><li>Прописать add_theme_support("menus");</li> <li>Или зарегистрировать место под меню с помощью register_nav_menu() , тогда поддержка меню включится автоматически</li> </ol><p>Для получения данных пользуйтесь wp_nav_menu() , потому что WP_Query не будет работать, и это отличительная особенность типа постов nav_menu_item</p><p> // Этот код сработает wp_nav_menu(); // Выведет первое зарегистрированное непустое меню // А код ниже работать не будет $args = array("post_type" => "nav_menu_item", // Тип поста: page, attachment, ...); $p = get_posts($args); exit(print_r($p)); // На выходе будем иметь пустой массив </p><h2>Пользовательский Произвольный тип записи (Custom Post Type, CPT WordPress)</h2> <p>Вот мы и подошли к главному — тому инструменту, который позволяет расширить стандартный блоговый функционал WordPress до бесконечных возможностей: пользовательский произвольный тип записи.<br> Самый простой пример, как можно зарегистрировать наш новый тип записи sheensay_product</p><p>Add_action("init", "sheensay_post_type"); function sheensay_post_type() { register_post_type("sheensay_product", array("labels" => array("name" => "Продукция", "singular_name" => "Продукцию",), "public" => true, // тип записи открыт для поиска и тому подобного "has_archive" => true, // Включаем страницы архивов "supports" => array("title", "editor", "thumbnail", "comments"), // Включаем поддержку заголовка, редактора, миниатюры, комментариев)); } </p><p>Здесь sheensay_product — это название нового типа записей. Оно не должно конфликтовать с другими в системе, об этом подробнее ниже.<br> Также, в этом варианте оно служит ярлыком этого типа записей, то есть присутствует в URL. Если же хотите указать другой ярлык, например <b>продукция </b>, делайте как на примере ниже</p><p>Add_action("init", "sheensay_post_type"); function sheensay_post_type() { register_post_type("sheensay_product", array("labels" => array("name" => "Продукция", "singular_name" => "Продукцию",), "public" => true, "rewrite" => array("slug" => "продукция"), // Тут определяется ярлык Custom Post Type "has_archive" => true, "supports" => array("title", "editor", "thumbnail"),)); } </p><h3>Как правильно подобрать название нового типа записи</h3> <blockquote class="attention"><p>В WordPress зарезервированы следующие названия, которые нельзя использовать в качестве имени нового типа записи:</p> <ul><li>attachment</li> <li>revision</li> <li>nav_menu_item</li> <li>action</li> <li>theme</li> <li>order</li> </ul><p>Также, стоит воздержаться от использования префикса wp_ в начале названия, так как, возможно, это вызовет конфликты с будущими версиями ядра WordPress.<br> Лучше всего, если вы будете предварять названия произвольными префиксами, связанными с названием вашего сайта, продукта или бренда, например sheensay_product , тогда гарантированно избежите потенциальных конфликтов</p> </blockquote> <h3>Как сделать произвольную таксономию</h3> <p>Произвольные типы записей могут использовать таксономии из записей, например, рубрики (категории) или метки (теги), но можно, чтобы таксономии были свои.</p><p>Add_action("init", "sheensay_post_type"); function sheensay_post_type() { // Регистрируем таксономию register_taxonomy("sheensay_product_type", "sheensay_product", array("label" => "Типы", "hierarchical" => true, // Если TRUE, таксономия будет аналогом рубрик (категорий). Если FALSE (по умолчанию), то таксономия станет аналогом меток (тегов). "rewrite" => array("slug" => "тип-продукции"),)); // Регистрируем произвольный тип записи (Custom Post Type) register_post_type("sheensay_product", array("labels" => array("name" => "Продукция", "singular_name" => "Продукцию",), "public" => true, "rewrite" => array("slug" => "продукция"), // Тут определяется ярлык CPT "has_archive" => true, "supports" => array("title", "editor", "thumbnail"), // Включаем поддержку заголовка, редактора, миниатюры)); } </p><h3>Шаблоны для произвольных типов постов</h3> <p>Всё зависит от того, какого рода информация отображается. Вариантов может быть 3: шаблон конкретной записи, шаблон архивов записей и шаблон таксономий<br></p> <h4>Шаблон страницы записи</h4> <p>Перечисляются в порядке приоритета</p> <ol><li>single-{тип_поста}.php</li> <li>single.php</li> <li>index.php</li> </ol><h4>Шаблон архива записей</h4> <ol><li>archive-{тип_поста}.php</li> <li>archive.php</li> <li>index.php</li> </ol><h4>Шаблон произвольной таксономии</h4> <ol><li>taxonomy-{имя_таксономии}-{имя_термина}.php</li> <li>taxonomy-{имя_таксономии}.php</li> <li>taxonomy.php</li> <li>archive.php</li> <li>index.php</li> </ol><p>Здесь имя_таксономии — это sheensay_product_type , а имя_термина — это ярлык той таксономии, что вы создадите в админке.</p> <h3>Как получить данные произвольного типа записей (Custom Post Type WordPress) и отобразить на сайте</h3> <p>Получить данные произвольного типа записей (Custom Post Type) в WordPress для отображения на сайте можно теми же способами, что и обычные Записи и Страницы</p><p> $args = array("post_type" => "sheensay_product", // Указываем наш новый тип записи "posts_per_page" => 10,); $p = get_posts($args); foreach ($p as $post) { setup_postdata($post); ?> "><?= the_title() ?><br /> <?php } wp_reset_postdata(); ?> </p><p>Если же говорить про главный запрос, по которому данные, например, предзагружаются для вывода на главной странице или стандартных страницах архивов, то произвольные типы записей там отключены.<br> Поэтому, если вы хотите, чтобы какая-либо созданный тип записей отображался, скажем, на страницах архивов наряду с обычными записями, вам нужно изменить фильтр предзагрузки постов</p><p> // Подключаем к стандартным "post" и "page" наш "sheensay_product" add_action("pre_get_posts", "add_sheensay_product_in_main_query"); function add_sheensay_product_in_main_query($query) { if (is_archive() && $query -> is_main_query()) $query -> set("post_type", array("post", "page", "sheensay_product")); return $query; } </p><h3>Готовый класс для создания произвольного типа записей с произвольной таксономией</h3> <p>Ниже представлен класс, с помощью которого вы сможете зарегистрировать любой произвольный тип записей с собственной таксономией, а URL будет иметь вид<br> http://example.com/продукция/тип/продукт</p> <blockquote class="note"><p>Чтобы URL формировался, вы должны перейти в настройки постоянных ссылок /wp-admin/options-permalink.php и установить любой отличный от простого вид общих настроек</p> <p><img src='https://i2.wp.com/sheensay.ru/wp-content/uploads/2016/08/options-permalink.png' width="100%" loading=lazy></p> </blockquote> <p>Ниже сам код класса. Вы можете не вносить в него никаких изменений, а поменять ярлык типа записи можно в самом конце в строке new Sheensay_Product("продукция"); <br> Сам код пишется в или в . Первый вариант предпочтительнее, так как в этом случае, вы не потеряете доступа к контенту нового типа записей при смене активной темы.</p><p> <??p=1713 * */ final class Sheensay_Product { // Ярлык произвольного типа записи по умолчанию private $post_type = "продукция"; function __construct($post_type = "") { // Переопределяем значение ярлыка по умолчанию if ($post_type) $this -> post_type = $post_type; /* * Регистрируем Custom Post Type */ add_action("init", array($this, "sheensay_cpt_product")); /* * Фильтруем URL */ add_filter("post_type_link", array($this, "product_permalink_structure"), 10, 2); /* * Чтобы работала пагинация */ add_action("generate_rewrite_rules", array($this, "fix_product_category_pagination")); } function sheensay_cpt_product() { /* * Регистрируем произвольную таксономию к новому типу записей */ register_taxonomy("sheensay_product_type", "sheensay_product", array("label" => "Типы", "hierarchical" => true, "query_var" => true, "rewrite" => array("slug" => $this -> post_type),)); /* * Регистрируем новый тип записи */ $labels = array("name" => "Продукция", // Основное название "singular_name" => "Продукцию", // Добавить "add_new" => "Добавить новую", // Имя ссылки на новую запись в сайдбаре "add_new_item" => "Добавить новую продукцию", // Заголовок в редакторе при добавлении новой записи); $args = array("labels" => $labels, "public" => true, "publicly_queryable" => true, "show_ui" => true, "query_var" => true, "capability_type" => "post", "hierarchical" => false, "menu_position" => null, "supports" => array("title", "editor", "thumbnail", "excerpt"), "rewrite" => array("slug" => $this -> post_type . "/%sheensay_product_type%", "with_front" => false,), "has_archive" => $this -> post_type,); register_post_type("sheensay_product", $args); if (current_user_can("manage_options")) // Вот с этой функцией осторожней. Она сбрасывает все правила определения URL. Лучше её закомментировать после завершения всех работ flush_rewrite_rules(); } function product_permalink_structure($post_link, $post) { if (FALSE !== strpos($post_link, "%sheensay_product_type%")) { $product_type_term = get_the_terms($post -> ID, "sheensay_product_type"); if (!empty($product_type_term)) $post_link = str_replace("%sheensay_product_type%", $product_type_term -> slug, $post_link); } return $post_link; } function fix_product_category_pagination($wp_rewrite) { unset($wp_rewrite -> rules[ $this -> post_type . "/([^/]+)/page/?({1,})/?$"]); $wp_rewrite -> rules = array($this -> post_type . "/?$" => $wp_rewrite -> index . "?post_type=sheensay_product", $this -> post_type . "/page/?({1,})/?$" => $wp_rewrite -> index . "?post_type=sheensay_product&paged=" . $wp_rewrite -> preg_index(1), $this -> post_type. "/([^/]+)/page/?({1,})/?$" => $wp_rewrite -> index . "?sheensay_product_type=" . $wp_rewrite -> preg_index(1) . "&paged=" . $wp_rewrite -> preg_index(2),) + $wp_rewrite -> rules; } } /* * Запускаем класс * В скобках можно определить название ярлыка типа записи */ new Sheensay_Product("продукция"); </p><p>Теперь в админке вы можете зарегистрировать новую продукцию и их типы</p> <script>document.write("<img style='display:none;' src='//counter.yadro.ru/hit;artfast_after?t44.1;r"+ escape(document.referrer)+((typeof(screen)=="undefined")?"": ";s"+screen.width+"*"+screen.height+"*"+(screen.colorDepth? screen.colorDepth:screen.pixelDepth))+";u"+escape(document.URL)+";h"+escape(document.title.substring(0,150))+ ";"+Math.random()+ "border='0' width='1' height='1' loading=lazy>");</script> </div> </article> <div class="center"><em>Эта статья также доступна на следующих языках: <a href="/th/ebay-100/">Тайский</a><br><br></em> </div> <div class="share42init" data-url="/luchshie-magazinyi-ebay-spisok-100/" data-title="Лучшие магазины eBay: список 100+"></div> <script type="text/javascript" src="/wp-includes/share42/share42.js"></script> <div id="disqus_thread"> <div id="dsq-content"> <ul id="dsq-comments"> <li class="comment even thread-even depth-1" id="dsq-comment-1071"> <div id="dsq-comment-header-1071" class="dsq-comment-header"> <cite id="dsq-cite-1071"> <span id="dsq-author-user-1071">Next</span> </cite> </div> <div id="dsq-comment-body-1071" class="dsq-comment-body"> <div id="dsq-comment-message-1071" class="dsq-comment-message"><p>Огромное Вам СПАСИБО за очень полезную информацию в статье. Очень понятно все изложено. Чувствуется, что проделана большая работа по анализу работы магазина eBay</p> </div> </div> <ul class="children"> <li class="comment odd alt depth-2" id="dsq-comment-1072"> <div id="dsq-comment-header-1072" class="dsq-comment-header"> <cite id="dsq-cite-1072"> <a id="dsq-author-user-1072" href="/" target="_blank" >rootshell</a> </cite> </div> <div id="dsq-comment-body-1072" class="dsq-comment-body"> <div id="dsq-comment-message-1072" class="dsq-comment-message"><p>Спасибо вам и другим постоянным читателям моего блога. Без вас у меня не было бы достаточной мотивации, чтобы посвящать много времени ведению этого сайта. У меня мозги так устроены: люблю копнуть вглубь, систематизировать разрозненные данные, пробовать то, что раньше до меня никто не делал, либо не смотрел под таким углом зрения. Жаль, что только нашим соотечественникам из-за кризиса в России отнюдь не до шоппинга на eBay. Покупают на Алиэкспрессе из Китая, так как там в разы дешевле товары (часто в ущерб качеству). Но онлайн-аукционы eBay, Amazon, ETSY легко дадут китайцам фору по ассортименту брендовых вещей, винтажных вещей, ручной работы и разных этнических товаров.</p> </div> </div> <ul class="children"> <li class="comment even depth-3" id="dsq-comment-1073"> <div id="dsq-comment-header-1073" class="dsq-comment-header"> <cite id="dsq-cite-1073"> <span id="dsq-author-user-1073">Next</span> </cite> </div> <div id="dsq-comment-body-1073" class="dsq-comment-body"> <div id="dsq-comment-message-1073" class="dsq-comment-message"><p>В ваших статьях ценно именно ваше личное отношение и анализ темы. Вы этот блог не бросайте, я сюда часто заглядываю. Нас таких много должно быть. Мне на эл. почту пришло недавно предложение о том, что научат торговать на Амазоне и eBay. И я вспомнила про ваши подробные статьи об этих торг. площ. Перечитала все заново и сделала вывод, что курсы- это лохотрон. Сама на eBay еще ничего не покупала. Я не из России , а из Казахстана (г. Алматы). Но нам тоже лишних трат пока не надо. Желаю вам удачи и берегите себя в азиатских краях.</p> </div> </div> </li> </ul> </li> </ul> </li> <li class="comment odd alt thread-odd thread-alt depth-1" id="dsq-comment-1281"> <div id="dsq-comment-header-1281" class="dsq-comment-header"> <cite id="dsq-cite-1281"> <a id="dsq-author-user-1281" href="/" target="_blank" >rootshell</a> </cite> </div> <div id="dsq-comment-body-1281" class="dsq-comment-body"> <div id="dsq-comment-message-1281" class="dsq-comment-message"><p>Еще приятно, что попытки eBay по руссификации интерфейса для пользователей из России и стран СНГ, начали приносить плоды. Ведь подавляющая часть граждан стран бывшего СССР не сильна познаниями иностранных языков. Английский язык знают не более 5% населения. Среди молодежи — побольше. Поэтому хотя бы интерфейс на русском языке — это большая помощь для онлайн-шоппинга на этой торговой площадке. Ебей не пошел по пути китайского собрата Алиэкспресс, где совершается машинный (очень корявый и непонятный, местами вызывающий смех) перевод описания товаров. Надеюсь, что на более продвинутом этапе развития искусственного интеллекта станет реальностью качественный машинный перевод с любого языка на любой за считанные доли секунды. Пока имеем вот что (профиль одного из продавцов на ебей с русским интерфейсом, но англоязычным описанием):<br /> https://uploads.disquscdn.com/images/7a52c9a89108b922159a4fad35de0ab0bee0c8804b9731f56d8a1dc659655d60.png</p> </div> </div> </li> </ul> </div> </div> </div> <div id="sidebar-bottom"> <aside id="sidebar-1" class="sidebar"> <div id="categories-2" class="widget widget_categories_right"> <h4 class="widgettitle">Разделы</h4> <ul style="margin-left:20px;"> <li class="cat-item"><a href="/category/android/">Android</a></li> <li class="cat-item"><a href="/category/apple/">Apple</a></li> <li class="cat-item"><a href="/category/linux/">Linux</a></li> <li class="cat-item"><a href="/category/wifi/">Wi-Fi</a></li> <li class="cat-item"><a href="/category/windows/">Windows</a></li> <li class="cat-item"><a href="/category/internet/">Интернет</a></li> <li class="cat-item"><a href="/category/computer/">Компьютер</a></li> </ul> </div> <div class="widget widget_text_icl"> <div class="textwidget"> <div class="title"> <b><a href="/solutions/avtomaticheskii-rezhim-blokirovki-nedopustim-v-tranzakcii-perevod/" title="Перевод конфигурации на управляемые блокировки">Перевод конфигурации на управляемые блокировки</a></b> </div> <div class="entry"> <p> <a href="/solutions/avtomaticheskii-rezhim-blokirovki-nedopustim-v-tranzakcii-perevod/"><img src="/uploads/1f774172626e8f35b83aa798cd498b86.jpg" alt="Перевод конфигурации на управляемые блокировки" loading=lazy></a> <br> Основные причины перехода на управляемые блокировки: Основная причина - рекомендация 1С:Эксперта на основании показаний или 1С:ЦУП Проблемы с параллельной работой пользователей () Использование... </p> </div> <div class="title"> <b><a href="/devices/kto-pridumal-paipal-istoriya-paypal-kak-paypal-stal-liderom-osnovnye-etapy/" title="Кто придумал пайпал. История PayPal. Как PayPal стал лидером: основные этапы развития платежной системы">Кто придумал пайпал. История PayPal. Как PayPal стал лидером: основные этапы развития платежной системы</a></b> </div> <div class="entry"> <p> <a href="/devices/kto-pridumal-paipal-istoriya-paypal-kak-paypal-stal-liderom-osnovnye-etapy/"><img src="/uploads/9fed2dea6acda6558dce6f0f21709001.jpg" alt="Кто придумал пайпал. История PayPal. Как PayPal стал лидером: основные этапы развития платежной системы" loading=lazy></a> <br> Здравствуйте, уважаемые читатели блога сайт. Сегодня я хочу продолжать наполнять материалами рубрику . До этого я писал про , и , которые являются наиболее . Но не рунетом одним... В мире сейчас... </p> </div> <div class="title"> <b><a href="/modems/rabota-so-snimkami-snapshots-sostoyaniya-virtualnyh-mashin-v/" title="Резервное копирование системы с помощью виртуализации Резервное копирование виртуальных машин virtualbox">Резервное копирование системы с помощью виртуализации Резервное копирование виртуальных машин virtualbox</a></b> </div> <div class="entry"> <p> <a href="/modems/rabota-so-snimkami-snapshots-sostoyaniya-virtualnyh-mashin-v/"><img src="/uploads/7d7b2abdf4eb2499e3b9289d8097cbfe.jpg" alt="Резервное копирование системы с помощью виртуализации Резервное копирование виртуальных машин virtualbox" loading=lazy></a> <br> Использование групп VMГруппы VM позволяют пользователю создавать специальные группы виртуальных машин, для коллективного управления ими. Создайте группу, используя GUI 1) Перетащите одну... </p> </div> <div class="title"> <b><a href="/linux/cluzhba-udalennogo-upravleniya-windows-windows-remote-management-kak/" title="Как активировать Windows Remote Management с помощью групповой политики Что такое WinRS и как его использовать">Как активировать Windows Remote Management с помощью групповой политики Что такое WinRS и как его использовать</a></b> </div> <div class="entry"> <p> <a href="/linux/cluzhba-udalennogo-upravleniya-windows-windows-remote-management-kak/"><img src="/uploads/77e772a50d2fa9792ce92fae20fa156b.jpg" alt="Как активировать Windows Remote Management с помощью групповой политики Что такое WinRS и как его использовать" loading=lazy></a> <br> Настройка удаленного взаимодействия в PowerShell (часть 1) Чтобы обеспечить возможность удаленного взаимодействия с помощью PowerShell, необходимо произвести некоторые настройки. Количество этих... </p> </div> <div class="title"> <b><a href="/miscellaneous/puk-i-pin-kody-mts-vse-sposoby-uznat-pin-kod-sim-karty-mts/" title="Все способы узнать пин код-сим карты мтс">Все способы узнать пин код-сим карты мтс</a></b> </div> <div class="entry"> <p> <a href="/miscellaneous/puk-i-pin-kody-mts-vse-sposoby-uznat-pin-kod-sim-karty-mts/"><img src="/uploads/e670ae73feb1d7f685335129a8608a93.jpg" alt="Все способы узнать пин код-сим карты мтс" loading=lazy></a> <br> Абсолютно все телесистемы России, устанавливают пин и пак коды на свои стартовые пакеты. Зачастую, вопрос, как узнать пин код сим-карты МТС, возникает у абонентов, по неосмотрительности... </p> </div> <div class="title"> <b><a href="/linux/tarif-megafon-vse-vklyucheno-opisanie-obzor-i-sravnenie-vsei/" title="Как не переплачивать: выбираем лучший тариф "МегаФон"">Как не переплачивать: выбираем лучший тариф "МегаФон"</a></b> </div> <div class="entry"> <p> <a href="/linux/tarif-megafon-vse-vklyucheno-opisanie-obzor-i-sravnenie-vsei/"><img src="/uploads/d45a502bbbd1228191fe5dd9711156c4.jpg" alt="Как не переплачивать: выбираем лучший тариф "МегаФон"" loading=lazy></a> <br> Оператор «Megafon» из года в год радует абонентов новыми, актуальными и доступными тарифными планами. Компания старается предоставить клиентам как можно больше разнообразных сервисов и услуг за... </p> </div> <div class="title"> <b><a href="/devices/obzor-besplatnoi-versii-adwcleaner-obzor-besplatnoi-versii-adwcleaner-adwcleaner-chto/" title="Обзор бесплатной версии AdwCleaner AdwCleaner: что это">Обзор бесплатной версии AdwCleaner AdwCleaner: что это</a></b> </div> <div class="entry"> <p> <a href="/devices/obzor-besplatnoi-versii-adwcleaner-obzor-besplatnoi-versii-adwcleaner-adwcleaner-chto/"><img src="/uploads/8cc1bc5ba710c4f8bb10686275f20f3d.jpg" alt="Обзор бесплатной версии AdwCleaner AdwCleaner: что это" loading=lazy></a> <br> Естественно, любой юзер, много времени проводя за интернет-серфингом, не понаслышке знает, как раздражает надоедливая реклама, установка каких-то непонятных панелей в браузер, все более... </p> </div> <div class="title"> <b><a href="/operating-systems/kak-polzovatsya-dr-web-cureit-chtoby-ne-povredit-sistemnye-faily-dr/" title="Dr Web CureIT — где скачать, как настроить и использовать Настройка и запуск сканирования, обезвреживание угроз">Dr Web CureIT — где скачать, как настроить и использовать Настройка и запуск сканирования, обезвреживание угроз</a></b> </div> <div class="entry"> <p> <a href="/operating-systems/kak-polzovatsya-dr-web-cureit-chtoby-ne-povredit-sistemnye-faily-dr/"><img src="/uploads/89fc3f149c6feab8d941161d738563c5.jpg" alt="Dr Web CureIT — где скачать, как настроить и использовать Настройка и запуск сканирования, обезвреживание угроз" loading=lazy></a> <br> В результате обнаружения вредоносной программы антивирусом Dr.Web к ней можно применить одно из следующих действий: Вылечить – если файл поражён компьютерным вирусом, то его можно "очистить",... </p> </div> <div class="title"> <b><a href="/solutions/kak-ustanovit-windows-7-na-noutbuke-s-fleshki-ustanovka-vindovs-s-fleshki/" title="Установка виндовс с флешки через биос">Установка виндовс с флешки через биос</a></b> </div> <div class="entry"> <p> <a href="/solutions/kak-ustanovit-windows-7-na-noutbuke-s-fleshki-ustanovka-vindovs-s-fleshki/"><img src="/uploads/b0497733514ca5da285f1567e2995385.jpg" alt="Установка виндовс с флешки через биос" loading=lazy></a> <br> Содержание Практически все современные портативные компьютеры (кроме Apple) используют операционную систему от компании Microsoft. Иногда возникает ситуация, при которой необходимо провести... </p> </div> <div class="title"> <b><a href="/modems/obzor-i-sravnenie-kondicionerov-mdv-kanalnye-invertornye-mobilnye-i/" title="Кондиционера инструкция пользователя пульт дистанционного управления (сплит-системы) Инструкции для дистанционного пульта управления">Кондиционера инструкция пользователя пульт дистанционного управления (сплит-системы) Инструкции для дистанционного пульта управления</a></b> </div> <div class="entry"> <p> <a href="/modems/obzor-i-sravnenie-kondicionerov-mdv-kanalnye-invertornye-mobilnye-i/"><img src="/uploads/ca8cb45aa79780b0a1c9bb27b9f557dc.jpg" alt="Кондиционера инструкция пользователя пульт дистанционного управления (сплит-системы) Инструкции для дистанционного пульта управления" loading=lazy></a> <br> Приветствую всех посетителей нашего портала! Сегодня я расскажу вам, как включить кондиционер на тепло и при этом на 100% быть уверенным, что вы всё настроили правильно! Очень часто переключение... </p> </div> </div> </div> <div id="text_icl-3" class="widget widget_text_icl"> <div class="textwidget"> <p><a href="" rel="alternate" type="application/rss+xml"><img src="//feedburner.google.com/fb/images/pub/feed-icon32x32.png" alt="" style="vertical-align:middle;border:0"/ loading=lazy></a> <a href="" rel="alternate" type="application/rss+xml">Подписаться на RSS</a></p> </div> </div> <div id="text_icl-7" class="widget widget_text_icl"> <div class="textwidget"> <div class="center"></div> </div> </div> <div id="text_icl-8" class="widget widget_text_icl"> <div class="textwidget"> </div> </div> <div id="text_icl-13" class="widget widget_text_icl"> </div> <div id="text_icl-14" class="widget widget_text_icl"> </div> </aside> <aside id="sidebar-2" class="sidebar"> </aside> </div> </section> <footer id="footer"> <div class="center">Разрешается копирование материалов сайта с обязательной ссылкой на <a href="/">ksound36.ru</a>  </div> </footer> </div> <script type='text/javascript'> /* <![CDATA[ */ var scriptParams = { "google_search_engine_id":"007248068859778613277:ewdxetioq-u"} ; /* ]]> */ </script> <script type='text/javascript' src='https://ksound36.ru/wp-content/plugins/wp-google-search/assets/js/google_cse_v2.js?ver=1'></script> <script type='text/javascript' src='/wp-includes/js/comment-reply.min.js?ver=4.9'></script> <script type='text/javascript' src='/wp-includes/js/wp-embed.min.js?ver=4.9'></script> <script> window.__bp_session_timeout = '900'; window.__bp_session_freezing = 0; !function() { window.bizpanda || (window.bizpanda = { }), window.bizpanda.bp_can_store_localy = function() { return !1 } , window.bizpanda.bp_ut_get_cookie = function(e) { for( var n = e + "=", i = document.cookie.split(";"), o = 0; o < i.length; o++ ) { for( var t = i[o]; " " == t.charAt(0); ) { t = t.substring(1); } if( 0 == t.indexOf(n) ) { return decodeURIComponent(t.substring(n.length, t.length)) } } return !1 } , window.bizpanda.bp_ut_set_cookie = function(e, n, i) { var o = new Date; o.setTime(o.getTime() + 24 * i * 60 * 60 * 1e3); var t = "expires=" + o.toUTCString(); document.cookie = e + "=" + encodeURIComponent(n) + "; " + t + "; path=/" } , window.bizpanda.bp_ut_get_obj = function(e) { var n = null; return (n = window.bizpanda.bp_can_store_localy() ? window.localStorage.getItem("bp_ut_session") : window.bizpanda.bp_ut_get_cookie("bp_ut_session")) ? (n = JSON.parse(n), n.started + 1e3 * e < (new Date).getTime() && (n = null), n) : !1 } , window.bizpanda.bp_ut_set_obj = function(e) { e.started && window.__bp_session_freezing || (e.started = (new Date).getTime()); var e = JSON.stringify(e); window.bizpanda.bp_can_store_localy() ? window.localStorage.setItem("bp_ut_session", e) : window.bizpanda.bp_ut_set_cookie("bp_ut_session", e, 5e3) } , window.bizpanda.bp_ut_count_pageview = function() { var e = window.bizpanda.bp_ut_get_obj(window.__bp_session_timeout); e || (e = { }), e.pageviews || (e.pageviews = 0), 0 === e.pageviews && (e.referrer = document.referrer, e.landingPage = window.location.href, e.pageviews = 0), e.pageviews++, window.bizpanda.bp_ut_set_obj(e) } , window.bizpanda.bp_ut_count_locker_pageview = function() { var e = window.bizpanda.bp_ut_get_obj(window.__bp_timeout); e || (e = { }), e.lockerPageviews || (e.lockerPageviews = 0), e.lockerPageviews++, window.bizpanda.bp_ut_set_obj(e) } , window.bizpanda.bp_ut_count_pageview() } (); </script> </body> </html>