使用漂亮的URL按自定义字段排序自定义帖子类型帖子

时间:2020-01-22 作者:Jonny

我有一个自定义的帖子类型,我们称之为my_post_type

它在/my_post_type/

我想创建一个与归档页面类似的漂亮URL,但按自定义字段值(即。/my-post-type/ranked/). 它还应包括分页(即。/my-post-type/ranked/2)

我知道我可以使用这些查询参数:

\'post_type\' => \'my_post_type\',
\'meta_key\' => \'rating\',
\'orderby\'   => \'meta_value_num\',
\'order\' => \'ASC\',
但是我对如何注册/my-post-type/ranked/ URL(无需创建单个帖子类型并为其分配模板)。

我尝试使用以下方法:

function rewriteOrderByRating() {
    add_rewrite_rule(\'^my_post_type/ranked/?\', \'index.php?post_type=my_post_type&meta_key=rating&orderby=meta_value_num&order=ASC\', \'top\');
}
add_action(\'init\', \'rewriteOrderByRating\', 10, 0);
。。。但我认为有两个问题:

meta_key=ratingorderby=meta_value_num 似乎不会影响查询。我也试过了orderby=meta_value. 这个rating 自定义字段存储为字符串,我不知道这是否会导致问题。

上面的代码不能解释分页(我的正则表达式很差)。我是否应该用额外的重写来解释分页?

1 个回复
最合适的回答,由SO网友:Jacob Peattie 整理而成

这是可能的,如果有点牵连的话。要实现这一目标,您需要:

自定义查询变量。一个基于查询变量对结果进行排序的过滤器。一个用于存档的重写规则,将查询变量应用于您的漂亮URL所以首先要做的是添加查询变量。这意味着?ranked=1 添加到URL的查询参数将传递到WP_Query 对象

add_filter(
    \'query_vars\',
    function( $query_vars ) {
        $query_vars[] = \'ranked\';

        return $query_vars;
    }
);
然后我们可以检查pre_get_posts 钩子,如果存在,则将主查询设置为按我们想要的方式排序帖子:

add_action(
    \'pre_get_posts\',
    function( WP_Query $query ) {
        if ( $query->is_post_type_archive( \'my_post_type\' ) ) {
            if ( $query->get( \'ranked\', false ) ) {
                $query->set( \'meta_key\', \'rating\' );
                $query->set( \'orderby\', \'meta_value_num\' );
            }
        }
    }
);
这将为您提供所需的功能,但URL很难看。访问/my_post_type/?ranked=1 将按所需格式显示结果,分页链接应自动保持ranked 参数,因此分页应该有效。

下一步是添加重写规则。你需要两个。一个用于第一页,然后一个用于分页页面。您只需采用post类型存档的默认重写规则,然后添加ranked:

add_action(
    \'init\',
    function() {
        add_rewrite_rule( \'my_post_type/ranked/?$\', \'index.php?post_type=my_post_type&ranked=1\', \'top\' );
        add_rewrite_rule( \'my_post_type/ranked/page/([0-9]{1,})/?$\', \'index.php?post_type=my_post_type&ranked=1&paged=$matches[1]\', \'top\' );
    }
);
现在您可以在加载排名的帖子/my_post_type/ranked//my_post_type/ranked/page/2. 的默认输出paginate_links() 将自动为您提供正确的链接,以便对排名结果进行分页。

因此,上述3段代码将为您提供所需的功能。如果需要检查您是否在其他Fitler或actions中查看排名视图,可以使用以下条件:

if ( get_query_var( \'ranked\', false ) ) {

}
例如,您可能希望筛选<title></title> 如果加载排名视图以添加“Top Rated”,则为页面标记。您可以这样做(只要您的主题支持title-tag):

add_filter(
    \'document_title_parts\',
    function( $title_parts ) {
        if ( is_post_type_archive( \'my_post_type\' ) ) {
            if ( get_query_var( \'ranked\', false ) ) {
                $title_parts[\'title\'] = \'Top Rated \' . $title_parts[\'title\'];
            }
        }

        return $title_parts;
    }
);

相关推荐

Problem with permalinks

我已经更改了类别的基本名称,现在它是“博客”,工作正常。但当我通过/blog/%category%/%postname%/更改结构时。显示404。如果我删除结构中的blog,它会再次工作,但我想使用blog word。问题出在哪里?非常感谢。