【问题标题】:WordPress - pre_get_posts in place of query_posts on pagesWordPress - pre_get_posts 代替页面上的 query_posts
【发布时间】:2014-02-28 05:51:17
【问题描述】:

我的情况有些复杂,我会尽量简明扼要地解释一下。

我目前正在使用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' );

好吧,就这么简单——如果是主页,修改主查询并排除两个类别。

我感到困惑和想不通的是:-

  1. 自定义页面模板的用例场景。通过我的query_posts 修改,我可以在if (have_posts()) 之前放入数组,选择我的页面模板,发布它,然后我就走了。 对于pre_get_posts,我不知道怎么说,例如$query-&gt;most-viewed

  2. array( 'meta_key' =&gt; 'wpb_post_views_count', 'orderby' =&gt; 'meta_value_num', 'order' =&gt; 'DESC' , 'paged' =&gt; $paged, ) );

我到底是怎么用pre_get_posts 做到这一点的,并确保它是分页的,即。适用于无限滚动?在我使用pre_get_posts 看到的所有示例中,都没有数组。

【问题讨论】:

  • 对不起,我没有弄清楚你想要什么。 query_posts、WP_Query、pre_get_posts 都在 wp-includes/query.php 中,query_posts 使用 WP_Query 来做,所以这里基本上没有太大区别。 pre_get_posts 只是一个全局钩子,在做真正的工作之前修改 $query(由 query_posts($query) 传入,但解析)。
  • 我认为无限滚动与您的问题无关。无限滚动插件使用下一个页面链接获取内容。您也可以使用 get_posts、query_post 或任何您想要的方式设置这些链接。

标签: php wordpress


【解决方案1】:

如何使用pre_get_posts钩子通过自定义页面模板在页面上显示帖子列表?

我一直在玩 pre_get_posts 钩子,这是一个想法

第 1 步:

使用 slug 创建一个名为 Show 的页面:

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 的建议,我更新了答案并删除了查询对象部分修改,因为它可以例如打破他设置的面包屑。

还删除了pre_get_posts 挂钩中的is_page() 检查,因为在某些情况下它可能仍会产生一些违规行为。原因是查询对象并不总是可用的。这正在处理中,参见例如#27015。如果我们要使用is_page()is_front_page(),则有workarounds possible

我构建了下表,只是为了更好地了解给定 slug 的主要 WP_Query 对象的一些 属性查询变量

interesting to note WP_Query 中的 分页 取决于 nopaging 未设置且当前页面不是单数(来自 4.4 @987654325 @):

// 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'];
}

我们可以看到生成的 SQL 查询的LIMIT 部分在条件检查中。这就解释了为什么我们要修改上面的is_singular 属性。

我们本可以使用其他过滤器/挂钩,但这里我们使用了 OP 提到的pre_get_posts

希望对您有所帮助。

【讨论】:

  • 这是一个很好的答案,我认为这可能是我能得到的最好的答案,所以这里是赏金!可惜 pre_get_posts 没有更灵活。
  • 谢谢@andy,这是一个有趣的谜题;-)
  • 我会尽快将赏金奖励给你,不幸的是我无法在启动后的 24 小时内奖励赏金。享受;
  • 没问题。享受周日剩下的时间。在明天一切恢复正常之前“放松”的最后一天
  • 感谢@PieterGoosen 的更新和慷慨的赏金。我刚刚更新了答案。我想我最初发布它时试图删除页面标识,但由于您的建议,我现在跳过了该部分。
【解决方案2】:

在@birgire 回答的启发下,我想出了以下想法。 (注意:This is a copy of my answer from this answer over at WPSE

我在这里尝试做的是使用后注入,而不是完全更改主查询并陷入所有上述问题,例如直接更改全局变量、全局值问题和重新分配页面模板。

通过使用帖子注入,我能够保持完整的帖子完整性,因此$wp_the_query-&gt;post$wp_query-&gt;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

  • 访问查询对象和当前帖子对象的通用钩子

    • pregetgostsforgages_current_post_and_object

这些钩子为您提供了完全不干涉的体验,因为您不需要更改页面模板本身的任何内容,这是我从一开始的初衷。页面可以完全从插件或函数文件中更改,这使得它非常动态

我还使用了get_template_part() 来加载一个模板部分,该部分将用于显示帖子。今天的大多数主题都使用模板部分,这使得这在课堂上非常有用。如果您的主题使用content.php,您可以简单地将content 传递给$templatePart 以加载content.php

如果您需要模板部分的帖子格式支持,这很容易,您仍然可以将content 传递给$templatePart 并将$postFormatSupport 设置为true,然后将加载模板部分content-video.php帖子格式为video的帖子

主要查询

通过相应的过滤器和操作对主查询进行了以下更改

  • 为了对主查询进行分页:

    • 注入器查询的$found_posts 属性值通过found_posts 过滤器传递给主查询对象的值

    • 通过pre_get_posts将用户传递参数posts_per_page的值设置给主查询

    • $max_num_pages 是使用 $found_postsposts_per_page 中的帖子数量计算得出的。因为is_singular 在页面上为真,所以它禁止设置LIMIT 子句。简单地将is_singular 设置为false 会导致一些问题,因此我决定通过post_limits 过滤器设置LIMIT 子句。我将LIMIT 子句的offset 设置为0 以避免分页页面上出现404

这会处理分页和后期注入可能引起的任何问题

页面对象

当前页面对象可通过使用页面上的默认循环显示为帖子,独立于注入帖子的顶部。如果您不需要这个,您可以简单地将$removePageFromLoop 设置为true,这将隐藏页面内容而不显示。

在这个阶段,我使用 CSS 通过 loop_startloop_end 操作隐藏页面对象,因为我找不到其他方法。此方法的缺点是,如果您隐藏页面对象,则默认情况下,主查询中与 the_post 操作挂钩的任何内容也将被隐藏。

课程

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's $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++;       
    }
}  

用法

您现在可以按如下方式启动类(也在您的插件或函数文件中)以定位 ID 为 251 的页面,我们将在该页面上显示来自 post 帖子类型的每页 2 个帖子

$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(); 

添加分页和自定义样式

正如我所说,注入器查询中有一些操作可以添加分页或自定义样式。在这里,我使用my own pagination function from the linked answer 在循环之后添加了分页。此外,使用内置计数器,我添加了一个 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() 这样的内置函数也应该可以工作。

这是最终结果

静态首页

在静态首页以及我的分页功能上,一切都按预期工作,无需进行任何修改

结论

这可能看起来确实是很多开销,也可能是这样,但是专业人士的胜过骗局的重要时间

BIG PRO'S

  • 您无需以任何方式更改特定页面的页面模板。这使得一切都是动态的,并且可以轻松地在主题之间转移,而无需修改代码,无论一切都在插件中完成。

  • 如果你的主题还没有,你最多只需要在你的主题中创建一个content.php模板部分

  • 在主查询上工作的任何分页都将在页面上工作,无需任何类型的更改或传递给函数的查询之外的任何额外内容。

我现在想不到还有更多的专业人士,但这些是重要的

我希望这对将来的某人有所帮助

【讨论】:

  • Pieter,您是否获得了meta_query 来使用此解决方案?我试图只找到具有一定元价值的帖子,但到目前为止还没有成功。将meta_query 作为PreGetPostsForPages() 中的参数之一传递似乎不起作用。
  • 令人愉快的答案。运行代码并注意到以下内容:preGetPosts 方法在打开条件中检查 validatedPageID$this-&gt;validatedPageID 未设置 - 通过方法 $this-&gt;validatePageID() - 直到条件运行之后。
猜你喜欢
  • 1970-01-01
  • 2015-03-02
  • 2013-04-23
  • 2014-11-11
  • 1970-01-01
  • 1970-01-01
  • 2015-01-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多