WordPress - pre_get_posts вместо query_posts на страницах

Моя ситуация несколько сложная, я постараюсь объяснить ее как можно более лаконично.

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

Итак, почему я использую query_posts и не создаю объект WP_Query, который вы можете задать?

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

На одной странице я изменяю запрос, чтобы получить наиболее просматриваемые сообщения.

<?php $paged = get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1; ?>     
<?php query_posts( array( 'meta_key' => 'wpb_post_views_count', 'orderby' => 'meta_value_num', 'order' => 'DESC' ,  'paged' => $paged, ) ); ?>     


<?php if (have_posts()) : ?>

<?php while ( have_posts() ) : the_post() ?>

    <?php if ( has_post_format( 'video' )) {
            get_template_part( 'video-post' );
        }elseif ( has_post_format( 'image' )) {
            get_template_part( 'image-post' );
        } else {
           get_template_part( 'standard-post' );
        }

    ?>

<?php endwhile;?>

<?php endif; ?>

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

Возьмите это, например: -

function textdomain_exclude_category( $query ) {
    if ( $query->is_home() && $query->is_main_query() ) {
        $query->set( 'cat', '-1,-2' );
    }
}
add_action( 'pre_get_posts', 'textdomain_exclude_category' );

Хорошо, достаточно просто - если это главная страница, измените основной запрос и исключите две категории.

Я смущен и не могу понять: -

  • сценарий использования для настраиваемых шаблонов страниц. С моей модификацией query_posts я могу просто отбросить массив до if (have_posts()), выбрать мой шаблон страницы, опубликовать его и прочь. С pre_get_posts я не могу понять, как сказать, например, $query->most-viewed и т.д.

  • array( 'meta_key' => 'wpb_post_views_count', 'orderby' => 'meta_value_num', 'order' => 'DESC' , 'paged' => $paged, ) );

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

Ответ 1

Как использовать крюк pre_get_posts для отображения списка сообщений на странице с помощью настраиваемого шаблона страницы?

Я играл с крюком pre_get_posts и вот одна идея

Шаг # 1:

Запустить страницу, вызванную, например, Show with the slug:

example.com/show

Шаг # 2:

Создайте собственный шаблон страницы:

tpl_show.php

расположенный в текущем каталоге тем.

Шаг # 3:

Мы построим следующий обратный вызов действия pre_get_posts:

function b2e_pre_get_posts( $query )
{
    $target_page = 'show';                             // EDIT to your needs

    if (    ! is_admin()                               // front-end only
         && $query->is_main_query()                    // main query only
         && $target_page === $query->get( 'pagename' ) // matching pagename only
    ) {
        // modify query_vars:
        $query->set( 'post_type',      'post'                 );  // override 'post_type'
        $query->set( 'pagename',       null                   );  // override 'pagename'
        $query->set( 'posts_per_page', 10                     );
        $query->set( 'meta_key',       'wpb_post_views_count' );
        $query->set( 'orderby',        'meta_value_num'       );
        $query->set( 'order',          'DESC'                 );

        // Support for paging
        $query->is_singular = 0;

        // custom page template
        add_filter( 'template_include', 'b2e_template_include', 99 );
    }
}

add_action( 'pre_get_posts', 'b2e_pre_get_posts' );

где

function b2e_template_include( $template )
{
    $target_tpl = 'tpl_show.php'; // EDIT to your needs

    remove_filter( 'template_include', 'b2e_template_include', 99 );

    $new_template = locate_template( array( $target_tpl ) );

    if ( ! empty( $new_template ) )
        $template = $new_template; ;

    return $template;
}

Это также должно указывать на разбиение на страницы:

example.com/show/page/2
example.com/show/page/3

и др.

Примечания

Я обновил ответ и удалил модификацию части объекта запроса, основываясь на предположении от @PieterGoosen, так как это могло бы быть, например, сломайте панировочные сухари на его настройке.

Также удалили проверку is_page() внутри крюка pre_get_posts, поскольку в некоторых случаях она может по-прежнему давать некоторые нарушения. Причина в том, что объект запроса не всегда доступен. Это выполняется, см., Например, # 27015. Возможны обходные пути, если мы хотим использовать is_page() или is_front_page().

Я построил следующую таблицу, чтобы получить лучший обзор некоторых свойств и запросов varaables для основного объекта WP_Query для заданного пула:

table

Это интересно отметить, что разбиение на страницы в WP_Query зависит от того, что nopaging не задано, и текущая страница не является сингулярной (из источника 4.4 ):

// Paging
if ( empty($q['nopaging']) && !$this->is_singular ) {
    $page = absint($q['paged']);
    if ( !$page )
        $page = 1;

    // If 'offset' is provided, it takes precedence over 'paged'.
    if ( isset( $q['offset'] ) && is_numeric( $q['offset'] ) ) {
        $q['offset'] = absint( $q['offset'] );
        $pgstrt = $q['offset'] . ', ';
    } else {
        $pgstrt = absint( ( $page - 1 ) * $q['posts_per_page'] ) . ', ';
    }
    $limits = 'LIMIT ' . $pgstrt . $q['posts_per_page'];
}

где мы можем видеть, что часть LIMIT сгенерированного SQL-запроса находится в пределах условной проверки. Это объясняет, почему мы модифицируем свойство is_singular выше.

Мы могли бы использовать другие фильтры/крючки, но здесь мы использовали pre_get_posts, как указано OP.

Надеюсь на эту помощь.

Ответ 2

С вдохновением от ответа @birgire, я придумал следующую идею. (ПРИМЕЧАНИЕ: Это копия моего ответа из этого ответа на WPSE)

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

Используя пост-инъекцию, я могу сохранить целостность почты, поэтому $wp_the_query->post, $wp_query->post, $posts и $post остаются постоянными по всему шаблону, все они содержат только текущий объект страницы, случай с истинными страницами. Таким образом, функции, такие как панировочные сундуки, все еще считают, что текущая страница - это настоящая страница, а не какой-то архив

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

ПОСЛЕДОВАТЕЛЬНЫЙ ИНТЕРВЬЮ

Чтобы выполнить пост-инъекцию, я использовал специальный запрос для возврата сообщений, необходимых для инъекций. Я также использовал свойство пользовательского запроса $found_pages, чтобы настроить основной запрос, чтобы получить разбиение на страницы, выполняемые из основного запроса. Сообщения вводятся в основной запрос посредством действия loop_end.

Чтобы сделать пользовательский запрос доступным и полезным вне класса, я ввел несколько действий.

  • Ключи для разбивки на страницы, чтобы перехватывать функции разбиения на страницы:

    • pregetgostsforgages_before_loop_pagination

    • pregetgostsforgages_after_loop_pagination

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

    • pregetgostsforgages_counter_before_template_part

    • pregetgostsforgages_counter_after_template_part

  • Общий доступ для доступа к объекту запроса и текущему объекту post

    • pregetgostsforgages_current_post_and_object

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

Я также использовал get_template_part(), чтобы загрузить часть шаблона, которая будет использоваться для отображения сообщений. Большинство тем сегодня используют шаблонные части, что делает это очень полезным в классе. Если ваша тема использует content.php, вы можете просто передать content в $templatePart для загрузки content.php.

Если вам нужна поддержка формата post для шаблонных частей, это легко, вы можете просто передать content в $templatePart и просто установить $postFormatSupport в true, а часть шаблона content-video.php будет загружена для сообщение с почтовым форматом video

ГЛАВНЫЙ ВОПРОС

Следующие изменения были внесены в основной запрос через соответствующие фильтры и действия

  • Для разбивки основного запроса:

    • Значение свойства запроса инжектора $found_posts переходит к значению основного объекта запроса через фильтр found_posts

    • Задайте значение переданного пользователем параметра posts_per_page в основной запрос через pre_get_posts

    • $max_num_pages рассчитывается с использованием количества сообщений в $found_posts и posts_per_page. Поскольку is_singular истинно на страницах, он запрещает установку LIMIT. Просто установка is_singular на false вызвала несколько проблем, поэтому я решил установить предложение LIMIT через фильтр post_limits. Я сохранил offset предложения LIMIT, установленного на 0, чтобы избежать 404 на постраничных страницах

Это касается разбиения на страницы и любых проблем, которые могут возникнуть в результате пост-инъекции

ОБЪЕКТ СТРАНИЦЫ

Текущий объект страницы доступен для отображения в виде сообщения, используя цикл по умолчанию на странице, отдельно и поверх введенных сообщений. Если вам это не нужно, вы можете просто установить $removePageFromLoop в значение true, это отобразит содержимое страницы.

На этом этапе я использую CSS, чтобы скрыть объект страницы с помощью действий loop_start и loop_end, поскольку я не могу найти другой способ сделать это. Недостатком этого метода является то, что все, что связано с the_post action hook внутри основного запроса, также будет скрыто по умолчанию, если вы спрячете объект страницы.

КЛАСС

Класс PreGetPostsForPages может быть улучшен и должен быть правильно заменен на имена. Хотя вы можете просто отказаться от этого в своем файле функций темы, было бы лучше отбросить его в пользовательский плагин.

Используйте, изменяйте и злоупотребляйте по своему усмотрению. Код хорошо прокомментирован, поэтому его следует легко отслеживать и настраивать

class PreGetPostsForPages
{
    /**
     * @var string|int $pageID
     * @access protected     
     * @since 1.0.0
     */
    protected $pageID;

    /**
     * @var string $templatePart
     * @access protected     
     * @since 1.0.0
     */
    protected $templatePart;

    /**
     * @var bool $postFormatSupport
     * @access protected     
     * @since 1.0.0
     */
    protected $postFormatSupport;

    /**
     * @var bool $removePageFromLoop
     * @access protected     
     * @since 1.0.0
     */
    protected $removePageFromLoop;

    /**
     * @var array $args
     * @access protected     
     * @since 1.0.0
     */
    protected $args;

    /**
     * @var array $mergedArgs
     * @access protected     
     * @since 1.0.0
     */
    protected $mergedArgs = [];

    /**
     * @var NULL|\stdClass $injectorQuery
     * @access protected     
     * @since 1.0.0
     */
    protected $injectorQuery = NULL;

    /**
     * @var int $validatedPageID
     * @access protected     
     * @since 1.0.0
     */
    protected $validatedPageID = 0;

    /** 
     * Constructor method
     *
     * @param string|int $pageID The ID of the page we would like to target
     * @param string $templatePart The template part which should be used to display posts
     * @param string $postFormatSupport Should get_template_part support post format specific template parts
     * @param bool $removePageFromLoop Should the page content be displayed or not
     * @param array $args An array of valid arguments compatible with WP_Query
     *
     * @since 1.0.0
     */      
    public function __construct( 
        $pageID             = NULL,
        $templatePart       = NULL,
        $postFormatSupport  = false,
        $removePageFromLoop = false,
        $args               = [] 
    ) {
        $this->pageID             = $pageID;
        $this->templatePart       = $templatePart;
        $this->postFormatSupport  = $postFormatSupport;
        $this->removePageFromLoop = $removePageFromLoop;
        $this->args               = $args;
    }

    /**
     * Public method init()
     *
     * The init method will be use to initialize our pre_get_posts action
     *
     * @since 1.0.0
     */
    public function init()
    {
        // Initialise our pre_get_posts action
        add_action( 'pre_get_posts', [$this, 'preGetPosts'] );
    }

    /**
     * Private method validatePageID()
     *
     * Validates the page ID passed
     *
     * @since 1.0.0
     */
    private function validatePageID()
    {
        $validatedPageID = filter_var( $this->pageID, FILTER_VALIDATE_INT );
        $this->validatedPageID = $validatedPageID;
    }

    /**
     * Private method mergedArgs()
     *
     * Merge the default args with the user passed args
     *
     * @since 1.0.0
     */
    private function mergedArgs()
    {
        // Set default arguments
        if ( get_query_var( 'paged' ) ) {
            $currentPage = get_query_var( 'paged' );
        } elseif ( get_query_var( 'page' ) ) {
            $currentPage = get_query_var( 'page' );
        } else {
            $currentPage = 1;
        }
        $default = [
            'suppress_filters'    => true,
            'ignore_sticky_posts' => 1,
            'paged'               => $currentPage,
            'posts_per_page'      => get_option( 'posts_per_page' ), // Set posts per page here to set the LIMIT clause etc
            'nopaging'            => false
        ];    
        $mergedArgs = wp_parse_args( (array) $this->args, $default );
        $this->mergedArgs = $mergedArgs;
    }

    /**
     * Public method preGetPosts()
     *
     * This is the callback method which will be hooked to the 
     * pre_get_posts action hook. This method will be used to alter
     * the main query on the page specified by ID.
     *
     * @param \stdClass WP_Query The query object passed by reference
     * @since 1.0.0
     */
    public function preGetPosts( \WP_Query $q )
    {
        if (    !is_admin() // Only target the front end
             && $q->is_main_query() // Only target the main query
             && $q->is_page( filter_var( $this->validatedPageID, FILTER_VALIDATE_INT ) ) // Only target our specified page
        ) {
            // Remove the pre_get_posts action to avoid unexpected issues
            remove_action( current_action(), [$this, __METHOD__] );

            // METHODS:
            // Initialize our method which will return the validated page ID
            $this->validatePageID();
            // Initiale our mergedArgs() method
            $this->mergedArgs();
            // Initiale our custom query method
            $this->injectorQuery();

            /**
             * We need to alter a couple of things here in order for this to work
             * - Set posts_per_page to the user set value in order for the query to
             *   to properly calculate the $max_num_pages property for pagination
             * - Set the $found_posts property of the main query to the $found_posts
             *   property of our custom query we will be using to inject posts
             * - Set the LIMIT clause to the SQL query. By default, on pages, `is_singular` 
             *   returns true on pages which removes the LIMIT clause from the SQL query.
             *   We need the LIMIT clause because an empty limit clause inhibits the calculation
             *   of the $max_num_pages property which we need for pagination
             */
            if (    $this->mergedArgs['posts_per_page'] 
                 && true !== $this->mergedArgs['nopaging']
            ) {
                $q->set( 'posts_per_page', $this->mergedArgs['posts_per_page'] );
            } elseif ( true === $this->mergedArgs['nopaging'] ) {
                $q->set( 'posts_per_page', -1 );
            }

            // FILTERS:
            add_filter( 'found_posts', [$this, 'foundPosts'], PHP_INT_MAX, 2 );
            add_filter( 'post_limits', [$this, 'postLimits']);

            // ACTIONS:
            /**
             * We can now add all our actions that we will be using to inject our custom
             * posts into the main query. We will not be altering the main query or the 
             * main query $posts property as we would like to keep full integrity of the 
             * $post, $posts globals as well as $wp_query->post. For this reason we will use
             * post injection
             */     
            add_action( 'loop_start', [$this, 'loopStart'], 1 );
            add_action( 'loop_end',   [$this, 'loopEnd'],   1 );
        }    
    }    

    /**
     * Public method injectorQuery
     *
     * This will be the method which will handle our custom
     * query which will be used to 
     * - return the posts that should be injected into the main
     *   query according to the arguments passed
     * - alter the $found_posts property of the main query to make
     *   pagination work 
     *
     * @link https://codex.wordpress.org/Class_Reference/WP_Query
     * @since 1.0.0
     * @return \stdClass $this->injectorQuery
     */
    public function injectorQuery()
    {
        //Define our custom query
        $injectorQuery = new \WP_Query( $this->mergedArgs );

        $this->injectorQuery = $injectorQuery;

        return $this->injectorQuery;
    }

    /**
     * Public callback method foundPosts()
     * 
     * We need to set found_posts in the main query to the $found_posts
     * property of the custom query in order for the main query to correctly 
     * calculate $max_num_pages for pagination
     *
     * @param string $found_posts Passed by reference by the filter
     * @param stdClass \WP_Query Sq The current query object passed by refence
     * @since 1.0.0
     * @return $found_posts
     */
    public function foundPosts( $found_posts, \WP_Query $q )
    {
        if ( !$q->is_main_query() )
            return $found_posts;

        remove_filter( current_filter(), [$this, __METHOD__] );

        // Make sure that $this->injectorQuery actually have a value and is not NULL
        if (    $this->injectorQuery instanceof \WP_Query 
             && 0 != $this->injectorQuery->found_posts
        )
            return $found_posts = $this->injectorQuery->found_posts;

        return $found_posts;
    }

    /**
     * Public callback method postLimits()
     *
     * We need to set the LIMIT clause as it it is removed on pages due to 
     * is_singular returning true. Witout the limit clause, $max_num_pages stays
     * set 0 which avoids pagination. 
     *
     * We will also leave the offset part of the LIMIT cluase to 0 to avoid paged
     * pages returning 404's
     *
     * @param string $limits Passed by reference in the filter
     * @since 1.0.0
     * @return $limits
     */
    public function postLimits( $limits )
    {
        $posts_per_page = (int) $this->mergedArgs['posts_per_page'];
        if (    $posts_per_page
             && -1   !=  $posts_per_page // Make sure that posts_per_page is not set to return all posts
             && true !== $this->mergedArgs['nopaging'] // Make sure that nopaging is not set to true
        ) {
            $limits = "LIMIT 0, $posts_per_page"; // Leave offset at 0 to avoid 404 on paged pages
        }

        return $limits;
    }

    /**
     * Public callback method loopStart()
     *
     * Callback function which will be hooked to the loop_start action hook
     *
     * @param \stdClass \WP_Query $q Query object passed by reference
     * @since 1.0.0
     */
    public function loopStart( \WP_Query $q )
    {
        /**
         * Although we run this action inside our preGetPosts methods and
         * and inside a main query check, we need to redo the check here aswell
         * because failing to do so sets our div in the custom query output as well
         */

        if ( !$q->is_main_query() )
            return;

        /** 
         * Add inline style to hide the page content from the loop
         * whenever $removePageFromLoop is set to true. You can
         * alternatively alter the page template in a child theme by removing
         * everything inside the loop, but keeping the loop
         * Example of how your loop should look like:
         *     while ( have_posts() ) {
         *     the_post();
         *         // Add nothing here
         *     }
         */
        if ( true === $this->removePageFromLoop )
            echo '<div style="display:none">';
    }   

    /**
     * Public callback method loopEnd()
     *
     * Callback function which will be hooked to the loop_end action hook
     *
     * @param \stdClass \WP_Query $q Query object passed by reference
     * @since 1.0.0
     */
    public function loopEnd( \WP_Query $q )
    {  
        /**
         * Although we run this action inside our preGetPosts methods and
         * and inside a main query check, we need to redo the check here as well
         * because failing to do so sets our custom query into an infinite loop
         */
        if ( !$q->is_main_query() )
            return;

        // See the note in the loopStart method  
        if ( true === $this->removePageFromLoop )
            echo '</div>';

        //Make sure that $this->injectorQuery actually have a value and is not NULL
        if ( !$this->injectorQuery instanceof \WP_Query )
            return; 

        // Setup a counter as wee need to run the custom query only once    
        static $count = 0;    

        /**
         * Only run the custom query on the first run of the loop. Any consecutive
         * runs (like if the user runs the loop again), the custom posts won't show.
         */
        if ( 0 === (int) $count ) {      
            // We will now add our custom posts on loop_end
            $this->injectorQuery->rewind_posts();

            // Create our loop
            if ( $this->injectorQuery->have_posts() ) {

                /**
                 * Fires before the loop to add pagination.
                 *
                 * @since 1.0.0
                 *
                 * @param \stdClass $this->injectorQuery Current object (passed by reference).
                 */
                do_action( 'pregetgostsforgages_before_loop_pagination', $this->injectorQuery );


                // Add a static counter for those who need it
                static $counter = 0;

                while ( $this->injectorQuery->have_posts() ) {
                    $this->injectorQuery->the_post(); 

                    /**
                     * Fires before get_template_part.
                     *
                     * @since 1.0.0
                     *
                     * @param int $counter (passed by reference).
                     */
                    do_action( 'pregetgostsforgages_counter_before_template_part', $counter );

                    /**
                     * Fires before get_template_part.
                     *
                     * @since 1.0.0
                     *
                     * @param \stdClass $this->injectorQuery-post Current post object (passed by reference).
                     * @param \stdClass $this->injectorQuery Current object (passed by reference).
                     */
                    do_action( 'pregetgostsforgages_current_post_and_object', $this->injectorQuery->post, $this->injectorQuery );

                    /** 
                     * Load our custom template part as set by the user
                     * 
                     * We will also add template support for post formats. If $this->postFormatSupport
                     * is set to true, get_post_format() will be automatically added in get_template part
                     *
                     * If you have a template called content-video.php, you only need to pass 'content'
                     * to $template part and then set $this->postFormatSupport to true in order to load
                     * content-video.php for video post format posts
                     */
                    $part = '';
                    if ( true === $this->postFormatSupport )
                        $part = get_post_format( $this->injectorQuery->post->ID ); 

                    get_template_part( 
                        filter_var( $this->templatePart, FILTER_SANITIZE_STRING ), 
                        $part
                    );

                    /**
                     * Fires after get_template_part.
                     *
                     * @since 1.0.0
                     *
                     * @param int $counter (passed by reference).
                     */
                    do_action( 'pregetgostsforgages_counter_after_template_part', $counter );

                    $counter++; //Update the counter
                }

                wp_reset_postdata();

                /**
                 * Fires after the loop to add pagination.
                 *
                 * @since 1.0.0
                 *
                 * @param \stdClass $this->injectorQuery Current object (passed by reference).
                 */
                do_action( 'pregetgostsforgages_after_loop_pagination', $this->injectorQuery );
            }
        }

        // Update our static counter
        $count++;       
    }
}  

ИСПОЛЬЗОВАНИЕ

Теперь вы можете инициировать класс (также в вашем файле плагинов или функций), как показано ниже, для целевой страницы с идентификатором 251, на котором мы покажем 2 сообщения на страницу из типа сообщений post

$query = new PreGetPostsForPages(
    251,       // Page ID we will target
    'content', //Template part which will be used to display posts, name should be without .php extension 
    true,      // Should get_template_part support post formats
    false,     // Should the page object be excluded from the loop
    [          // Array of valid arguments that will be passed to WP_Query/pre_get_posts
        'post_type'      => 'post', 
        'posts_per_page' => 2
    ] 
);
$query->init(); 

ДОБАВЛЕНИЕ ПАГАЗИРОВАНИЯ И ТАМОЖЕННЫЙ СТИЛЬ

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

Вот действия, которые я использовал

add_action( 'pregetgostsforgages_counter_before_template_part', function ( $counter )
{
    $class = $counter%2  ? ' right' : ' left';
    echo '<div class="entry-column' . $class . '">';
});

add_action( 'pregetgostsforgages_counter_after_template_part', function ( $counter )
{
    echo '</div>';
});

add_action( 'pregetgostsforgages_after_loop_pagination', function ( \WP_Query $q )
{
    paginated_numbers();    
});

Обратите внимание, что разбиение на страницы задается основным запросом, а не запросом инжектора, поэтому также должны работать встроенные функции, такие как the_posts_pagination().

Это конечный результат

ввести описание изображения здесь

СТАТИЧЕСКИЕ ПЕРЕДНИЕ СТРАНИЦЫ

Все работает так, как и ожидалось, на статических передних страницах вместе с моей функцией разбиения на страницы без каких-либо изменений.

Заключение

Это может показаться действительно большим количеством накладных расходов, и это может быть, но pro перевешивает большое время

BIG PRO'S

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

  • В большинстве случаев вам нужно только создать часть шаблона content.php в вашей теме, если ваша тема еще не имеет

  • Любая страница, которая работает с основным запросом, будет работать на странице без какого-либо изменения или чего-либо еще от запроса, передаваемого функции.

Есть больше pro, о которых я не могу сейчас думать, но они важны

Я надеюсь, что это поможет кому-то в будущем