如果公共查询变量的值不存在,是否显示404错误页?

时间:2013-11-12 作者:its_me

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?

1 个回复
最合适的回答,由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 查询变量(无效的分类名称,但不仅如此)位于查询中。

结束