Sorting Posts by Custom Taxonomy and Title in WordPress with FacetWP

[ ][ ] September 3, 2024

Whats the Problem?

When using FacetWP to query and display posts, you may find that while you can filter posts based on custom taxonomies, sorting posts by those taxonomies and then by title within each term can be challenging. For instance, if you have a custom taxonomy called ‘partner-tier’ with terms like ‘platinum’, ‘elite’, ‘premier’, and ‘standard’, you might want to sort posts first by these tiers and then by post title alphabetically within each tier. This sorting requirement is crucial for displaying content in a meaningful and organized manner, especially when dealing with hierarchical or categorized content.

The Solution

To address this sorting issue, you need to implement custom sorting logic within the loop that handles the display of posts. The solution involves the following steps:

  1. Fetch and Store Posts: Collect all the queried posts into an array. This allows you to manipulate and sort the posts before rendering them.
  2. Custom Sorting Function: Create a custom sorting function using usort() to sort posts by the custom taxonomy term first and then by post title. The sorting function needs to handle:
    • Primary Sort: By the custom taxonomy term using a predefined order.
    • Secondary Sort: By the post title alphabetically within each taxonomy term.
  3. Display Sorted Posts: After sorting, use a loop to output the posts in the desired order.

Below is a code example that demonstrates this approach:

<?php
$custom_order = ['platinum', 'elite', 'premier', 'standard'];

// Array to hold posts
$posts_array = [];

// Collect posts in an array
if (have_posts()) {
    while (have_posts()) {
        the_post();
        
        $post_id = get_the_ID();
        $tier = wp_get_post_terms($post_id, 'partner-tier');
        if (is_array($tier) && !is_wp_error($tier) && isset($tier[0])) {
            $tier = $tier[0];  // Pass the term object
        } else {
            $tier = null;  // Set to null if no term
        }

        // Add post to array with tier data
        $posts_array[] = [
            'post' => $post,
            'tier' => $tier
        ];
    }

    // Sort posts based on the custom order of tiers and post title
    usort($posts_array, function($a, $b) use ($custom_order) {
        // Get tier slugs
        $slug_a = isset($a['tier']) ? $a['tier']->slug : '';
        $slug_b = isset($b['tier']) ? $b['tier']->slug : '';

        // Get indices for custom tier order
        $index_a = array_search($slug_a, $custom_order);
        $index_b = array_search($slug_b, $custom_order);

        // Handle cases where tiers are not found in the custom order array
        $index_a = ($index_a === false) ? PHP_INT_MAX : $index_a;
        $index_b = ($index_b === false) ? PHP_INT_MAX : $index_b;

        // First, sort by tier
        $tier_comparison = $index_a - $index_b;
        if ($tier_comparison !== 0) {
            return $tier_comparison;
        }

        // If tiers are the same, sort by post title
        $title_a = get_the_title($a['post']->ID);
        $title_b = get_the_title($b['post']->ID);
        
        return strcmp($title_a, $title_b);
    });

    // Output sorted posts
    echo '<div class="resource-container">';
    foreach ($posts_array as $item) {
        $post = $item['post'];
        $tier = $item['tier'];

        setup_postdata($post);

        // Pass the term object to the template part
        get_template_part('template-part/partner', null, array('tier' => $tier));
    }
    echo '</div>';

    // Reset post data
    wp_reset_postdata();
} else {
    echo '<h1>No Results</h1>';
}
?>

Conclusion

Sorting posts by custom taxonomy terms and then by title within each term can enhance the organization and presentation of content on your WordPress site. By using a custom sorting function within your loop, you can achieve the desired order, ensuring that posts are displayed in a structured and user-friendly manner. This approach integrates seamlessly with FacetWP and allows for precise control over post sorting.

If you encounter any issues or have specific requirements, feel free to adjust the sorting logic or reach out for further assistance.

Please note: This website is currently under development. I appreciate your patience and understanding as I work on perfecting everything. Thank you!