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

Custom Sorting of CPT & Taxonomies WordPress

  • SOLVED

Hello,

I have an archive page for my custom post type as well as some taxonomy pages.

I need to have a couple of sorting options:

Name (sort by post title)
Date (sort by Date)
20 (show 20 posts per page)
50 (show 50 posts per page)


So by default the posts will be in order by title, 6 per page and then clicking on this filters would change that.

Please let me know if you need to me to clarify anything,

Thanks!

Answers (3)

2012-12-13

John Cotton answers:

The conventional way to do it is something like:


switch($sort) {
case 'title':
$args = array( 'orderby' => 'title', 'order' => 'ASC' );
break;
case 'show_20':
$args = array( 'posts_per_page' => 20 );
break;
case 'show_50':
$args = array( 'posts_per_page' => 50 );
break;
default: // date desc - do nothing
break;
}

if( isset($args) ) {
global $wp_query;
$args = array_merge( $wp_query->query_vars, $args );
query_posts( $args );
}

get_header();


Clearly that's a little rough since I don't know what you are using/doing to indicate the filter sort, but hopefully you get the idea.

I say conventional since query_posts re-runs the main query. I hate the inefficiency of that (the wasted first query) so I tend to do custom sorting/filtering ahead of the main query by changing the SQL that gets passed around by the query filters.


Anthony Moore comments:

Hi John,

What other information would you need to understand what I am using to indicate the filter sort?

Essentially on my archive page above the posts I just have the links. No dropdowns or anything.




John Cotton comments:

<blockquote>
What other information would you need to understand what I am using to indicate the filter sort?

Essentially on my archive page above the posts I just have the links. No dropdowns or anything.
</blockquote>
The URLs for each link?


Anthony Moore comments:

Right now I do not have any urls for my links as I was unsure of what to put in them.

Do I need to create separate pages for each filter? or can my archive template be used?


John Cotton comments:

<blockquote>Or can my archive template be used?</blockquote>

The code I have given you is for your archive page. I've modified a little below as I noticed you wanted title as the default.


switch( $_REQUEST['sort'] ) {
case 'date':
// the query posts default, so we don't need to change anything...
break;

case 'show_20':
$args = array( 'posts_per_page' => 20 );
break;

case 'show_50':
$args = array( 'posts_per_page' => 50 );
break;

default:
$args = array( 'orderby' => 'title', 'order' => 'ASC' );
break;
}


if( isset($args) ) {
global $wp_query;

$args = array_merge( $wp_query->query_vars, $args );
query_posts( $args );
}

// code goes above get_header on your archive-cpt-type.php file
get_header();


So, taking date as an example, you'd have this link:

http://domain.com/archive-file-permalink?sort=date

Or for increasing the number
http://domain.com/archive-file-permalink?sort=show_20

Now I know what you're going to ask - "how do I get it to sort by date AND show 50?" - I'll leave you to figure that one out as I'm going to bed! You've got enough code above to fix that problem.



Anthony Moore comments:

Great thank you!

I have it working on my archive and taxonomy pages. I am however having a hard time getting it to work on a page template.

The page template is used to display all of the terms from that taxonomy. Do you know if this is possible to work with page templates?


John Cotton comments:

<blockquote>The page template is used to display all of the terms from that taxonomy. Do you know if this is possible to work with page templates?</blockquote>
Of course it will work - but you paste of the code doesn't show where you've tried putting it....

2012-12-13

Arnav Joy answers:

try this

<?php

/**

* Template Name: Celebrities

*

*

*/





get_header(); ?>



<div id="content">

<div class="row">

<div class="eight columns">

<div id="main">

<div id="archive-speakers">

<h3 class="page-title">Celebrities</h3>

<div id="top-pagination">

<p>

<span class="left">Sort by: <a href="<?php bloginfo('url'); ?>/celebrities/">Name<a> | <a href="<?php bloginfo('url'); ?>/celebrities/?sort=date">Most Recent</a></span>

<span class="right">View: <a href="<?php bloginfo('url'); ?>/celebrities/?show_posts=20">20</a> | <a href="<?php bloginfo('url'); ?>/celebrities/?show_posts=50">50</a></span>

</p>

</div>

<div class="clear"></div>



<?php $paged = (get_query_var('paged')) ? get_query_var('paged') : 1; ?>



<?php

if ( !empty( $_REQUEST['show_posts'] ) )
$show_posts = $_REQUEST['show_posts'];
else
$show_posts = 5;

if ( !empty( $_REQUEST['sort'] ) ){
$sort = 'date';
$order = 'DESC';
}
else{
$sort = 'title';
$order = 'ASC';
}


$my_query_args=array(

'post_type'=>'speakers',

'posts_per_page' => $show_posts ,

'orderby'=> $sort ,

'order'=> $order,

'paged'=>$paged,

'taxonomy_name'=>'celebrity_types'

);



$wp_query = new WP_Query($my_query_args);



while ($wp_query->have_posts()) : $wp_query->the_post(); ?>



<article>

...Some article stuff in here

</article>

<?php endwhile; wp_reset_postdata();?>



<div id="pagination">

<p><span class="left"><?php echo 'Page '. $paged . ' of ' . $wp_query->max_num_pages; ?></span><?php prev_blog_page(); ?><?php next_blog_page(); ?></p>

</div>

</div>

</div> <!-- #post -->

</div> <!-- #main -->



</div><!-- .row -->



</div><!-- #content-->







<?php get_footer(); ?>


Anthony Moore comments:

Yes thank you that worked for my page templates!

2012-12-13

Ellah Alzona answers:

Can you paste here everything in your page template so far?


Ellah Alzona comments:

Can I also see a screenshot of your desired output? A fast draft will do.


Anthony Moore comments:

<?php
/**
* Template Name: Celebrities
*
*
*/


get_header(); ?>

<div id="content">
<div class="row">
<div class="eight columns">
<div id="main">
<div id="archive-speakers">
<h3 class="page-title">Celebrities</h3>
<div id="top-pagination">
<p>
<span class="left">Sort by: <a href="<?php bloginfo('url'); ?>/celebrities/">Name<a> | <a href="<?php bloginfo('url'); ?>/celebrities/?sort=date">Most Recent</a></span>
<span class="right">View: <a href="<?php bloginfo('url'); ?>/celebrities/?sort=show_20">20</a> | <a href="<?php bloginfo('url'); ?>/celebrities/?sort=show_50">50</a></span>
</p>
</div>
<div class="clear"></div>

<?php $paged = (get_query_var('paged')) ? get_query_var('paged') : 1; ?>

<?php
$my_query_args=array(
'post_type'=>'speakers',
'posts_per_page' => 5,
'orderby'=>'title',
'order'=>'ASC',
'paged'=>$paged,
'taxonomy_name'=>'celebrity_types'
);

$wp_query = new WP_Query($my_query_args);

while ($wp_query->have_posts()) : $wp_query->the_post(); ?>

<article>
...Some article stuff in here
</article>
<?php endwhile; wp_reset_postdata();?>

<div id="pagination">
<p><span class="left"><?php echo 'Page '. $paged . ' of ' . $wp_query->max_num_pages; ?></span><?php prev_blog_page(); ?><?php next_blog_page(); ?></p>
</div>
</div>
</div> <!-- #post -->
</div> <!-- #main -->

</div><!-- .row -->

</div><!-- #content-->



<?php get_footer(); ?>


Anthony Moore comments:

Pretty much when this page template loads it displays all posts from a certain taxonomy, 5 per page.

Clicking on the "20" or "50"" button will load the same page, but now show 20 or 50 per page based on what the user clicked.