Changing WP_Query params with url Query Var

:)

I've used WP_Query to display there posts (travels) here http://boost19.delavec.si/wordpressP/produkti/

So... I've got this WP_Query that is looping through my custom posts

  ?php $paged = (get_query_var('paged')) ? get_query_var('paged') : 1; ?
            ?php $loop = new WP_Query( array(
                'post_type' = 'product',
                'meta_key' = 'product_price',
                'orderby' = 'meta_value_num',
                'order' = 'ASC',
                'posts_per_page' = 4,
                'paged' = $paged) ); ?

            ?php while( $loop-have_posts() ) : $loop-the_post(); ?

            div class="av_one_third" style="display: inline-block; width: 20%; margin-bottom: 3%; text-align: center; margin-left: 3%;"
                div class="card rounded-0 bg-light mb-3" style="width: 225px; height: 325px; text-align: center"
                    h5 class="card-title"?php the_title(); ?/h5
                    a href="?php the_permalink(); ?"
                        ?php the_post_thumbnail(); ?
                    /a
                    pWe are going to ?php the_field('product_place'); ?/p
                    pProduct price: ?php the_field('product_price'); ?€/p
                    ?php if(get_field('product_discount_price')): ?
                        h4Discount: ?php the_field('product_discount_price'); ?€/h4
                    ?php endif; ?
                    pWe are going on ?php the_field('product_date'); ?/p
                /div
            /div
        ?php endwhile; ?

And I wish to add like 'sorting' action to it - I was wondering if I could change the 'order' to 'DESC' for starters?

I've tried and read different things like https://premium.wpmudev.org/blog/building-customized-urls-wordpress/ https://codex.wordpress.org/WordPress_Query_Vars

and tried this with no avail ;

http://boost19.delavec.si/wordpressP/produkti/?order=DESC or http://boost19.delavec.si/wordpressP/?post_type=productorderby=meta_value_nummeta_key=product_priceorder=DESC

which doesn't return true values that is should.

Anyone faced anything like that? Or if anyone has any other ideas how to tacke this sort by price thing?

Btw I'm using advanced custom fields - the name for the price field is

product_price

Topic query-variable wp-query urls sort Wordpress parameter

Category Web


This code manually sets the order with the 'order' => 'ASC' declaration in the WP_Query arguments.

$loop = new WP_Query( array(
  'post_type' => 'product',
  'meta_key' => 'product_price',
  'orderby' => 'meta_value_num',
  'order' => 'ASC',
  'posts_per_page' => 4,
  'paged' => $paged) );

If we want to pass a url parameter to that we could use something like:

'order' => $_GET['posts_order']

along with a url-pattern, like: /?posts_order=ASC

But that would be a terrible idea... because someone could visit the url: /?posts_order=DROP TABLE IF EXISTS table1 & potentially break things.

So, if we're going to listen for a variable in the url, we'll want to sanitize it.

<?php 
if ( ! empty( $_GET['posts_order'] ) ) {
  $posts_order = sanitize_key( $_GET['posts_order'] );  // prevent malicious characters in user-submitted variable
}

or, even better, we can use a whitelist-approach & only allow certain values for

$posts_order = 'DESC';
if ( ! empty( $_GET['posts_order'] ) ) {
  $posts_order_raw = sanitize_key( $_GET['posts_order'] );
  if ( 'ASC' === $posts_order_raw ) {
    $posts_order = 'ASC';
  }
}

$loop = new WP_Query( array(
  'post_type' => 'product',
  'meta_key' => 'product_price',
  'orderby' => 'meta_value_num',
  'order' => $posts_order,
  'posts_per_page' => 4,
  'paged' => $paged) ); 

But wait, there's more!

We could omit the order declaration entirely from the WP_Query

$loop = new WP_Query( array(
  'post_type' => 'product',
  'meta_key' => 'product_price',
  'orderby' => 'meta_value_num',
  // 'order' => $posts_order, # Remove this line #
  'posts_per_page' => 4,
  'paged' => $paged) );

& instead, control the order from the pre_get_posts hook:

<?php
function wp_se_331547( $wp_query ) {

  if ( !is_admin() && is_main_query() ) {
    if( 'product' === get_post_type() ) {
      $posts_order = 'DESC';
      if ( ! empty( $_GET['posts_order'] ) ) {
        $posts_order_raw = sanitize_key( $_GET['posts_order'] );
        if ( 'ASC' === $posts_order_raw ) {
          $posts_order = 'ASC';
        }
      }
      $wp_query->set( 'order', $posts_order );
    }
  }

}
add_action('pre_get_posts', 'wp_se_331547');

About

Geeks Mental is a community that publishes articles and tutorials about Web, Android, Data Science, new techniques and Linux security.