4

I am wondering how to write code to order a list of posts by their terms from custom taxonomies?

Here is what I have so far:

  • I have a page that lists all the posts in a Custom Post Type, on one page.
  • Under each CPT Post, I have retrieved the Custom Taxonomies to show.
  • I have allowed for the CPT posts to be sorted by Alpha, ASC and DESC.

In the end, it looks like this: enter image description here

The Goal:

I would like to add a couple links with the "Sort By Title" ones I already have.

Specifically, I would like to order by (alpha) Director, Studio, and Episodes, because I know these are either strings or numeric.

I would also like to order by the Season Premiered, by year, but I may need to change the way I named those terms (It'll probably just spit out Winter 2011, Winter 2012 with the way it currently is).

Sorting by Genre is another matter entirely that I am not going to tackle because of the multiple terms.

I am not too sure how to go about this and could use the help.

The Page's Current Code:

<div class="content-container">
<a href="?sort=titleup">Sort By Title A-Z</a>
<a href="?sort=titledown">Sort By Title Z-A</a>
<hr>

<?php
$type = 'animes';
$args=array(
'post_type' => $type,
'post_status' => 'publish',
'posts_per_page' => -1,
'caller_get_posts'=> 1
);

if( isset( $_GET['sort'] ) && "titleup" == $_GET['sort'] ){
$args['orderby'] = 'title';
$args['order'] = 'ASC';
}

if( isset( $_GET['sort'] ) && "titledown" == $_GET['sort'] ){
$args['orderby'] = 'title';
$args['order'] = 'DESC';
}

$my_query = new WP_Query($args);
if( $my_query->have_posts() ) {
while ($my_query->have_posts()) : $my_query->the_post(); ?>
<div class="anime-title"><a href="<?php the_permalink() ?>" title="<?php the_title_attribute(); ?> Page"><?php the_title(); ?></a></div>

<br><span>Director:</span>
<?php 
$taxonomy = 'director';
// get the term IDs assigned to post.
$post_terms = wp_get_object_terms( $post->ID, $taxonomy, array( 'fields' => 'ids' ) );
// separator between links
$separator = ', ';

if ( !empty( $post_terms ) && !is_wp_error( $post_terms ) ) {

$term_ids = implode( ',' , $post_terms );
$terms = wp_list_categories( 'title_li=&style=none&echo=0&taxonomy=' . $taxonomy . '&include=' . $term_ids );
$terms = rtrim( trim( str_replace( '<br />',  $separator, $terms ) ), $separator );

// display post categories
echo  $terms;
}
?>

<br><span>Studio:</span>
<?php 
$taxonomy = 'studio';
// get the term IDs assigned to post.
$post_terms = wp_get_object_terms( $post->ID, $taxonomy, array( 'fields' => 'ids' ) );
// separator between links
$separator = ', ';

if ( !empty( $post_terms ) && !is_wp_error( $post_terms ) ) {

$term_ids = implode( ',' , $post_terms );
$terms = wp_list_categories( 'title_li=&style=none&echo=0&taxonomy=' . $taxonomy . '&include=' . $term_ids );
$terms = rtrim( trim( str_replace( '<br />',  $separator, $terms ) ), $separator );

// display post categories
echo  $terms;
}
?>

<br><span>Season Premiered:</span>
<?php 
$taxonomy = 'season';
// get the term IDs assigned to post.
$post_terms = wp_get_object_terms( $post->ID, $taxonomy, array( 'fields' => 'ids' ) );
// separator between links
$separator = ', ';

if ( !empty( $post_terms ) && !is_wp_error( $post_terms ) ) {

$term_ids = implode( ',' , $post_terms );
$terms = wp_list_categories( 'title_li=&style=none&echo=0&taxonomy=' . $taxonomy . '&include=' . $term_ids );
$terms = rtrim( trim( str_replace( '<br />',  $separator, $terms ) ), $separator );

// display post categories
echo  $terms;
}
?>

<br><span>Episodes:</span>
<?php 
$taxonomy = 'episodes';
// get the term IDs assigned to post.
$post_terms = wp_get_object_terms( $post->ID, $taxonomy, array( 'fields' => 'ids' ) );
// separator between links
$separator = ', ';

if ( !empty( $post_terms ) && !is_wp_error( $post_terms ) ) {

$term_ids = implode( ',' , $post_terms );
$terms = wp_list_categories( 'title_li=&style=none&echo=0&taxonomy=' . $taxonomy . '&include=' . $term_ids );
$terms = rtrim( trim( str_replace( '<br />',  $separator, $terms ) ), $separator );

// display post categories
echo  $terms;
}
 ?>


<br><span>Genres:</span>
<?php 
$taxonomy = 'genre';
// get the term IDs assigned to post.
$post_terms = wp_get_object_terms( $post->ID, $taxonomy, array( 'fields' => 'ids' ) );
// separator between links
$separator = ', ';

if ( !empty( $post_terms ) && !is_wp_error( $post_terms ) ) {

$term_ids = implode( ',' , $post_terms );
$terms = wp_list_categories( 'title_li=&style=none&echo=0&taxonomy=' . $taxonomy . '&include=' . $term_ids );
$terms = rtrim( trim( str_replace( '<br />',  $separator, $terms ) ), $separator );

// display post categories
echo  $terms;
}
?>
<hr>

<?php
endwhile;
}
wp_reset_query();  // Restore global post data stomped by the_post().
?>

Other Information:

Upon clicking the Title of the Show, it'll bring the reader to another page that shows an image of the show, the custom taxonomies listed again, and all other posts related to that Show (connected by Tag being the name of the Show). e.g, If there is a Review or Discussion post tagged with the Show "Boys and Girls", it'll show up on this page.

Upon clicking the taxonomy terms, the reader will be taken to the page that lists all the Shows that are related to that term. e.g, All the shows that have been made by that Studio, all the shows with 12 episodes, all the shows under the Genre 'Action'.

This above can potentially bring into question the overall structure of how I setup this up. I am very new to web development and wordpress, so I have done my best based on the research I've done.

I have a couple of other unanswered Stack Exchange posts that go further into details and questions about structuring this part of the website. Help there is appreciated as well, or if you need further clarification on what I am trying to attempt.

Custom Post Type and Taxonomies Structure

Creating a Sortable Table by Taxonomy Terms

Thank you very much for your time and the help you have all given me so far.

1
  • You can even just query posts as per normal, and then use usort to sort the returned array of results. I have don quite a few on this subject ;-) Commented Dec 1, 2015 at 4:26

2 Answers 2

4

WordPress core (as expressed by involved people on multiple occasions) strongly discourages sort by terms. It sees terms as exclusively grouping mechanism, with no ordering capabilities implied.

So in your specific case WP would understand that there are different directors, that there are groups of shows done by those directors, but won't at all understand that there is some expectation of how order of shows can be impacted by directors assigned.

Of course in practical development people do need to sort by terms in different circumstances. In practice this means some very custom SQL to make it happen.

One of the most useful examples of implementation I know is covered by Sortable Taxonomy Columns blog post.

So to make it happen you would have to write/adapt necessary SQL and then incorporate it into your queries.

2
  • Thank you Rarst! I just needed some sort of direction. I'll look back into SQL and making it work via that.
    – Nimara
    Commented Nov 30, 2015 at 18:44
  • For future reference to other readers: While I have accepted this answer, I have gone "both ways" in terms of how to tackle this. I am currently messing around with meta data that is an exact copy of the taxonomy terms. I have begun to sort by those for a simple page list for now, but definitely will be attempting to broaden my SQL skills by doing this as well. As it stands, I am going to benefit from learning both ways and more about taxonomies and custom post meta.
    – Nimara
    Commented Nov 30, 2015 at 22:11
2

While Rarst's answer is correct, helpful and really gives you room to improve your understanding about the subject, the shortest practical answer to ordering any WP_Query by a custom_post_meta is:

$args = array(
    'meta_key' => 'name',  //custom field name here
    'orderby' => 'meta_value', 
    'order' => 'ASC') // the sort order
    // the rest of your arguments here...
);

If you need a custom sort order, other than ASC or DESC, you need to build a custom Query.


UPDATE: My answer has nothing to do with the question. I simply missread it. Sorry.

I won't delete it though, as the comments hold useful information for anyone who didn't yet decide between using custom_post_meta or taxonomy for a certain attribute. Sorting by taxonomy term is possible, as Rarst has pointed out, using Scribu's query (3rd, improved version). But you should avoid it, as it will take a toll on the speed of your queries.

Use terms to group and meta to sort. Your site will be a lot faster, even with a lot of entries.

6
  • So instead of taxonomy terms are you suggesting I use custom post meta data instead? Would it be fine to use both?
    – Nimara
    Commented Nov 30, 2015 at 18:55
  • 1
    @Nimara You can use both but it could just be extra database clutter ( you decide if that's necessary ). I would suggest using the save_post hook to get the selected terms and save the selected term slugs as post_meta which you can then order as the answer suggests.
    – Howdy_McGee
    Commented Nov 30, 2015 at 18:57
  • 2
    I disagree that custom fields are interchangeable with taxonomy terms, there is plenty of nuance to it semantically and technically. In fact that's what I wrote about before in detail Taxonomy term or custom field :)
    – Rarst
    Commented Nov 30, 2015 at 19:03
  • While I wait for Andrei to touch on terms a little further-- @Rarst Do you think I was correct in using taxonomies for the above categories? After reading your article, I feel like I am on the right track, but unfortunately that does make ordering posts by these terms more difficult. I'm rereading some SQL tutorials right now so I can tackle it that way.
    – Nimara
    Commented Nov 30, 2015 at 19:17
  • 1
    @Rarst Custom Fields are not interchangeable but WordPress makes it so much easier if you need to sort on the values which is needed in practical development. I suggest he uses both to group ( tax ) and sort ( pm ) even though it adds additional relations that already exist. The queries will be both easier to understand and maintain in the long run. It could be that I'm just more comfortable with WordPress generating the SQL than writing the raw SQL myself though.
    – Howdy_McGee
    Commented Nov 30, 2015 at 19:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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