phpwordpressloops

Handle one WP_Query with multidimensional arguments for several loops in Wordpress?


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?


Solution

  • The plan:

    If we try to plan for the database growth, we might come up with a display schema like this one:

    Schema

    where:

    For a scalable taxonomy search solution, we should look for a way to run WP_Query() only once for each search query.

    Taxonomy structure:

    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.

    Native taxonomy search:

    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.

    The User Interface:

    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

    Terms Pagination:

    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.