1. Code
  2. WordPress
  3. Plugin Development

Руководство по пользовательским типам записей: создание, выведение и дополнительные поля.

WordPress подразумевает кастомизацию/настройку. Он был создан таким образом, чтобы можно было настроить абсолютно каждый раздел. В этом уроке мы рассмотрим пользовательские типы записей, одну из наиболее значительных и замечательных возможностей WordPress, с помощью которой WordPress смог достичь новых высот.
Scroll to top
This post is part of a series called A Guide to WordPress Custom Post Types.
WordPress Custom Post Types: Taxonomies, Admin Columns & Filters

Russian (Pусский) translation by Ola Matona (you can also view the original English article)

WordPress подразумевает кастомизацию/настройку.  Он был создан таким образом, чтобы можно было настроить абсолютно каждый раздел. В этом уроке мы рассмотрим пользовательские типы записей, одну из наиболее значительных и замечательных возможностей WordPress, с помощью которой WordPress смог достичь новых высот.


Что такое пользовательские типы записей?

Предположим, вы хотите чтобы в вашем блоге был отдельный раздел для кинообзоров. Используя пользовательские типы записей вы сможете создать новый тип, к примеру, Записи и Страницы, который будет содержать другой вид данных.  У него будет свое меню администратора, специальные страницы для редактирования, свои таксономии и многие другие инструменты, которые нужны для полноценной работы с публикациями.

Пользовательские типы записей  - это дополнительный набор настроек администратора, который существует наряду с настройками для таких типов записей по умолчанию, как записи, страницы, прикрепленные файлы, и т.д. Пользовательские типы записей могут хранить любой тип данных. У них есть отдельный редактор, загрузчик медиафайлов, и они используют уже существующую структуру таблиц WordPress, что упрощает управление данными. Основное преимущество пользовательских типов записей, созданных при помощи WordPress API, состоит в их совместимости с уже существующими темами и шаблонами. Также, благодаря использованию постоянных ссылок, пользовательские типы постов хорошо взаимодействуют и с поисковыми системами.


Зачем использовать пользовательские типы записей?

Пользовательские типы записей помогают хранить разные типы записей в разных местах. Это помогает отделить обычные посты от других.   Вот и все.


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

Мы создадим плагин для пользовательского типа записи, который будет выводить лучшие кинообзоры. Начнем. 

Шаг 1. Создайте папку для WordPress плагина 

Откройте папку с WordPress плагинами  и создайте новую папку Movie-Reviews.

Шаг 2: Создайте PHP файл

В созданной папке создайте PHP файл Movie-Reviews.php

Шаг 3: Добавьте шапку

Откройте созданный файл и вставьте код для шапки сверху.

1
2
<?php
3
/*

4
Plugin Name: Movie Reviews

5
Plugin URI: https://wp.tutsplus.com/

6
Description: Declares a plugin that will create a custom post type displaying movie reviews.

7
Version: 1.0

8
Author: Soumitra Chakraborty

9
Author URI: http://wp.tutsplus.com/

10
License: GPLv2

11
*/
12
?>

Шаг 4: Зарегистрируйте пользовательскую функцию

Перед тегом закрытия PHP команды  введите следующую строку кода create_movie_review. При инициализации она будет запускать соответствующую пользовательскую функцию каждый раз при генерации страницы.

1
2
add_action( 'init', 'create_movie_review' );

Шаг 5: Выполнение функции

Код для выполнения функции create_movie_review.

1
2
function create_movie_review() {
3
  register_post_type( 'movie_reviews',
4
		array(
5
			'labels' => array(
6
				'name' => 'Movie Reviews',
7
				'singular_name' => 'Movie Review',
8
				'add_new' => 'Add New',
9
				'add_new_item' => 'Add New Movie Review',
10
				'edit' => 'Edit',
11
				'edit_item' => 'Edit Movie Review',
12
				'new_item' => 'New Movie Review',
13
				'view' => 'View',
14
				'view_item' => 'View Movie Review',
15
				'search_items' => 'Search Movie Reviews',
16
				'not_found' => 'No Movie Reviews found',
17
				'not_found_in_trash' => 'No Movie Reviews found in Trash',
18
				'parent' => 'Parent Movie Review'
19
			),
20
21
			'public' => true,
22
			'menu_position' => 15,
23
			'supports' => array( 'title', 'editor', 'comments', 'thumbnail', 'custom-fields' ),
24
			'taxonomies' => array( '' ),
25
			'menu_icon' => plugins_url( 'images/image.png', __FILE__ ),
26
			'has_archive' => true
27
		)
28
	);
29
}

Функция register_post_type сделает бОльшую часть работы в нашем случае. Сразу как она вызовется, она подготовит необходимую для нового пользовательского поста конфигурацию WordPress, включая дополнительные разделы для администратора. В функцию передается два типа аргументов: уникальное имя (name)  пользовательского типа поста и массив с его свойствами. Это другой массив с другими метками, которые указывают какие текстовые  строки будут показываться в разных частях пользовательского типа записи, например: 'name' выводит название пользовательского типа записи на панели управления, 'edit' и 'view' выводят кнопки Edit и View. Думаю, все остальные аргументы говорят сами за себя.

Так, в следующих аргументах:

  • 'public' => true задает видимость пользовательского типа записи как на панели управления администратора, так и в клиентской части.
  • 'menu_position' => 15 задает, где в меню, будет находиться пользовательский тип записи.
  • 'supports' => array( 'title', 'editor', 'comments', 'thumbnail', 'custom-fields' ) задает те атрибуты пользовательского типа записи, которые будут отображаться.
  • 'taxonomies' => array( '' ) создает пользовательские таксономии. В данном случае они не определены.
  • 'menu_icon' => plugins_url( 'images/image.png', __FILE__ )  показывает иконку в меню администратора.
  • 'has_archive' => true разрешает архивирование пользовательских типов записей.

Вы можете узнать больше о других аргументах, используемых в пользовательских типах записей на странице WordPress Codex register_post_type

Шаг 6: Иконка для пользовательского типа записей

Сохраните иконку размером 16x16 пикселей в вашей папке с плагином.  Это нужно для того, чтобы на панели управления у пользовательского типа записи была иконка.

Шаг 7: Активируйте плагин

Активируйте плагин, и вуаля, у вас есть пользовательский тип записи с возможностью редактировать текст, настройками для публикации, изображений, комментариев, а также редактор пользовательских полей.

Шаг 8: Добавляем новую запись

Выберите Добавить новую, чтобы открыть панель редактирования пользовательского типа записи. Добавьте название фильма, текст обзора, а также выберите миниатюру  изображения.

Шаг 9: Публикуем

Опубликуйте запись и нажмите View Movie Review, чтобы увидеть созданный кинообзор.


Создание дополнительных полей для пользовательских типов записей

Механизм дополнительных полей (метабоксов) использует встроенную в WordPress систему дополнительных полей. Это помогает добавлять поля, предназначенные исключительно для пользовательских типов записей, не используя в редакторе пользовательских полей по умолчанию.

Шаг 1: Регистрируем пользовательскую функцию

Откройте файл Movie-Reviews.php и добавьте следующий код перед тегом закрытия. Этот код регистрирует функцию, которая будет вызываться при посещении панели администратора WordPress.

1
2
add_action( 'admin_init', 'my_admin' );

Шаг 2: Выполняем пользовательскую функцию

Добавьте выполнение функции my_admin, которая регистрирует дополнительные поля и связывает их с пользовательским типом записи movie_reviews.

1
2
function my_admin() {
3
	add_meta_box( 'movie_review_meta_box',
4
		'Movie Review Details',
5
		'display_movie_review_meta_box',
6
		'movie_reviews', 'normal', 'high'
7
	);
8
}

В данном случае функция add_meta_box используется для добавления дополнительных полей к пользовательскому типу записей. Об атрибутах:

  • movie_review_meta_box необходимый атрибут для HTML id 
  • Movie Review Details текст, которые будет виден в заголовке дополнительного поля
  • display_movie_review_meta_box функция обратного вызова которая отображает содержимое дополнительных полей
  • movie_review имя пользовательского типа записи, где будут отображаться дополнительные поля
  • normal определяет где на странице будет показан блок редактирования
  • high определяет приоритет отображаемых полей

Шаг 3: Выполняем функцию display_movie_review_meta_box

1
2
<?php
3
function display_movie_review_meta_box( $movie_review ) {
4
	// Retrieve current name of the Director and Movie Rating based on review ID

5
	$movie_director = esc_html( get_post_meta( $movie_review->ID, 'movie_director', true ) );
6
	$movie_rating = intval( get_post_meta( $movie_review->ID, 'movie_rating', true ) );
7
	?>
8
	<table>
9
		<tr>
10
			<td style="width: 100%">Movie Director</td>
11
			<td><input type="text" size="80" name="movie_review_director_name" value="<?php echo $movie_director; ?>" /></td>
12
		</tr>
13
		<tr>
14
			<td style="width: 150px">Movie Rating</td>
15
			<td>
16
				<select style="width: 100px" name="movie_review_rating">
17
				<?php
18
				// Generate all items of drop-down list

19
				for ( $rating = 5; $rating >= 1; $rating -- ) {
20
				?>
21
					<option value="<?php echo $rating; ?>" <?php echo selected( $rating, $movie_rating ); ?>>
22
					<?php echo $rating; ?> stars <?php } ?>
23
				</select>
24
			</td>
25
		</tr>
26
	</table>
27
	<?php
28
}
29
?>

Этот код выводит содержимое дополнительных полей. Здесь используется объектная переменная, которая содержит информацию о каждом из показанных на панели редактирования кинообзоров. Используя этот объект мы получили ID записи и использовали его, чтобы сделать запрос в базу данных для получения имени режиссера и рейтинга, что в свою очередь выведется в полях на экране. При добавлении новой записи, функция get_post_meta возвратит пустую строку, и в итоге дополнительные поля будут пустыми.

Шаг 4: Регистрируем функцию сохранения записи

1
2
add_action( 'save_post', 'add_movie_review_fields', 10, 2 );

Эта функция вызывается при сохранении записи в базе данных.

Шаг 5: Выполняем функцию add_movie_review_fields

1
2
function add_movie_review_fields( $movie_review_id, $movie_review ) {
3
	// Check post type for movie reviews

4
	if ( $movie_review->post_type == 'movie_reviews' ) {
5
		// Store data in post meta table if present in post data

6
		if ( isset( $_POST['movie_review_director_name'] ) && $_POST['movie_review_director_name'] != '' ) {
7
			update_post_meta( $movie_review_id, 'movie_director', $_POST['movie_review_director_name'] );
8
		}
9
		if ( isset( $_POST['movie_review_rating'] ) && $_POST['movie_review_rating'] != '' ) {
10
			update_post_meta( $movie_review_id, 'movie_rating', $_POST['movie_review_rating'] );
11
		}
12
	}
13
}

Эта функция выполняется когда записи сохраняются или удаляются в панели администратора. В данном случае, тип получаемой записи проверяется, и, в том случае, если запись является пользовательской, вновь проводится проверка, есть ли у дополнительных полей какие-либо значения, и далее эти значения в этих полях сохраняются.

Шаг 6: Отключаем стандартные пользовательские поля

Создавая пользовательский тип записи, мы задали функцию create_movie_review. Удалите элемент custom-fields из массива supports, поскольку он нам больше не понадобиться. Теперь, если вы сохраните файл и откроете панель редактирования Movie Reviews, вы увидите два поля в дополнительных полях: Movie Author и Movie Rating. Вы можете добавить другие элементы тем же способом.


Создание шаблона для пользовательского типа записи

Правильным будет для каждого типа пользовательских записей использовать свои шаблоны для отображения данных. В нашем случае мы создадим шаблон, которые выводит все кинообзоры, которые были добавлены с использованием пользовательского типа записи Movie Review.

Шаг 1: Регистрируем функцию запуска шаблона

Откройте файл Movie-Reviews.php и перед тегом закрытия добавьте следующий код. Этот код регистрирует функцию, которая будет вызываться при посещении панели администратора WordPress.

1
2
add_filter( 'template_include', 'include_template_function', 1 );

Шаг 2: Выполняем функцию

1
2
function include_template_function( $template_path ) {
3
	if ( get_post_type() == 'movie_reviews' ) {
4
		if ( is_single() ) {
5
			// checks if the file exists in the theme first,

6
			// otherwise serve the file from the plugin

7
			if ( $theme_file = locate_template( array ( 'single-movie_reviews.php' ) ) ) {
8
				$template_path = $theme_file;
9
			} else {
10
				$template_path = plugin_dir_path( __FILE__ ) . '/single-movie_reviews.php';
11
			}
12
		}
13
	}
14
	return $template_path;
15
}

Здесь проверяется, есть ли в текущей папке темы шаблон типа single-(post-type-name).php. Если его там нет, то проверяется наличие шаблона в папке с плагином, куда мы и поместим наш шаблон, как часть плагина. Событийный обработчик (хук) template_include используется, чтобы изменить обычное выполнение программы и принудительно запустить специальный шаблон.

Шаг 3: Создаем файл шаблона Single Page

Сохранив ранее открытый файл с плагином, создайте другой файл с именем single-movie_reviews.php и вставьте в него следующий код.

1
2
<?php
3
 /*Template Name: New Template

4
 */
5
6
get_header(); ?>
7
<div id="primary">
8
	<div id="content" role="main">
9
	<?php
10
	$mypost = array( 'post_type' => 'movie_reviews', );
11
	$loop = new WP_Query( $mypost );
12
	?>
13
	<?php while ( $loop->have_posts() ) : $loop->the_post();?>
14
		<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
15
			<header class="entry-header">
16
17
				<!-- Display featured image in right-aligned floating div -->
18
				<div style="float: right; margin: 10px">
19
					<?php the_post_thumbnail( array( 100, 100 ) ); ?>
20
				</div>
21
22
				<!-- Display Title and Author Name -->
23
				<strong>Title: </strong><?php the_title(); ?><br />
24
				<strong>Director: </strong>
25
				<?php echo esc_html( get_post_meta( get_the_ID(), 'movie_director', true ) ); ?>
26
				<br />
27
28
				<!-- Display yellow stars based on rating -->
29
				<strong>Rating: </strong>
30
				<?php
31
				$nb_stars = intval( get_post_meta( get_the_ID(), 'movie_rating', true ) );
32
				for ( $star_counter = 1; $star_counter <= 5; $star_counter++ ) {
33
					if ( $star_counter <= $nb_stars ) {
34
						echo '<img src="' . plugins_url( 'Movie-Reviews/images/icon.png' ) . '" />';
35
					} else {
36
						echo '<img src="' . plugins_url( 'Movie-Reviews/images/grey.png' ). '" />';
37
					}
38
				}
39
				?>
40
			</header>
41
42
			<!-- Display movie review contents -->
43
			<div class="entry-content"><?php the_content(); ?></div>
44
		</article>
45
46
	<?php endwhile; ?>
47
	</div>
48
</div>
49
<?php wp_reset_query(); ?>
50
<?php get_footer(); ?>

В данном случае мы создали базовый шаблон страницы с использованием цикла. Функция query_posts получает элементы пользовательского типа записей и отображает их используя цикличность. Это конечно совсем простой цикл, вы можете менять его, как вам необходимо. Вы также можете использовать необходимые CSS стили, чтобы поменять внешнее оформление.

Внимание: необходимо создать новую страницу из панели управления используя созданный шаблон.

Шаг 4: Изображения

Сохраните два изображения с иконками для звездочек размером 32x32 пикселя в вашу папку с плагином. Назовите их соответственно icon.png и grey.png. Вот и все, теперь кинообзоры показываются на отдельной странице и отсортированы по дате.

В следующем уроке я опишу другие возможности пользовательских типов записей, такие как создание архивных страниц, собственных таксономий и колонок, и т.д. Не стесняйтесь поделиться своими предложениями.