Тег ‘wordpress’

По-русски про WordPress: Custom post types

Wednesday, August 4th, 2010

Итак, писали мы писали плагины для создания Custom Post Types’ов, а WordPress, тем временем, обновилась до версии 3.0 и удивила нас встроенной поддержкой такого функционала. Вся гадость в том, что мы уже практически всё реализовали с помощью плагинов (добавляя к постам custom fields). Ну что ж, и такое могло случиться.
Поддержка Custom Post Types когда-нибудь, да, должна была появиться. Этого требовали цели по расширяемости WordPress, да и в остальных CMS это было уже давно. Однако не суть что велосипед. Суть в реализации.

Что надо сделать чтобы добавить свой объект в WordPress

Под объектом я понимаю запись (post) или страницу (page). Так же есть объекты прикреплений (attachments) но обо всем по порядку:

1. Нужно добавить на действие (action) init свои дела, описывающие таксономию нового типа контента и свойства его самого.

1.1. Добавить фильтр на хук post_updated_messages в котором описать изменение служебных сообщений – типа запись сохранена и прочих. (optional)

2. Добавить функцию сохранения скрипта. Точнее повесить на действие save_post свои дела :) Уже второй раз так странно пишу – это я об add_action(‘save_post’, …)

3. Описать колонки при выводе списка постов в таблице

4. Описать содержимое колонок

5. Сделать дополнительные действия, коих бесконечное множество.

Вполне себе адекватно работает код со страницы Custom Post Types из кодекса, но есть несколько подводных камней, о которых там ни слова.

1. Насколько я понял, WordPress позволяет добавить всего два типа содержимого. Не в смысле количества а по поведению – это post и page. Зависит это от параметра hierarchy массива $args передаваемого функции register_post_type. Если hierarchy => true, то наш пост type будет page, поэтому необходимо будет использовать хуки для page, а не для post.

2. Так же как и типов контента, есть два типа таксономии – категории и теги. И функции register_taxonomy тоже передается свой массив $args, в котором также есть параметр hierarchy. Если true – категории, если false – теги.

Это собственно логично, но об этом я информации не нашел. Логично что страницы могут иметь вложенные страницы, а категории – вложенные категории (hierarchy=>true).

3. Также мы наткнулись на подводный камень (мягко сказано), когда решили сделать структуру URL такого вида:

http://[domain]/[language]/[post_type]/[category]/[post_name]

4. Для [language] мы решили использовать мультиблоговость (мультисайтовость) WordPress 3.0, но это совсем другая история и совсем не такая интересная :), а вот пермалинки постов должны были иметь именно такую структуру. Загвоздка в том, что все хотелось сделать по-человечески и с минимальным количеством телодвижений :) Ведь все гениальное, как известно, просто.

Чтобы сделать именно так, необходимо в параметр slug массива rewrite массива $args, который передается в register_post_type, написать “[post_type]/%category%”, что даст право на запрос нашей структуры URL, а чтобы пермалинки автоматически работали как надо (выводили категорию) необходимо отфильтровать post_type_link, где заменить, после нескольких проверок, в пермалинке %category% на категорию поста к которому относится данный пермалинк :)
Никаких $wp_rewrite нам трогать не надо, однако на него интересно посмотреть со стороны :)

5. Еще одной проблемой стали следующие запросы:

http://[domain]/[language]/[post_type]/[category]/

и

http://[domain]/[language]/[post_type]/

WordPress естественно не знал что по ним выводить и решал выводить 404. Но мы ему объяснили с помощью файла темы taxonomy-sometax.php (где sometax это taxonomy name добавленной нами ранее таксономии) и параметра slug массива rewrite массива $args функци register_taxonomy (он должен быть эквивалентным этому же параметру из $args для register_post_type и register_taxonomy должна вызываться до register_post_type). А во втором случае мы пришли к выводу что проще всего создать страницу (page) с таким URL и в ее шаблоне уже настроить вид, как нам надо.

Решили проблему незнания архитектурных возможностей WordPress 3.0 и теперь придется многие плагины переписывать и дописывать до этой структуры :) На то она и работа чтобы ее работать :)

PS Если будут желающие – выложу код для наглядности :) Но пока, мне думается, хватает кодекса.

PPS Мое мнение о реализации данного функционала в WordPress достаточно простое – эти абстракции работают, а чтобы их заставить работать необходимо всего 5-10 телодвижений. Самое главное – этот функционал очень мощный и если кто еще и считает WordPress блоговым движком, тот сильно ошибается. Необходимо просто понять философию, чтобы разубедиться в этом утверждении.

UPDATE

Выложил код с комментами по просьбам трудящихся :)

Anything else?