Создание библиотеки, или Custom post types | DAndreev.com

Создание библиотеки, или Custom post types

wp_codex

17 июня стартовал релиз долгожданного WordPress 3.0. Я, правда на него перешел за 3 месяца до этого, но это пока были бетта версии.

Одним из главных достоинств новой версии являются уже нашумевшие Custom Post Types. Ну или пользовательские типы постов по-русски. Чтобы интереснее было с этим разобраться я решил создать что-нибудь полезное.

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

Создание плагина

Ну в самом начале приступая к разработке в первую очередь нужно расписать по этапам, что нужно сделать для того чтобы получить желаемый результат. Задание не сложное, потому всё довольно просто.

  1. Создать плагин.
  2. Создать тип постов для хранения книг.
  3. Создать пользовательскую таксономию, для их классификации.
  4. Настройка темы для вывода библиотеки

Начнем с первого. Плагин создавать очень легко. Потому я не стану на этом подробно останавливаться. Просто создаете в папочке plugins (я надеюсь вы знаете где она находится) папку с именем “books”.

Создаем в ней файл books-plugin.php

И, собственно, чтобы WordPress считал этот файл плагином в самом его начале надо вставить комментарий с описание плагина.

/*
	Plugin Name: Books Plugin URI: http://dandreev.com
	Description: Plugin for wordpress to stroe books information.
	Author: Dmitriy Andreev Version: 1.0
	Author URI: http://dandreev.com
*/

После комментария можно уже начинать писать код самого плагина.

Создание нового типа постов

И так приступим к основной части плагина.

Создадим тип постов “book” для хранения данных о книге. Это первое и очень важное нововведение в WP 3.0. До этого приходилось разные типы постов различать по дополнительным мета полям. Это было не очень удобно, до появления в WP 3.0 Custom post types. Теперь же достаточно зарегистрировать новый тип постов и можно не только не заморачиваться с мета полями, но и для редактирования их в меню появится отдельный пункт для каждого типа.

Новый тип постов создается функцией register_post_type( $post_type, $args ),

где $post_type — название типа новых постов, $args — массив аргументов

Сначала я создал функцию ‘my_custom_init’, которая подключается посредством хука ‘init’. В момент инициализации самого вордпресса. В теле этой функции и будет происходить всё.

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

$labels = array(
	'name' => _x('Книги','post type general name'),
	'singular_name' =>_x('Книга','post type singular name'),
	'add_new' => _x('Добавить новую', 'book'),
	'add_new_item' => __('Добавить новую книгу'),
	'edit_item' => __('Редактировать'),
	'new_item' => __('Новая'),
	'view_item' => __('Просмотреть'),
	'search_items' => __('Поиск по кингам'),
	'not_found' => __('Ни одной книги не найдено'),
	'not_found_in_trash' => __('В корзине нет книг'),
	'parent_item_colon' => ''
);

Теперь я создал массив параметров для создания нужного типа постов для книг.

$args = array(
	'labels' => $labels,
	'public' => true,
	'publicy_queryable' => true,
	'show_ui' => true,
	'query_var' => true,
	'rewrite' => array('slug' => 'books'),
	'capability_type' => 'post',
	'hierarchical' => false,
	'menu_position' => null,
	'supports' => array('title','editor','author','thumbnail','comments')
);

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

register_post_type('book',$args);

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

Итак новый тип постов создали. Только их же надо как-то классфицировать. Я предлагаю сделать два типа таксономии.

Для тех кто еще не знает, таксономия — это тип классификации постов. Например есть две стандартные таксономии: категории и метки(тэги). Категории — это иерархическая таксономия, а метки — это свободная таксономия, она не имеет иерархии.

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

И тогда можно будет искать книги или по жанрам, или же выбрать все книги с определнным атором.

Вот код для создания таксономии жанров:

register_taxonomy(
	'janr',
	'book',
	array(
		'hierarchical' => true,
		'label' => "Жанры",
		'query_var' => true,
		'rewrite' => true
	)
);

А вот код для создания таксономии авторов

register_taxonomy(
	'authors',
	array('book','page'),
	array(
		'hierarchical' => false,
		'label' => "Авторы",
		'query_var' => true,
		'rewrite' => true
	)
);

После этого мы увидим в меню с книгами еще два пункта для редактирования авторов и жанров.

А при редактировании поста, справа появилось две панели для каждого типа таксономии.

Собственно здесь можно создание постов считать законченным, но можно добавить еще небольшой штрих. Я думаю для каждой книги лучше иметь не только описание, но еще и небольшую миниатюру. Добавим ее (размер можете указать такой, какой вам больше нравится):

if(function_exists('add_image_size')) { add_image_size('book-thumbnail', 100, 200); }

Для использования миниатюры, в время создания или редактирования книги, загружаем изображение миниатюры и жмем «Use as featured image». И справа должна появится иконка с этим изображением.

Установить изображение как миниатюру поста

Миниатюра в панели справа

А для того чтобы вывести эту миниатюру в теме нужно воспользоваться следующей функцией:

the_post_thumbnail('book-thumbnail');

Настройка темы для вывода библиотеки

С созданием пользовательского типа постов разобрались, но теперь встает другая задача, как вывести их.
С одним постом проблем не возникает. Для этого в иерархии шаблона нужно создать файл с именем:
single-posttype.php

Где posttype — это и есть название зарегистрированного нового типа постов. (single-book.php в моем случае).
А вот проблемы начинаются, когда нужно вывести список постов. Пермалинк на один такой пост в общем случае выглядит как:
http://domain.com/posttype/postname/

Отсюда монжно сделать вывод, что по ссылке http://domain.com/posttype/ можно получить список постов. К сожалению это не так. И при попытке ввести такую ссылку Вы получите любимую 404-ую.
Потому для вывода списка постов пришлось прибегнуть к небольшой хитрости.
В админке я создал страницу со слагом books. А в теме добавил файл page-books.php

В этой странице нужно написать всё тоже самое, что и в обычной странице index или category (это же зависит от вашего шаблона. Надо вывести список постов в цикле для данной страницы. На этом я подробно останавляиваться здесь не буду.)

За некоторым исключением. В начале страницы, создаем объект WP_Query и выбираем посты по новому типу.

$books = new WP_Query('post_type=book&post_status=publish');

А затем надо изменить в цикле вывода статей строчки

 

have_posts()

на

$books->have_posts()

И выражение

the_post();

Поменять на

$books->the_post();

Вот код вывода книг в виде списка постов

$books = new WP_Query('post_type=book&post_status=publish');
 
if($books->have_posts())
{
	while($books->have_posts())
	{
 
		$books->the_post();
		$cat_ID   = wp_get_post_categories(get_the_ID());
		$category = get_category($cat_ID[0]);
 
		// получаем таксономии
		$auth_list = get_the_term_list(get_the_ID, 'authors','',', ');
		$janr_list = get_the_term_list(get_the_ID, 'janr','',', ');
 
		?>
		<div id="title-block" <?php // echo'class="'.$category->slug.'"'; ?>">
			<h1><a href="<?php the_permalink();?>"><?php the_title(); ?></a></h1>
			<div class="post-meta">
				<?php the_time('j F Y') ?> |
				<?php echo $auth_list." | ".$janr_list; ?>
			</div>
		</div>
		<div id="text-content">
		<?php
		if(has_post_thumbnail())
		{
			echo '<a class="button book-post-thumbnail" href="'.get_permalink().'">';
			the_post_thumbnail('book-thumbnail');
			echo '';
		}
		the_content();
		?>
		<div class="clear-float"></div>
		</div>
	<?php
	}
}

И всё теперь по запросу
http://domain.com/books/

Будет выводиться страница со списком книг.

Заключение

Custom post types это одно из самых важных нововведений в последней версии WordPress.

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

Применив немного фантазии, можно придумать очень интересные структуры, используя Custom Post Types. Например, портфолио или интернет магазин, или же список недвижимости. Это всё уже на ваше усмотрение.

Retweet

Похожие статьи

Комментарии

Alex
18 Oct, 2010в22:32

Здравствуйте Дмитрий,
Идея данного плагина очень полезна и я не встречал в сети подобных не “тяжелых” плагинов. К сожалению из-за нулевого знания РНР, я так и не разобрался как все это дело соединить чтоб получился плагин.
Я уверен если вы выложите для скачивания, готовый плагин, желающих скачать будит хоть отбавляй =)

Дмитрий Андреев
19 Nov, 2010в21:17

Спасибо, Александр. Я постараюсь в ближайшее время выложить код плагина. На его базе на самом деле можно создать гораздо более полезные и нужные плагины, и улучшить гибкость WordPress, чем собственно я и занимаюсь последнее время.

glazsasha
22 Nov, 2010в15:17

делал все очень похоже только под flash игры. столкнулся с проблемой вывода пагинации, mostviewed и с рейтингом. Если бы вы к этому посту продолжение на эти темы написали было бы отлично или подсказали бы как это сделать?

Карина
26 Dec, 2010в23:24

У меня в таком виде код сработал, долго искала, что в каком порядке:

function post_type_books()
{
$labels = array(
‘name’ => _x(‘Книги’,'post type general name’),
‘singular_name’ =>_x(‘Книга’,'post type singular name’),
‘add_new’ => _x(‘Добавить новую’, ‘book’),
‘add_new_item’ => __(‘Добавить новую книгу’),
‘edit_item’ => __(‘Редактировать’),
‘new_item’ => __(‘Новая’),
‘view_item’ => __(‘Просмотреть’),
‘search_items’ => __(‘Поиск по кингам’),
‘not_found’ => __(‘Ни одной книги не найдено’),
‘not_found_in_trash’ => __(‘В корзине нет книг’),
‘parent_item_colon’ => ”
);
$args = array(
‘labels’ => $labels,
‘public’ => true,
‘publicy_queryable’ => true,
‘show_ui’ => true,
‘query_var’ => true,
// ‘rewrite’ => false,
‘rewrite’ => array(‘slug’ => ‘books’),
‘capability_type’ => ‘post’,
‘hierarchical’ => false,
‘menu_position’ => null,
‘supports’ => array(‘title’,'editor’,'author’,'thumbnail’,'comments’)
);
register_post_type(‘books’,$args);
register_taxonomy(
‘authors’,
array(‘books’,'page’),
array(
‘hierarchical’ => false,
‘label’ => “Авторы”,
‘query_var’ => true,
‘rewrite’ => true
)
);
register_taxonomy(
‘artists’,
array(‘books’,'page’),
array(
‘hierarchical’ => false,
‘label’ => “Художники”,
‘query_var’ => true,
‘rewrite’ => true
)
);
register_taxonomy(
‘publisher’,
array(‘books’,'page’),
array(
‘hierarchical’ => false,
‘label’ => “Издательство”,
‘query_var’ => true,
‘rewrite’ => true
)
);
register_taxonomy(
‘years’,
‘books’,
array(
‘hierarchical’ => true,
‘label’ => “Год издания”,
‘query_var’ => true,
‘rewrite’ => true
)
);
register_taxonomy(
‘files’,
‘books’,
array(
‘hierarchical’ => true,
‘label’ => “Тип файлов”,
‘query_var’ => true,
‘rewrite’ => true
)
);
}
add_action(‘init’, ‘post_type_books’);

размещала здесь: адрес сайта/wp-content/themes/название темы/functions.php

sts
30 Dec, 2010в19:20

Да, очень полезный пример. Кстати в сети так и не нашел нормально работающих плагинов электронной библиотеки. Полностью присоединяюсь к Alex, код плагина нужен.
От себя хочу добавить, что данную “тему” нужно развивать, может быть, разбить на несколько уроков.
Спасибо за нужное дело.

Дмитрий Андреев
28 Jan, 2011в06:46

Добрый день, Карина.
Фал functions.php работает на том же уровне, что и плагины WordPress.
Потому можно либо создавать плагин, можно размещать в файле functions.php.
По мне лучше писать плагин, поскольку это не будет загромождать саму тему, а functions.php писать уже мелкие функции для работы с сайта.

А в чем собственно вопрос то был?

Михаил
17 Feb, 2011в09:56

Для всего этого очень понравились плагины more_types more_field/
У меня другая проблема подскажите плиз.
список записей выводится без проблем, но когда несколько страниц выходит 404 ошибка
т.е. не работают ссылки вида ../category/category-custom/page/2

Александр
06 Mar, 2011в16:44

Дмитрий, подскажите, в чем может быть дело. Делаю все по Вашей схеме: комментарий плагина – массив текстовых названий меню и кнопок – массив параметров для создания нужного типа постов для книг. Далее нужно вставлять строку “”register_post_type(‘book’,$args);”",после чего в меню должен появиться раздел “книги”, но здесь начинаются непонятки. Если эту строку не ставить – то плагин активируется(без раздела “книги” в меню, что устроить не может :) ), а с ней – выдает ошибку:”
Fatal error: Call to a member function add_rewrite_tag() on a non-object in /home2/tulenev8/public_html/wp-includes/post.php on line 872″ В чем может быть причина? Заранее спасибо!

Дмитрий Андреев
07 Apr, 2011в05:44

Михаил, добрый день.
Ну так сложно сказать в чем может быть проблема.
Есть пример выложенный в сети?
И как Вы объявляли “category” и “category custom” это пользовательская таксономия?
Возможно вы не задали там параметр rewrite.

Дмитрий Андреев
07 Apr, 2011в05:57

Александр, добрый день.
Я, кажется тоже сталкивался с такой проблемой. Если не ошибаюсь, то дело в том, что файл плагина подключается до объявления объекта “$wp_rewrite”.
Я её решил, так: объявление нового типа постов занес в функцию register_books_type(), а затем добавил эту функцию в через хак.
Вот только не помню точно какой wp_loaded или init.
вот так add_action(‘wp_loaded’,'register_books_type’);

жорж
14 Sep, 2011в17:31

> Отсюда монжно сделать вывод, что по ссылке http://domain.com/posttype/ можно получить список постов. К сожалению это не так. И при попытке ввести такую ссылку Вы получите любимую 404-ую.

на самом деле проблема решается очень просто – надо создать файл archive-posttype.php
кстати сам не сразу нашел

Дмитрий Андреев
15 Sep, 2011в10:42

Да, я тоже долго думал как они вообще должны выводиться, и потом просто сделал привычным путем, через страницу и WP_Query
Этот способ я теперь тоже учту на будущее.

asha
03 Feb, 2012в07:11

Помогите, пожалуйста!
У меня не работает с Custom Post Types, следующий код:

Дмитрий Андреев
03 Feb, 2012в07:22

Добрый день, я бы помог, но к сожалению Ваш код не виден.

asha
03 Feb, 2012в14:07
asha
03 Feb, 2012в14:07

Форма комментариев его «съела»))) Надеюсь в этот раз будет виден.

Дмитрий
18 May, 2012в15:04

Можно ли первый вариан
$books = new WP_Query(‘post_type=books&post_status=publish’);

if($books->have_posts())
{
while($books->have_posts())
{
}
}

записать так:

есть ли разница?

Юрий
02 May, 2013в10:31

Скажите, а можно сделать как-то, чтобы плагин подцепил существующую базу. Просто есть сайт, на котором пытаюсь реализовать библиотеку фантастики, и там около шестисот постов.

Дмитрий Андреев
14 May, 2013в12:29

Ну вообще все можно, зависит от того как там все реализовано, если сделано как раз через Custom Posts то будет просто, если нет надо будет самому писать запросы к базе, только до этого надо изучить схему базы.

Оставить комментарий