Пользовательские типы записей и template_redirect
У меня есть два пользовательских типа записей (например, post_type_1 и post_type_2), которые я хочу перенаправить на независимые шаблоны (single-post_type_1.php и single-post_type_2.php) для управления их отображением. Я не хочу размещать шаблоны отображения в папке темы, так как хочу, чтобы они были автономными в своих соответствующих папках плагинов.
Как можно сделать так, чтобы каждый из них регистрировал хук template_redirect, не влияя на другой? Или следует использовать другой подход?
В настоящее время я делаю это в Плагине 1:
add_action( 'template_redirect', 'template_redirect_1' );
function template_redirect_1() {
global $wp_query;
global $wp;
if ( $wp_query->query_vars['post_type'] === 'post_type_1' ) {
if ( have_posts() )
{
include( PATH_TO_PLUGIN_1 . '/views/single-post_type_1.php' );
die();
}
else
{
$wp_query->is_404 = true;
}
}
}
И это в Плагине 2:
add_action( 'template_redirect', 'template_redirect_2' );
function template_redirect_2() {
global $wp_query;
global $wp;
if ( $wp_query->query_vars['post_type'] === 'post_type_2' ) {
if ( have_posts() )
{
include( PATH_TO_PLUGIN_2 . '/views/single-post_type_2.php' );
die();
}
else
{
$wp_query->is_404 = true;
}
}
}
Как только я регистрирую хук template_redirect плагина 2, плагин 1 перестает работать.
Что я упускаю?
Какой лучший способ это сделать?

Для этого следует использовать фильтр template_include:
add_filter('template_include', 'wpse_44239_template_include', 1, 1);
function wpse_44239_template_include($template){
global $wp_query;
// Здесь выполните обработку и определите $template как полный путь к альтернативному шаблону.
return $template;
}
template_redirect
— это действие, вызываемое непосредственно перед отправкой заголовков для вывода отрендеренного шаблона. Это удобный хук для выполнения 301 редиректов и т.д., но его не следует использовать для подключения других путей к шаблонам, так как WordPress делает это автоматически с помощью фильтра 'template_include'.
Хуки template_include
и single_template
работают ТОЛЬКО с путём к шаблону, используемому для рендеринга контента. Это правильное место для изменения пути к шаблону.
Обновление из комментария от @ChipBennett:
single_template
был удалён начиная с версии 3.4. Используйте вместо него {posttype}_template.

Итак, это работает, но оказывается, template_redirect и single_template тоже работают. Настоящая проблема, как я выяснил, заключалась в том, что у меня есть пользовательская функция сортировки столбцов в админке, которая подключается к фильтру 'request', и я не ограничивал изменение переменной $vars только для определённого типа записи. Но я рад, что узнал о хуке template_include. Всё ещё не уверен, в чём разница между template_redirect, template_include и single_template.

Так что насчёт single_template? Эта ссылка (http://codex.wordpress.org/Plugin_API/Filter_Reference/single_template) говорит, что его можно использовать для изменения шаблона для записи или страницы, когда вызывается одиночный шаблон. Это именно то, что я пытаюсь сделать. В любом случае, использование либо фильтра template_include, либо single_template работает и, кажется, достигает того же самого.

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

Круто, спасибо за помощь. Получается, single_template более специфичен (уже по области действия), чем template_include?

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

Моя ошибка, думал, что уже сделал это. Только что отметил как правильный ответ. :)

К вашему сведению, single_template
был удален начиная с версии 3.4. Вместо этого используйте {posttype}_template
.
