Кастомный шаблон одиночной записи по категории
Я пытаюсь разобраться во всех тонкостях терминологии WordPress, так что прошу прощения за возможные неточности.
Я настраиваю полноценный сайт на WordPress с использованием кастомного шаблона, основанного на теме TwentyTen.
Я стараюсь максимально использовать стандартный тип записей "post", а страницы с "списками" делать просто как страницы категорий.
Одна из категорий называется "work" (работы)
Мне удалось кастомизировать эти страницы, создав файлы category-work.php и loop-work.php. Но как создать кастомный шаблон для одиночной записи определенной категории?
Похоже, что создание файла single-work.php будет искать кастомный тип записи "work". Есть ли способ создать модифицированную копию single.php, которая будет активироваться по категории или слагу категории?
Сделайте ваш single.php следующим:
<?php
$post = $wp_query->post;
if ( in_category( 'work' ) ) {
include( TEMPLATEPATH.'/single-work-cat.php' );
}
else {
include( TEMPLATEPATH.'/single-generic.php' );
}
?>
где single-work-cat.php будет шаблоном для записей категории "work", а single-generic.php — шаблоном для всех остальных случаев. Для дополнительных категорий просто добавьте больше условий elseif и создайте новые шаблоны single.

Я понимаю, что это старый вопрос, но если кто-то найдет его при поиске по той же теме, имейте в виду, что вам не следует использовать операторы include в ваших темах WordPress. Всегда используйте get_template_part() или locate_template() вместо этого.
(см. http://make.wordpress.org/themes/guidelines/guidelines-theme-check/)
Следующий код использует фильтры WordPress для выполнения задачи и будет автоматически искать шаблоны для любых категорий:
/**
* Замените "themeslug" на уникальный слаг вашей темы
*
* @see http://codex.wordpress.org/Theme_Review#Guidelines
*/
add_filter( 'single_template', 'themeslug_single_template' );
/**
* Добавляет учет категорий к шаблонам, которые WordPress использует для одиночных записей
*
* @global obj $post Объект записи WordPress по умолчанию. Используется для получения ID через get_post_type()
* @param string $template Текущий найденный шаблон из get_single_template()
* @return string Результат новой функции locate_template()
*/
function themeslug_single_template( $template ) {
global $post;
$categories = get_the_category();
if ( ! $categories )
return $template; // нет необходимости продолжать, если нет категорий
$post_type = get_post_type( $post->ID );
$templates = array();
foreach ( $categories as $category ) {
$templates[] = "single-{$post_type}-{$category->slug}.php";
$templates[] = "single-{$post_type}-{$category->term_id}.php";
}
// не забываем шаблоны по умолчанию
$templates[] = "single-{$post_type}.php";
$templates[] = 'single.php';
$templates[] = 'index.php';
/**
* Позволяем WordPress самостоятельно определить, существуют ли шаблоны или нет.
*
* @see http://codex.wordpress.org/Function_Reference/locate_template
*/
return locate_template( $templates );
}
В коде есть пара слабых мест. Во-первых, это означает, что WordPress выполняет locate_template() дважды для одиночных записей (один раз до выполнения этой функции и один раз во время). Во-вторых, я не думаю, что есть чистый способ определить приоритет, по каким категориям искать в первую очередь. Это означает, что если ваша запись находится в нескольких категориях, у которых есть уникальные шаблоны для одиночных записей, вы не сможете выбрать, какой шаблон будет использован.
