В данной статье я расскажу как создать плагин для пользовательских типов сообщений в ВордПресс с поддержкой категорий, которые не перекликаются с категориями для стандартных постов.
Создание плагина
Существуют определенные стандарты создания плагинов для ВордПресс, которых нужно придерживаться (подробнее можно прочесть в «Кодексе ВордПресс»). Ниже я приведу некоторые важные аспекты, которые нужно учитывать при создании своего собственного плагина.
Выбор названия для плагина
Будет правильно, если в названии плагина будет отображена оснавная задача данного плагина. Поэтому, плагин для данного примера назову – «My portfolio».
Файловая структура плагина
Как правило, плагины размещаются в соответствующем разделе wp-content/plugins/
. Плагин может состоять как из одного файла, находящегося непосредственно в разделе plugins
, так и из нескольких объединенных в одну папку. Целесообразно назвать файл/папку плагина в соответствии с названием самого плагина. Естественно, различные плагины в рамках одного сайта не могут иметь идентичное название файла/папки.
В случае, если плагин состоит всего из одного файла, тов самом начале файла содержится метаинформация о плагине для ВордПресс. Ниже я приведу типичный пример метаинформации для данного плагина.
<?php /* Plugin Name: My portfolio Plugin URI: http://www.my-portfolio.com Version: 1.0 Description: Declares custom post type "project" for Potfolio. Author: IMAKER IT Author URI: http://www.my-portfolio.com License: My free license */
Этой информации достаточно для идентификации плагина в системе.
Программная часть плагина
Итак, плагин будет состоять всего из одного файла. Соответственно и назову файл my-portfolio.php
. Путь к плагину теперь выглядит так: /wp-content/plugins/my-portfolio.php
. Если теперь перейти в раздел «Плагины», то там отображается созданный плагин «My portfolio» и его уже можно активировать. После активации плагина на сайте ничего не произойдет, так как плагин еще не имеет програмной части.

Раздел «Плагины», плагин: «My portfolio».
Как видно из описания, данный плагин декларирует пользовательский тип сообщений project
. Сообщения дынного типа должны поддерживать категории и состоять из наименования, титульного изображения и контента. Соответственно, это все нужно указать в программой части плагина.
Сначала, регистрируется тип сообщений project
с соответствующими настройками. Подробнее останавливаться на настройках, думаю, нету надобности. Там и так все интуитивно понятно.
/* Registered a custom post type with slug "project" */ function imaker_projects() { // Set UI labels for Custom Post Type $labels = array( 'name' => _x('Portfolio', 'post type general name'), 'singular_name' => _x('Project', 'post type singular name'), 'add_new' => _x('Add New', 'project'), 'add_new_item' => __('Add new project'), 'edit_item' => __('Edit project'), 'new_item' => __('New project'), 'all_items' => __('All projects'), 'view_item' => __('View project'), 'search_items' => __('Search project'), 'not_found' => __('No projects found'), 'not_found_in_trash' => __('No projects found in Trash'), 'parent_item_colon' => __('Parent projects'), 'menu_name' => __('Portfolio') ); // Set other options for Custom Post Type $args = array( 'labels' => $labels, 'hierarchical' => true, 'description' => 'Project Posts', 'supports' => array( 'title', 'editor', 'thumbnail' ), 'taxonomies' => array( 'project_category', 'post_tag' ), 'show_ui' => true, 'show_in_menu' => true, 'menu_position' => null, 'menu_icon' => 'dashicons-list-view', 'show_in_nav_menus' => true, 'publicly_queryable' => true, 'exclude_from_search' => false, 'query_var' => true, 'can_export' => true, 'rewrite' => array('slug'=>'portfolio/%project_category%', 'with_front'=>FALSE), 'public' => true, 'has_archive' => 'projects', 'capability_type' => 'post', ); register_post_type('project',$args); } add_action( 'init', 'imaker_projects' );
Следующим шагом добавляется поддержка категорий. Но вместо обычной таксономии category
регистрируется новая project_category
. Это позволит избежать отображения категорий для проектов в общем списке категорий для сообщений. Для большей наглядности, я добавил комментарии к некоторым параметрам.
/* Set taxonomy for custom post type */ function my_taxonomy() { register_taxonomy( 'project_category', //The name of the taxonomy 'project', //Post type name array( 'hierarchical' => true, 'label' => 'Categories', //Display name 'query_var' => true, 'rewrite' => array( 'slug' => 'category', //The base slug 'with_front' => false //Don't display the category base before ), 'show_admin_column' => true, //Display column in Backend ) ); } add_action( 'init', 'my_taxonomy');
Что бы категории отображались в URL сообщения применяется фильтр post_type_link
с соответствующим изменением в URL.
/* Changed permalink */ function filter_post_type_link($link, $post) { if ($post->post_type != 'project') return $link; if ($cats = get_the_terms($post->ID, 'project_category')) $link = str_replace('%project_category%', array_pop($cats)->slug, $link); return $link; } add_filter('post_type_link', 'filter_post_type_link', 10, 2);
В случае, если не указана категория для сообщения, то сообщение должно перемещаться в категорию other
. За это ответственен следующий блок.
/* Set default category, if post has not category */ function default_taxonomy_term( $post_id, $post ) { if ( 'publish' === $post->post_status ) { $defaults = array( 'project_category' => array('other'), ); $taxonomies = get_object_taxonomies( $post->post_type ); foreach ( (array) $taxonomies as $taxonomy ) { $terms = wp_get_post_terms( $post_id, $taxonomy ); if ( empty( $terms ) && array_key_exists( $taxonomy, $defaults ) ) { wp_set_object_terms( $post_id, $defaults[$taxonomy], $taxonomy ); } } } } add_action( 'save_post', 'default_taxonomy_term', 100, 2 );
В общем, это вся программная часть данного плагина. Ниже я приведу весь код целиком, который нужно разместить в файле my-portfolio.php
.
_x('Portfolio', 'post type general name'), 'singular_name' => _x('Project', 'post type singular name'), 'add_new' => _x('Add New', 'project'), 'add_new_item' => __('Add new project'), 'edit_item' => __('Edit project'), 'new_item' => __('New project'), 'all_items' => __('All projects'), 'view_item' => __('View project'), 'search_items' => __('Search project'), 'not_found' => __('No projects found'), 'not_found_in_trash' => __('No projects found in Trash'), 'parent_item_colon' => __('Parent projects'), 'menu_name' => __('Portfolio') ); // Set other options for Custom Post Type $args = array( 'labels' => $labels, 'hierarchical' => true, 'description' => 'Project Posts', 'supports' => array( 'title', 'editor', 'thumbnail' ), 'taxonomies' => array( 'project_category', 'post_tag' ), 'show_ui' => true, 'show_in_menu' => true, 'menu_position' => null, 'menu_icon' => 'dashicons-list-view', 'show_in_nav_menus' => true, 'publicly_queryable' => true, 'exclude_from_search' => false, 'query_var' => true, 'can_export' => true, 'rewrite' => array('slug'=>'portfolio/%project_category%', 'with_front'=>FALSE), 'public' => true, 'has_archive' => 'projects', 'capability_type' => 'post', ); register_post_type('project',$args); } add_action( 'init', 'imaker_projects' ); /* Set taxonomy for custom post type */ function my_taxonomy() { register_taxonomy( 'project_category', //The name of the taxonomy 'project', //Post type name array( 'hierarchical' => true, 'label' => 'Categories', //Display name 'query_var' => true, 'rewrite' => array( 'slug' => 'category', //The base slug 'with_front' => false //Don't display the category base before ), 'show_admin_column' => true, //Display column in Backend ) ); } add_action( 'init', 'my_taxonomy'); /* Changed permalink */ function filter_post_type_link($link, $post) { if ($post->post_type != 'project') return $link; if ($cats = get_the_terms($post->ID, 'project_category')) $link = str_replace('%project_category%', array_pop($cats)->slug, $link); return $link; } add_filter('post_type_link', 'filter_post_type_link', 10, 2); /* Set default category, if post has not category */ function default_taxonomy_term( $post_id, $post ) { if ( 'publish' === $post->post_status ) { $defaults = array( 'project_category' => array('other'), ); $taxonomies = get_object_taxonomies( $post->post_type ); foreach ( (array) $taxonomies as $taxonomy ) { $terms = wp_get_post_terms( $post_id, $taxonomy ); if ( empty( $terms ) && array_key_exists( $taxonomy, $defaults ) ) { wp_set_object_terms( $post_id, $defaults[$taxonomy], $taxonomy ); } } } } add_action( 'save_post', 'default_taxonomy_term', 100, 2 );
Также, данный плагин доступен для скачивания: Plug-in "Portfolio" .