Views Taxonomy: Get Terms with Associated Nodes
This example serves as both an example of how to alter a Views2 query, as well as how to use the get_terms_by_count() function I’ve written.
Unfortunately there is not (at present) a Views2 taxonomy filter that lets you “Get only terms with at least X associated nodes.” We had a client request that terms without associated nodes be hidden. This was actually more complex than it sounds, but the solution led me to a whole new level of Views2 understanding. Views2 has a hook called hook_views_query_alter() that lets you alter a Views2 query before it is executed. This is exactly what we needed to do in order to only pull terms with associated nodes. Specifically, we needed to add an additional WHERE clause to the query.
So, we run a custom function to get all terms that have at least one associated node. We then loop through the resulting terms and build the where clause.
Unsure how to use this code, or where to put it? Perhaps you need to look at Creating a Custom Module.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
/** * Implement hook_views_query_alter(). */ function mymodule_views_query_alter(&$view, &$query) { // Only show terms in the first "page" display // (of the TaxonomyIndexes view) if they have associated nodes if ($view->name == 'TaxonomyIndexes' && $view->current_display == 'page_1') { $terms = mymodule_get_terms_by_count(4,1); //get terms from vocab 4 that have at least 1 row associated $where_clause = ''; foreach ($terms as $term) { if ($where_clause != '') { $where_clause .= ' OR '; } $where_clause .= 'term_data.tid = ' . $term->tid; } $view->query->set_group_operator('AND'); $view->query->add_where('with_records_filter', $where_clause); } } /** * Returns an array of taxonomy terms that have been associated with at least X nodes * * @param $vid * The vocabulary id * @param $min_items * The minimum number of nodes that have been associated with this term * @return * An array of taxonomy term objects */ function mymodule_get_terms_by_count($vid, $min_items = -1) { $terms = taxonomy_get_tree($vid); $items = array(); foreach ($terms as $term) { $count = taxonomy_term_count_nodes($term->tid); if ($count == -1 || $count >= $min_items) { $items[] = $term; } } return $items; } |
Resulting SQL query:
1 2 3 4 5 6 7 8 |
SELECT term_data.tid AS tid, term_data.name AS term_data_name, term_data.vid AS term_data_vid, term_image.tid AS term_image_tid FROM term_data term_data LEFT JOIN term_image term_image ON term_data.tid = term_image.tid WHERE (term_data.vid in ('4')) AND (term_data.tid = 15 OR term_data.tid = 16 OR term_data.tid = 17 OR term_data.tid = 19 OR term_data.tid = 20 OR term_data.tid = 97 OR term_data.tid = 21 OR term_data.tid = 22 OR term_data.tid = 23) |