1

I have spent a couple of days working on this and I am still not able to figure it out. I am trying to make advanced search filter that sorts posts from a specific category on two criteria: location (custom field) and published date (default WordPress date). I want that the user is able to sort posts by location and also to specify the post order(descending or ascending) before pressing the search button. So far I managed to make a search on location but I have no idea how to combine the two criteria or how to sort the posts by date:

<form name="search" action="" method="get">
  <select name="place">
    <?php
    $metakey = 'place';
    $places = $wpdb->get_col($wpdb->prepare("SELECT DISTINCT meta_value FROM   $wpdb->postmeta WHERE meta_key = %s ORDER BY meta_value ASC", $metakey) );
    if ($places) {
       foreach ($places as $place) {
          echo "<option value=\"" . $place . "\">" . $place . "</option>";
       }
    }
  ?>
  </select>

  <select class="dropdown-class" name="sort-posts" id="sortbox">
      <option disabled>Sort by</option>
      <option value="&orderby=date&order=dsc">Newest</option>
      <option value="&orderby=date&order=asc">Oldest</option>
  </select>

  <input type="submit" value="Search" />
</form>

<?php
$places = $_GET['place'];
if ($places) {
  $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;

  $args=array(
    'cat'=>6,
    'meta_value' => $places,
    'paged'=>$paged,
  );

  query_posts($args);
} else {
  query_posts('cat=6&posts_per_page=4');
}

if ($places) { ?>
  <h1>Search for: <?php echo $places; ?></h3>
  <?php } else { ?>
  <h3></h3>
  <?php } ?>

<div class="content-area">

    <?php if ( have_posts() ) : ?>

        <header class="archive-header">
            <?php
                the_archive_title( '<h1 class="archive-title">', '</h1>' );
                the_archive_description( '<div class="archive-description">', '</div>' );
            ?>
        </header><!-- .page-header -->

        <?php
        while ( have_posts() ) :

            the_post();

            get_template_part( 'template-parts/content', get_post_format() );

        endwhile;

    endif;
    ?>

</div><!-- .content-area -->

I am not sure how to do that. I searched the net for hours but I could not find any solution. Any help will be much appreciated.

  • I'd suggest using the pre_get_posts hook with $query->set as a way to accomplish this. Generally, best not to work with wp-query in template-files.& make sure to sanitize your get-params, ie: 'meta_value' => sanitize_key($places) instead of 'meta_value' => $places – admcfajn Sep 18 at 17:25
  • is it possible to give an example? i have never done this before and i do not know how to sort the posts in ascending order – Badan Sep 18 at 19:07
0

I finally found a solution. For those who might also stumble on this.

What I had to do is to put ASC and DESC as option values for the date sorting. I read in the documentation that WordPress uses these values by default to sort data.

<select class="dropdown-class" name="order" id="sortbox">
    <option value="DESC">Newest</option>
    <option value="ASC">Oldest</option>
</select>

Then, create a variable that stores the search query values:

$sortedDate=$ _GET[ 'order']; //Either DESC or ASC

Finally, I had to sort the database query using the result from the search query:

  $args=array( 'cat'=>6, 
              'meta_value' => $places, 
              'order'=> $sortedDate, 
              'paged'=>$paged, ); 
  query_posts($args);

Full code:

--advanced-search.php

<?php 
/** 
 * Template Name: Advanced Search 
 * Author: Atanas Yonkov 
 */ ?>

<form class="post-filters" name="search" action="" method="get">
    <select name="place">
        <option value="" disabled selected> Place </option>
        <?php $metakey='place' ; $places=$ wpdb->get_col($wpdb->prepare("SELECT DISTINCT meta_value FROM $wpdb->postmeta WHERE meta_key = %s ORDER BY meta_value ASC", $metakey) ); if ($places) { foreach ($places as $place) { echo "
        <option value=\ "" . $place . "\">" . $place . "</option>"; } } ?>
    </select>

    <select class="dropdown-class" name="order" id="sortbox">
        <option value="DESC">Newest</option>
        <option value="ASC">Oldest</option>
    </select>

    <input type="submit" value="Search" />
</form>

<?php $places=$ _GET[ 'place']; 
$sortedDate=$ _GET[ 'order']; 

if ($places || $sortedDate) { 
  $paged=( get_query_var( 'paged')) ? get_query_var( 'paged') : 1; 
  $args=array( 'cat'=>6, 
              'meta_value' => $places, 
              'order'=> $sortedDate, 
              'paged'=>$paged, ); 
  query_posts($args); 
} else { 
  query_posts('cat=6&posts_per_page=5'); 
} 

if ($places) { ?>
<h1>Search for: <?php echo $places; ?></h3>
  <?php } else { ?>
  <h3></h3>
  <?php }

-- category-6.php

<?php
/**
 * The template for displaying programs
 * Implements custom advanced search filter
 */

get_header(); 
//Call the advanced-search.php template
get_template_part( 'advanced-search', get_post_format()) ?>

    <div class="content-area">
        <?php if ( have_posts() ) : //Loop through posts ?>
            <header class="archive-header">
                <?php
                    the_archive_title( '<h1 class="archive-title">', '</h1>' );
                    the_archive_description( '<div class="archive-description">', '</div>' );
                ?>
            </header><!-- .page-header -->
            <?php
            while ( have_posts() ) :
                the_post();
                get_template_part( 'template-parts/content', get_post_format() );
            endwhile;
        else :
            get_template_part( 'template-parts/content', 'none' );
        endif;
        ?>
    </div><!-- .content-area -->

<?php wp_reset_query(); ?>
<?php
get_sidebar();
get_footer();

The final result is that I am able to sort post types from specific category based on two different criteria.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.