Ask your WordPress questions! Pay money and get answers fast! (more info)

Sort Category Archive by Cutsom field - Frontend WordPress

  • REFUNDED

Hi,

I want to allow users to sort a category archive (all posts in a category view) from front end, I have 5 custom field to do so.

1) wpcf-year (ASC or DESC)
2) wpcf-rank=1
3) wpcf-rank=2
4) wpcf-rank=3
5) and group results by categories

I believe this can easily be managed by url parameters like http://www.domain.com/category/?category_name=oranges&sort=wpcf-year&order=ASC (something like that)

I need the php function to support this.

I have already changed the default listing of posts by date to custom field wpcf-year (DESC) with help of this code.


add_filter('pre_get_posts', 'sort_archive');

function sort_archive($q) {

if ($q->is_category) {

$q->set('orderby', 'meta_value_num');

$q->set('meta_key', 'wpcf-year');

$q->set('order', 'DESC');

}

return $q;

}


I need a new php code for front-end filters which will override the above code and sort the category archive.

Regards,
Navs

Answers (2)

2013-03-09

SĂ©bastien | French WordpressDesigner answers:

i havé suggested prize of 30 $ for this question

2013-03-09

house.tc answers:

In your archive template, before <?php if (have_posts()) : while (have_posts()) : the_post(); ?>
Insert a GET form for user to sort eg:

<form method="get">
<select name="year" >
<option value="2011">2011</option>
<option value="2012">2012</option>
...etc
</select>

<select name="order" >
<option value="desc">desc</option>
<option value="acn">asc</option>
...etc
</select>
...etc
// and other of your custom fields
<input type="submit" name="usort">
</form>

// start your custom query if user submit the form
if(isset($_GET['usort']))
{
$year = isset($_GET['year']) ? $_GET['year'] : null;
$order = isset($_GET['order']) ? $_GET['oder'] : 'asn';

.....etc

$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$args= array(
'order' => $order,
'meta_key' => 'wpcf-year'
'orderby' => 'meta_value',
'cat' => get_query_var('cat'),//get current category id
'paged' => $paged
);
query_posts($args);
$query = new WP_Query( $args );
//start your custom loop here
if ($query->have_posts()) : $query->while (have_posts()) : $query->the_post();

}
else // here start your normal loop
{
if (have_posts()) : while (have_posts()) : the_post(); ...etc
}


Just a quick thought, not sure is what you wanted. This is just the concept of how you want to do it, just for reference.


Naveenn comments:

Thanx for the replies,

However I'm not sure how to use the above code with different values, Also can this override the default (forced) sorting by wpcf-year as explained in the question?

How can I sort listing where wpcf-rank value is 1, 2 or 3?

Please advice.

Navs


house.tc comments:

Ok, you have three variables for your user to sort the order : wpcf-year, wpcf-rank and category name. So in your form you will have this:

<form method="get" action="<?php echo get_permalink(get_query_var('cat')); ?>">

<select name="order" > // this is dropdown input type

<option value="desc">desc</option>

<option value="acn">asc</option>

</select>

<select name="rank" > // this is dropdown input type

<option value="1>1</option>

<option value="2">2</option>
<option value="3">3</option>

</select>
<?php

//here is get all the terms in category, you can control the category by changing the argument here.
$args = array(
'type' => 'post',
'child_of' => 0,
'parent' => '',
'orderby' => 'name',
'order' => 'ASC',
'hide_empty' => 1,
'hierarchical' => 1,
'exclude' => '',
'include' => '',
'number' => '',
'taxonomy' => 'category',
'pad_counts' => false );

$cats= get_categories($args);
echo "<select name="catname">";
foreach($cats as $cat){
echo "<option value="'.$cat->slug.'">'.$cat->name.'</option>";
}
echo "</select>";


?>
// and other of your custom fields

<input type="submit" name="usort">

</form>


<?php
//here is start to processing the loop

< if(isset($_GET['usort']))//if user click the submit

{

$order = isset($_GET['order']) ? $_GET['oder'] : 'asn';

$rank = isset($_GET['rank']) ? $_GET['rank'] : '1'; set default value is 1

$catname = isset($_GET['catname']) ? $_GET['catname'] : '' ;

$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;

$args= array(

'order' => $order,//order input insert to here

'meta_key' => 'wpcf-year'

'orderby' => 'meta_value',

'category_name ' => $catname,//sort by the category name

'paged' => $paged

'meta_query' => array(
array(
'key' => 'wpcf-rank',
'value' => $rank,// your rank insert to here
'compare' => '='
)

);

query_posts($args);

$query = new WP_Query( $args );

//start your custom loop here

if ($query->have_posts()) : $query->while (have_posts()) : $query->the_post();

//here you can show your result

}

else // here start your normal loop

{

if (have_posts()) : while (have_posts()) : the_post(); ...etc

}

?>


You can try this code, I haven't test it. Note that you should complete the loop before you want to try this


Naveenn comments:

Hi,

Thanx for the reply.

My sort options are a bit different and not manged through for, but links.

I have a somewhat working function using pre_get_posts.


add_action('pre_get_posts', 'check_meta_sort');
function check_meta_sort(&$query)
{
if (!isset($_GET['sort'])) {
return;
}
$query->query_vars['meta_key'] = $_GET['sort'];
$query->query_vars['orderby'] = $_GET['sort'];
$query->query_vars['order'] = $_GET['sortorder'];
}


The above code works fine when I pass variables via url <strong>/?sort=wpcf-year&sortorder=ASC</strong>

It would be great if you can help me modify this

<strong>The problem</strong>

1) It makes my menu disappear, I am supposed to use <strong>is_main_query</strong> and not create a custom query.
2) I need to add rank variables to it (1,2,3) (To allow sorting by rank 1 or 2 or 3)
3) I need to group results by category name (ASC or DESC)


Naveenn comments:

Hi Guys,

I was able to get/create a working code and I'm happy with it. I am sharing the same for someone who lands on this page looking for it.


add_action('pre_get_posts', 'my_meta_sort');
function my_meta_sort($query) {
if( $query->is_admin == 1 ) {
return;
}
if( !$query->is_main_query() ) {
return;
}
if( !$query->is_archive == 1 ) {
return;
}
$my_field = ( $_GET['sort'] ) ? stripslashes( $_GET['sort'] ) : '';
$my_value = ( $_GET['sortorder'] ) ? stripslashes( $_GET['sortorder'] ) : '';
if( $my_field ) {
$query->set( 'meta_key', $my_field );
$query->set( 'orderby', $my_field );
if( $my_value ) {
$query->set( 'order', $my_value );
}
}
}


in the above code you can simply pass your custom field value <strong>/?sort=wp-custom-rank&sortorder=ASC</strong>

The code is working fine for me, however I was not able to group results by "selected" categories for the post (there can be multiple) or define multiple sort orders, like <strong>also sort by</strong> "title" of the post.