Quantcast
Channel: Topic Tag: plugin | WordPress.org
Viewing all articles
Browse latest Browse all 26892

teeli on "Order & filter by multiple taxonomies & terms"

$
0
0

Hello,

I'm currently developing a custom plugin for a website that I'm currently building. It's an employee browser for a company website. The way it currently works is something like this:

- It creates a custom post type: person
- It adds several custom taxonomies to sort people: industry ("tag", eg. IT, media, advertisement), position ("category", eg. CEO, CTO, developer), languages ("tag", eg. english, spanish, french), office ("category", a city where the person works)
- There's archive page with all employees & a single employee.

Here's the problem:

In the archive there's an option to sort the employees either by their name (post title) or position (custom taxonomy) starting from higher ups and ending at lower level employess (eg. CEO first, then CTO etc)

Currently this is done so that there is a custom orderby-parameter for post queries, (orderby=position). Like this:

add_filter( 'posts_clauses', 'mc_people_order_position', 10, 2 );
function mc_people_order_position( $clauses, $wp_query ) {
    global $wpdb;
    if( isset( $wp_query->query['orderby'] ) && 'position' == $wp_query->query['orderby'] ) {
        $clauses['join'] .= "LEFT OUTER JOIN {$wpdb->term_relationships} ON {$wpdb->posts}.ID = {$wpdb->term_relationships}.object_id
                             LEFT OUTER JOIN {$wpdb->term_taxonomy} USING (term_taxonomy_id)
                             LEFT OUTER JOIN {$wpdb->terms} USING (term_id)";
        $clauses['where'] .= " AND (taxonomy = 'position' OR taxonomy IS NULL)";
        $clauses['groupby'] = "object_id";
        $clauses['orderby'] = " FIELD({$wpdb->terms}.slug, 'janitor', 'developer', 'CTO', 'COO', 'CEO') DESC, {$wpdb->terms}.slug ";
        $clauses['orderby'] .= ( 'ASC' == strtoupper( $wp_query->get( 'order' ) ) ) ? 'ASC' : 'DESC';
    }
    return $clauses;
}

This produces an SQL query something like this:

SELECT SQL_CALC_FOUND_ROWS wp_posts.ID
FROM wp_posts
LEFT OUTER JOIN wp_term_relationships ON wp_posts.ID = wp_term_relationships.object_id
LEFT OUTER JOIN wp_term_taxonomy USING (term_taxonomy_id)
LEFT OUTER JOIN wp_terms USING (term_id)
WHERE 1=1
AND (wp_posts.post_status = 'publish' OR wp_posts.post_author = 1 AND wp_posts.post_status = 'private')
AND (wp_term_taxonomy.taxonomy = 'position')
GROUP BY object_id
ORDER BY FIELD(wp_terms.slug, 'janitor', 'developer', 'CTO', 'COO', 'CEO') DESC,
wp_terms.slug ASC LIMIT 0, 21

This works fine when there is no other taxonomy queries. However if I'd want to filter only employees in a certain specific industry for example, and also order by position this will break.

At the moment I'm completely stuck with this, so I'm turning to the community with this. Any ideas how to either improve my current code to allow filtering by another taxonomy or any suggestions for a completely new way to do this?

ps. I also tried tax_query (like in here http://codex.wordpress.org/Class_Reference/WP_Query#Taxonomy_Parameters) but I couldn't figure out if that can be even used to order by terms


Viewing all articles
Browse latest Browse all 26892

Trending Articles