I want to optimize my code down below. locations and dance -styles are both categorycourses, but are identified by contants townLocation1 and TownLocation2 (the ones which isn't locations are dance-styles and vice versa)
$locations = get_terms("categorycourses", array('include' => array(townLocation1, townLocation2)));
$dance_styles = get_terms("categorycourses", array('exclude' => array(townLocation1, townLocation2)));
$content = '';
foreach ( $locations as $location ) {
$content .= . '<h1>'.$location->name.'</h1>';
foreach ( $dance_styles as $dance_style ) {
//Show courses that is associated with this dance-style
//and in this location
$loop = get_loop_courses($dance_style, $location->term_id);
if($loop->have_posts()) {
//show courses here (post with custom post type course)
}
} //end dance_styles
} //end locations
function get_loop_courses($categorycourse, $location_id) {
$terms_slug = strtolower($categorycourse->slug);
$terms_slug = str_replace(' ','', $terms_slug);
$args = array(
'posts_per_page' => -1, //Show ALL coures (no limit)
'post_type' => 'course',
'tax_query' => array(
array(
'taxonomy' => 'categorycourses',
'field' => 'slug',
'terms' => $terms_slug
),
),
);
$args['tax_query'][] = array(
'taxonomy' => 'categorycourses',
'field' => 'id',
'terms' => array($location_id)
);
}
$loop = new WP_Query($args);
return $loop;
}
The get_loop_courses
get called very many times and therefore when the database grows it's taking a lot of (unnessecary) time to load. My approach was thinking of building up an array of arguments (from the get_loop_courses-function) and then to execute the WP_Query ONCE and loop the resultset in a managable way. This is what I've tried:
$locations = get_terms("categorycourses", array('include' => array(townLocation1, townLocation2)));
$dance_styles = get_terms("categorycourses", array('exclude' => array(townLocation1, townLocation2)));
$loop_arr = array();
$content = '';
foreach ( $locations as $location ) {
$content .= . '<h1>'.$location->name.'</h1>';
foreach ( $dance_styles as $dance_style ) {
//Show courses that is associated with this dance-style
//and in this location
$loop_arr[] = get_loop_courses($dance_style, $location->term_id);
} //end dance_styles
} //end locations
$loop = new WP_Query($loop_arr); //this is giving me an array but with a lot of posts, and not the ones I intended
function get_loop_courses($categorycourse, $location_id) {
$terms_slug = strtolower($categorycourse->slug);
$terms_slug = str_replace(' ','', $terms_slug);
$args = array(
'posts_per_page' => -1, //Show ALL coures (no limit)
'post_type' => 'course',
'no_found_rows' => true, //no pagination!
'tax_query' => array(
array(
'taxonomy' => 'categorycourses',
'field' => 'slug',
'terms' => $terms_slug
),
),
);
$args['tax_query'][] = array(
'taxonomy' => 'categorycourses',
'field' => 'id',
'terms' => array($location_id)
);
}
return $args;
}
Am I thinking in "right" direction? Please give me pointers! This approach might not even be possible?
Is it possible to use transient in this case?
If we try to plan for the database growth, we might come up with a display schema like this one:
where:
It looks like your current solution is suitable for only few posts and terms (yellow)
With many posts and few terms, we want posts pagination (orange).
With many terms and few posts, we want to use terms pagination (green).
For many posts and terms, we want both kind of paginations (blue)
For a scalable taxonomy search solution, we should look for a way to run WP_Query()
only once for each search query.
It looks like you're splitting up your custom categorycourses
taxonomy into two mutually exclusive parts: locations and dance styles.
But I would recommend using two custom taxonomies: locations
and dancestyle
.
That sounds more logical.
When you got a large number of posts, you could use the native taxonomy search, to display all posts corresponding to a given location and dance style, for example.
example.com/?location=london&dancestyle=tango
This will use the main query and no need for secondary queries. The Twenty Twelve theme will use the archive.php
template to display the results and you will get the pagination for free!
If we want to use a custom template file instead of archive.php
, we can modify it with the template_include
filter.
There are many ways to cook up a user interface for the taxonomy search.
You could consider using a faceted search UI. Check for example this great plugin for good ideas:
http://wordpress.org/plugins/query-multiple-taxonomies/screenshots/
and here's a list of similar plugins:
https://github.com/scribu/wp-query-multiple-taxonomies/wiki/Similar-plugins
For a large number of terms (thousands), we can consider term pagination or some kind of drill down solutions like A-Z directory listing.
We can setup terms paginations in get_terms()
by using:
get_terms( 'mytaxonomy',
array(
'offset' => $offset,
'number' => $number,
)
);
I hope this helps you along the way.