Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I have the following Custom Post Types which are all linked to the destination taxonomy.

  • Deals
  • Accommodation
  • Attractions
  • Articles

How would I change the taxonomy-destination.php file to show matching posts from all 4 post types.

For instance, when currently viewing the destination "los angeles", it shows all this content together by date rather than separating in sepearte sections.

I would prefer to have them split, deals at the top, followed by the other content not all mixed together.

How would be best to achieve this?

share|improve this question
add comment

1 Answer 1

Hook into pre_get_posts, check for the taxonomy, and set all four post types as the post_type parameter of the query object. Check out the Type Parameters section on the WP_Query docs for more information.

<?php
add_action('pre_get_posts', 'wpse87225_set_post_types');
function wpse87225_set_post_types($query)
{
    if (is_admin() || !$query->is_main_query() || !is_tax('destination')) {
        return; // bail, not where we want to be
    }

    $query->set('post_type', array(
        'Deals', 'Accommodation', 'Attractions', 'Articles'));
}

The above could go in your functions.php file, or, more appropriately, a plugin.

Edit to address the group by requirement:

That's not going to split them up, however. There a few options to do that. First, you could just leave the main query alone (don't do the above), and create multiple instances of WP_Query and do multiple loops. Not bad.

You could also hook into posts_orderby and alter the SQL to order the posts by post type as well as whatever else is there:

<?php
add_filter('posts_orderby', 'wpse87225_posts_orderby', 10, 2);
function wpse87225_posts_orderby($orderby, $query)
{
    global $wpdb;

    if (is_admin() || !$query->is_main_query() || !is_tax('destination')) {
        return $orderby;
    }

    $new = "{$wpdb->posts}.post_type ASC";

    if ($orderby) {
        $orderby = $new . ', ' . $orderby;
    } else {
        $orderby = $new;
    }

    return $orderby;
}

You could even be very granular and order by specific post type with the help of the FIELD function.

<?php
add_filter('posts_orderby', 'wpse87225_posts_orderby', 10, 2);
function wpse87225_posts_orderby($orderby, $query)
{
    global $wpdb;

    if (is_admin() || !$query->is_main_query() || !is_tax('destination')) {
        return $orderby;
    }

    $new = "FIELD({$wpdb->posts}.post_type, 'Deals', 'Accommodation', 'Attractions', 'Articles') ASC";

    if ($orderby) {
        $orderby = $new . ', ' . $orderby;
    } else {
        $orderby = $new;
    }

    return $orderby;
}

Then just check when the post type changes, and display whatever header you like:

<?php
$post_type = '';
while (has_posts()): the_post;

if (get_post_type() !== $post_type) {
    // print the header for the post type
    // maybe something like this...
    echo '<h2>', esc_html(get_post_type_object(get_post_type())->label)), '</h2>';
}

// do stuff with the current post

$post_type = get_post_type();

endwhile;
share|improve this answer
    
I have used the bottom example in my functions.php file and it seemed to change the order, not sure what order though. It seems to be attraction then article, then attraction again. Also how would i "check when the post type changes, and display whatever header you like" –  Richard Ascough Feb 17 '13 at 4:38
    
If the "post types" you posted above are not the post type keys (eg. the first argument of register_post_type then it will not work as expected. Replace "Deals" with "whatever_you_register_the_deals_post_type_as". Same for the rest. I'll add an edit with check for header changes. –  chrisguitarguy Feb 17 '13 at 5:01
    
thanks that is now working, I forgot to add "guides" as a post type above. Seems to be displaying in order now. Now just need to change headers, or even templates based on post type –  Richard Ascough Feb 17 '13 at 5:13
    
Can you please explain where to enter the code above? –  Richard Ascough Feb 17 '13 at 6:58
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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