Как установить пользовательский тип записи в качестве статической главной страницы?


Я пишу свою пользовательскую тему с нуля, и у меня есть пользовательский тип сообщения "my_frontpage", и я хочу объявить одно из его сообщений как первую страницу. Я хочу сделать это через администратора, поэтому просто добавьте мой cpt на Главную страницу в поле выбора Внешний вид>> Настройка>>Статическая главная страница.

Этот вопрос довольно часто обсуждался в Интернете. Тем не менее, я не смог найти инструкции, которые всесторонне объясняли бы все шаги для достижения эта цель.

Пока я понимаю, что мне нужно использовать какой-то крючок, чтобы расширить выбор доступных "страниц" на первой странице с публикациями из моего cpt. Но какой крючок использовать? Я бы даже не знал, нужно ли мне использовать действие или крючок фильтра? Итак, не мог бы кто-нибудь, пожалуйста, помочь мне разобраться в этом вопросе с точки зрения непрофессионалов?

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

Author: Community, 2016-01-21

3 answers

У меня было время рассмотреть вашу проблему и options-reading.php страница, которая является шаблоном, используемым для отображения страницы настроек чтения в бэкэнде.

К сожалению, нет фильтров для фильтрации или добавления пользовательских записей в виде липких записей в раскрывающемся списке, который можно выбрать. Есть два скрытых фильтра, которые мы можем использовать, это

  • wp_dropdown_pages внутри wp_dropdown_pages() function который используется выпадающим списком, в котором отображается список страниц который можно установить в качестве статической главной страницы

  • get_pages внутри get_pages() функция, которая отвечает за возврат страниц, используемых wp_dropdown_pages()

ИМХО, я думаю, что get_pages вот лучший вариант. Таким образом, мы позволим wp_dropdown_pages() позаботиться обо всей разметке. Однако здесь нам нужно быть осторожными, когда мы используем фильтр get_pages

  • Нам нужно будет убедиться, что мы нацелены только на административную область и, в частности, на чтение страница настроек в противном случае мы изменим любую функцию/страницу, которая использует функцию get_pages()

Вам нужно решить, нужны ли вам страницы для отображения с записями пользовательского типа или просто нужны пользовательские типы записей

Вы можете попробовать следующее:

add_filter( 'get_pages', function ( $pages, $args )
{
    // First make sure this is an admin page, if not, bail
    if ( !is_admin() )
        return $pages;

    // Make sure that we are on the reading settings page, if not, bail
    global $pagenow;
    if ( 'options-reading.php' !== $pagenow )
        return $pages;

    // Remove the filter to avoid infinite loop
    remove_filter( current_filter(), __FUNCTION__ );

    $args = [
        'post_type'      => 'my_frontpage',
        'posts_per_page' => -1
    ];
    // Get the post type posts with get_posts to allow non hierarchical post types
    $new_pages = get_posts( $args );    

    /**
     * You need to decide if you want to add custom post type posts to the pages
     * already in the dropdown, or just want the custom post type posts in
     * the dropdown. I will handle both, just remove what is not needed
     */
    // If we only need custom post types
    $pages = $new_pages;

    // If we need to add custom post type posts to the pages
    // $pages = array_merge( $new_pages, $pages );

    return $pages;
}, 10, 2 );

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

Чтобы избежать этого, вы можете использовать статический счетчик для подсчета количество раз, когда фильтр запускался, а затем отключался непосредственно перед применением фильтра к раскрывающемуся списку страниц блога. Фильтр будет выполняться в общей сложности 3 раза, так как get_pages() выполняется 3 раза:

  • Сначала нужно проверить, действительно ли у нас есть страницы для установки в качестве статической главной страницы.

  • Второй запуск будет внутри wp_dropdown_pages(), который используется в раскрывающемся списке статической главной страницы

  • Последний запуск будет внутри wp_dropdown_pages(), который используется страницей блога выпадающий список

Итак, основываясь на этом, мы можем попробовать

add_filter( 'get_pages', function ( $pages, $args )
{
    // First make sure this is an admin page, if not, bail
    if ( !is_admin() )
        return $pages;

    // Make sure that we are on the reading settings page, if not, bail
    global $pagenow;
    if ( 'options-reading.php' !== $pagenow )
        return $pages;

    // Remove the filter to avoid infinite loop
    remove_filter( current_filter(), __FUNCTION__ );

    // Setup our static counter
    static $counter = 0;

    // Bail on the third run all runs after this. The third run will be 2
    if ( 2 <= $counter )
        return $pages;

    // Update our counter
    $counter++;

    $args = [
        'post_type'      => 'my_frontpage',
        'posts_per_page' => -1
    ];
    // Get the post type posts with get_posts to allow non hierarchical post types
    $new_pages = get_posts( $args );    

    /**
     * You need to decide if you want to add custom post type posts to the pages
     * already in the dropdown, or just want the custom post type posts in
     * the dropdown. I will handle both, just remove what is not needed
     */
    // If we only need custom post types
    $pages = $new_pages;

    // If we need to add custom post type posts to the pages
    // $pages = array_merge( $new_pages, $pages );

    return $pages;
}, 10, 2 );

Если вы зайдете на переднюю часть и посетите первую страницу, вы обнаружите, что она будет перенаправлена на страницу с одной публикацией. Это связано с тем, что по умолчанию основной запрос на статической главной странице настроен на запрос типа записи page. Это приводит к возвращению 404, а затем redirect_canonical() перенаправляет на страницу с одной публикацией. Это легко решить, все, что нам нужно сделать, это настроить основной запрос на статической главной странице.

add_action( 'pre_get_posts', function ( $q )
{
    if (    !is_admin() // Only target the front end
         && $q->is_main_query() // Only target the main query
         && 'page' === get_option( 'show_on_front' ) // Only target the static front page
    ) {
        $q->set( 'post_type', 'my_frontpage' );
    }
});

Теперь ваша статическая главная страница будет отображаться правильно.

Все, что вам остается сделать, это установить шаблон. Вы можете просто создать front-page.php, WordPress автоматически будет использовать его

 2
Author: Pieter Goosen, 2016-01-23 13:26:17

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

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

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

С точки зрения моделирования данных нет причин определять полный тип данных или, скажем, класс, если вы хотите применить его только к одному элементу - в моем случае к одной главной странице. Я использовал другой плагин под названием Расширенные пользовательские поля, так как это позволяет использовать более продвинутые типы данных для ваших пользовательских полей, чем предлагает Wordpress из коробки. Вы можете добавить свои пользовательские поля с помощью functions.php также. Надеюсь, это поможет.

 0
Author: Bunjip, 2016-01-27 20:28:13

Ну, есть также дополнительный способ избежать использования шаблона страницы и позволить Wordpress загружать первую страницу, используя правильный шаблон типа сообщения. Это помогает избежать дублирования кода, если вы хотите, чтобы первая страница выглядела одинаково для одного сообщения:

add_filter( 'template_include', 'add_front_page_template_path', 10, 1);

function add_front_page_template_path( $template_path ) {
    if (
        is_front_page() 
        && get_option( 'show_on_front' ) == 'page' 
        && ( $post_id = get_option( 'page_on_front' ) )
        && ( $post_type = get_post_type( $post_id ) ) != 'page' 
    ) {
        $_template_path = get_single_template( $post_type );

        /* In case there’s no template */
        $template_path = ( $template_path == '' ) ? $template_path : $_template_path;
    }

    return $template_path;  
}
 0
Author: cruzquer, 2018-01-17 21:49:00