В данной статье я расскажу как создать плагин для пользовательских типов сообщений в ВордПресс с поддержкой категорий, которые не перекликаются с категориями для стандартных постов.
Создание плагина
Существуют определенные стандарты создания плагинов для ВордПресс, которых нужно придерживаться (подробнее можно прочесть в «Кодексе ВордПресс»). Ниже я приведу некоторые важные аспекты, которые нужно учитывать при создании своего собственного плагина.
Выбор названия для плагина
Будет правильно, если в названии плагина будет отображена оснавная задача данного плагина. Поэтому, плагин для данного примера назову – «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» и его уже можно активировать. После активации плагина на сайте ничего не произойдет, так как плагин еще не имеет програмной части.
Как видно из описания, данный плагин декларирует пользовательский тип сообщений 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".