Public query vars are those available and usable via a direct URL
query.
On my site, I\'ve created some custom URLs with their own query variables like so:
example.net/?category_name=uk&tag=highlights
(e.g. list posts that belong to both - the \'Tech\' category and \'gadgets\' tag)
And have rewrite rules (using add_rewrite_rule
) in place to pretty the URLs, for example, like this:
example.net/uk/tag/highlights/
(The category base is removed by default from category permalinks.)
Now, the problem with using public query vars is that, they almost never show a 404 error page. For example, take a look these two URLs:
example.net/?category_name=uk&tag=jdfjdsjfdlkf
example.net/uk/tag/jdfjdsjfdlkf
Even though the tag jdfjdsjfdlkf
doesn\'t exist, the visitor is shown a "Nothing found" page (content-none.php
) instead of throwing a 404 error (404.php) with appropriate headers.
When I think about it, it does make sense. But to suit my specific case, I want a specific set of public query vars (category_name
, tag
, and channel
- a custom taxonomy query_var) to show a 404 error page when the value supplied doesn\'t exist.
My initial attempts got me here:
add_action( \'template_redirect\', \'my_page_template_redirect\' );
function my_page_template_redirect() {
global $wp_query, $post;
$cat = get_query_var( \'category_name\' );
$category = get_term( $cat, \'category\' );
$chnl = get_query_var( \'channel\' );
$channel = get_term( $chnl, \'itsme_channel\' );
$tag = get_query_var( \'tag\' );
$post_tag = get_term( $tag, \'post_tag\' );
if( $category && !is_wp_error($category) && $channel && !is_wp_error($channel) ){
// If URL is like `example.net/?category_name=uk&channel=tech` and both of the
// supplied values (i.e. Category and Channel taxonomy terms) exist
// Do nothing
} elseif( $category && !is_wp_error($category) && $post_tag && !is_wp_error($post_tag) ) {
// If URL is like `example.net/?category_name=uk&tag=highlights` and both of the
// supplied values (i.e. Category and Tag taxonomy terms) exist
// Do nothing
} elseif( $category && !is_wp_error($category) && $channel && !is_wp_error($channel) && $post_tag && !is_wp_error($post_tag) ) {
// If URL is like `example.net/?category_name=uk&channel=tech&tag=highlights` and all the
// supplied values (i.e. Category, Channel, and Tag taxonomy terms) exist
// Do nothing
} else {
// If one or all of the supplied values don\'t exist throw a 404 error
$wp_query->set_404();
status_header(404);
nocache_headers();
}
}
Problem
Looks like the conditions in place are wrong, or the term objects ($category
, $channel
, $post_tag
aren\'t set properly), as I am always shown a 404 error page, i.e. even if the terms exist.
What am I doing wrong here?
最合适的回答,由SO网友:gmazzap 整理而成
即使您使其工作正常,您也要运行3个不同的查询(get_term
启动查询)除了对任何请求进行主查询之外,我认为这不是实现您想要的操作的正确方法。
我猜当你发送一个无效的标签/类别/自定义税时,你找不到任何帖子,那么为什么不呢
add_action( \'template_redirect\', \'my_page_template_redirect\' );
function my_page_template_redirect() {
global $wp_query;
if ( ! (int) $wp_query->found_posts > 0 ) {
$wp_query->set_404();
status_header(404);
nocache_headers();
}
}
编辑此函数返回404,即使
existing 分类法已经通过,但没有帖子。有人可以找到这样的好处,如果没有,这是一种不这样做的替代方法:
function my_page_template_redirect() {
global $wp_query, $wp;
// this get an array of the query vars in the url
parse_str( parse_url ( add_query_arg( array() ), PHP_URL_QUERY ), $qv);
if ( ! empty( $qv ) ) { // if there are some query vars in the url
$queried = array_keys( $qv ); // get the query vars name
$valid = $wp->public_query_vars; // this are the valid query vars accepted by WP
// intersect array to retrieve the queried vars tha are included in the valid vars
$good = array_intersect($valid, $queried);
// if there are no good query vars or if there are at least one not valid var
if ( empty($good) || count($good) !== count($queried) ) {
$wp_query->set_404();
status_header(404);
nocache_headers();
}
}
}
仅当一个或多个
invalid 查询变量(无效的分类名称,但不仅如此)位于查询中。