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
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.