WordPress Custom Post URL Query

2019-08-09 04:34发布

I've been searching the web and rattling my brain for weeks but to no avail.

I have a product database on WordPress (v3.4) and I am trying to make it searchable using URL queries.

Ideally this is the scenario I want:

  • domain/products - to show all of the products
  • domain/products?tax1=term1 - to filter the products by a taxonomy
  • domain/products?tax1=term1&tax2=term2 - to filter my multiple
    taxonomies.

The post_type is called 'product' and I currently have a page called products with a page-template assigned to it. However, whenever I try to use the WordPress URL queries is redirects me to a similar URL'd news post (e.g. domain/2011/10/01/products-are-cool).

How do I go about creating these filters and having them display the results correctly?

UPDATE: I've come up with a solution that works perfectly for me.

if(isset($_GET)) $options = $_GET;

if (!empty($options)) {
$posts = new WP_Query( array(
'post_type' => 'product',                       
'orderby' => 'title',                       
'order' => 'asc',                       
'paged' => $paged,                      
'tax1' => $options['tax1'],                 
'tax2' => $options['tax2'],
));

And then use add_query_arg($termslug,$term->slug) to append the taxonomies onto the URL.

标签: php wordpress
1条回答
姐就是有狂的资本
2楼-- · 2019-08-09 04:43

You has some conflicting URI structure rules. You can add a line to htaccess to solve that for this particular page. Place it before the WordPress generated rules but after the RewriteEngine On clause.

RewriteRule    /products /?page=33 [L,QSA]

Where obviously 33 is the page id. The [L] directive means this is the last rewrite to be performed and should go straight to the new URI. [QSA] should attach any query that products?had=here to the new URI ?page=33&had=here.

I would point out the difference between Redirect and Rewrite:

  • a redirect sends a response back to you saying your URI has been redirected for some reason (temporarily/ permanently etc.):
    • http-request get /products?tax=tax1 =>
    • http-response 301 (moved permanently to:) /?page=33&tax=tax1 =>
    • http-request get /?page=33&tax=tax1
  • a redirect is visible in the address bar of your browser;
  • a redirect is indexed by search crawler;

  • a rewrite does not send a response back to you mentioning that your URI got rewritten;

  • a rewrite is not visible in the address bar of your site;
  • a rewrite behaves on the application side (WordPress) as if the application had received the rewritten URI (WordPress doesn't know when an address has been rewritten);

Basically the solution I suggested shows the visitor/ browser the /products?tax=tax1 address while showing WordPress the rewritten address /?page=33&tax=tax1.

Doing this in the .htaccess before other WordPress rewrites take place and using [L] which stops the execution of any following rewrites, allows you to avoid WordPress' internal mechanism of analyzing the URIs.

WordPress' internal mechanism would have tried to find out which category/ page/ post the URI is pointing to. But your URI scheme is not optimal (if you have categories and pages with the same name WordPress will choose one of them not necessarily the right one).

The following function needs to be put in the functions.php of your template code. Or in a plugin.

function custom_search_query( $request ) {
    $query = new WP_Query();  // the query isn't run if we don't pass any query vars
    $query->parse_query($request);

    $request['post_type'] = 'product';

    // this is the actual manipulation; do whatever you need here
    if(isset($_GET))
        $options = $_GET;
    if (!empty($options)) {
        $i = 0;
        $request['tax_query'] = array(); // resetting any previously selected meta_queries that might "linger" and cause weird behaviour.
        // CAREFUL HERE ^ might not be desired behaviour

        foreach($options AS $key => $value) {
            $request['tax_query'][$i]['taxonomy'] = $key;
            $request['tax_query'][$i]['terms'] = array($value);
            $request['tax_query'][$i]['operator'] = 'IN';
            $i++;
        }
    }

    return($request);
}
add_filter( 'request', 'custom_search_query' );

It makes no validation on the user input, (wordpress might do some of that but it's better if you do it).

查看更多
登录 后发表回答