1

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?

3

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;
4
  • 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" 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. 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 Feb 17 '13 at 5:13
  • Can you please explain where to enter the code above? Feb 17 '13 at 6:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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