Пользовательские типы записей и template_redirect

2 мар. 2012 г., 18:32:12
Просмотры: 25.8K
Голосов: 12

У меня есть два пользовательских типа записей (например, 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 перестает работать.

Что я упускаю?

Какой лучший способ это сделать?

0
Все ответы на вопрос 1
12
16

Для этого следует использовать фильтр 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.

2 мар. 2012 г. 18:58:18
Комментарии

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

anderly anderly
2 мар. 2012 г. 19:24:25

@anderly Я обновил свой ответ. Надеюсь, это поможет.

Brian Fegter Brian Fegter
2 мар. 2012 г. 19:36:34

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

anderly anderly
2 мар. 2012 г. 19:39:24

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

Brian Fegter Brian Fegter
2 мар. 2012 г. 19:42:14

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

anderly anderly
2 мар. 2012 г. 19:53:17

Это верно. :)

Brian Fegter Brian Fegter
2 мар. 2012 г. 20:22:59

Это ответило на ваш вопрос?

Brian Fegter Brian Fegter
2 мар. 2012 г. 21:27:11

Очень круто... Я не знал про template_include

helgatheviking helgatheviking
2 мар. 2012 г. 22:39:22

Да, вы ответили на него (+1). Ещё раз спасибо!

anderly anderly
3 мар. 2012 г. 06:42:30

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

Brian Fegter Brian Fegter
3 мар. 2012 г. 06:43:23

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

anderly anderly
3 мар. 2012 г. 21:55:42

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

Chip Bennett Chip Bennett
2 янв. 2013 г. 20:43:01
Показать остальные 7 комментариев