Categories
WordPress Templates

Multiple Loops in WordPress

About Custom Loops

This will likely be the most complex topic we cover in this class, but knowing how to make multiple loops in a single template file gives you some amazing abilities.

The default loop gives you posts in order of most recent to least recent.

However, with custom loops, we can select from a wide range of possible criteria with which to assemble and output our content.

Moreover, with multiple custom loops, we can:

  • have different sections on the page, each with their own content items. This content can be grouped by category, tag, author, date, reverse-chronology, etc.
  • have sections on the page with different numbers of content items
  • have random items
  • have different iterations of the loop call different template part files
  • etc

This depends on the WordPress wp_query object. Think of each new wp_query as a trip to the database pulling out the content you need for each particular part of the page.

To read about all of the various parameters available with wp_query, the WordPress Developer article on the subject is very, very helpful. A number of illuminating code snippets are provided there as well.

To get a sense of what I mean here, examine the image below, a 2016 screenshot of LangaraPRM.com.

There are a number of  sections on that page: Features, Environment, Community, Art, Travel, Food, Blog, Team Photos, Advertisement.

Each is a custom loop.

  • Features grabs the four most recent feature tagged entries from the database,
  • the next five sections get the single most recent post from each Category on the site that year,
  • the Blog section grabs the three most recent blog custom post type entries,
  • the Advertisement section grabs a random ad, and
  • the Team section gets from the database three student custom post type entries.

Moreover, each entry in these different sections can have different content pulled out. For example, some have excerpts; some do not. Some have larger feature images than others. The Team section gives social media links for each student—information stored with the post as a custom field.

( As an aside: to use custom fields, go to Screen Options in the post editing window and select it. Better yet, investigate one of the most widely used plugins in the WordPress world: Advanced Custom Fields ).

In short, custom loops greatly expand the ability of WordPress to be a true Content Management System as opposed to just a blogging platform.

 

 

Some Sample Content

For this exercise, I have created a Duplicator archive of a small site.

Please download the package. Use Chrome rather than Safari: Safari automatically unpacks ZIP files unless a preference setting is changed.

Unpack the zip file by double-clicking it (Mac) or right-clicking (Windows). This will leave you with a folder called pedalmania-2018. Put that folder in your testing environment htdocs folder (or equivalent).

Start MAMP, make a database called pedalmania2018 and then run through the Duplicator process. Add a new Admin user (you) as part of that process.

Finally, please also download the screenshots.

Get Underscores

Go to underscores.me and generate a new starter theme called pedalmania. In the Advanced section, click _sassify! if we have done SASS in class yet.

Install the newly created pedalmania starter theme inside wp-content/themes.

Set up a new project in whatever editor we’re using in class.

If using SASS, set up your watch process. I’ve created a simple gulp process: download and instructions on how to use it.

In the WordPress dashboard, set your new starter theme as the Active theme.

Start Theming

If you’re just starting learning how to template, a potentially useful practice is to duplicate your starter theme’s index.php file so that this fallback file is left untouched and that you therefore have a clean copy of the main template file if anything goes wrong.

Duplicate the file and name it front-page.php

Open front-page.php up in the preferred text editor. Our loop looks more or less like what is below.

We can also remove the conditional statement, and some comments, to save space.


get_header(); ?>

	<div id="primary" class="content-area">
		<main id="main" class="site-main" role="main">

		<?php
		if ( have_posts() ) : 

			/* Start the Loop */
			while ( have_posts() ) : the_post();
				get_template_part( 'template-parts/content', get_post_format() );
			endwhile;

			the_posts_navigation();

		else :
			get_template_part( 'template-parts/content', 'none' );
		endif; ?>

		</main><!-- #main -->
	</div><!-- #primary -->

<?php
get_sidebar();
get_footer();

If we test the page, we see that we get posts listed in this order:

  • Super Ring Tone Deluxe
  • Super Ringtone
  • Super Seek Wah
  • etc etc

This is the normal reverse chronological order. However, change your loop to look like what follows below (type the changes to the code; don’t just copy from the page you’re reading).

We are changing what posts get shown. In this case, we are getting two random posts from the fuzz category (there are four categories in the sample site I have given you).


 <!-- LOOP ONE: FUZZ -->
		<?php

// NEW STUFF HERE 
                $fuzz_query = new WP_Query( array(
                        'category_name' => 'fuzz', 
                        'posts_per_page' => '2',
                        'orderby' => 'rand',
                    ) );

 // MODIFIED STUFF HERE 
		if ( $fuzz_query->have_posts() ) :
			
// ADDITIONAL MODIFICATION HERE:			
			/* Start the Loop */
			while ( $fuzz_query->have_posts() ) : $fuzz_query->the_post();
				get_template_part( 'template-parts/content', get_post_format() );
			endwhile;
 
// ONE LAST ADDITION:
                        wp_reset_postdata();
		else :
			get_template_part( 'template-parts/content', 'none' );
		endif; 
?>

Reload the page and you will see that you get two new random posts from the FUZZ category.

Now duplicate the entire loop, and just change the name of the new query (in four places) to $modulation_query.

In the array passed to the new object constructor, change the category name to “modulation”. Here, then, are both loops:

<!-- LOOP ONE: FUZZ -->
		<?php
                $fuzz_query = new WP_Query( array(
                        'category_name' => 'fuzz', 
                        'posts_per_page' => '2',
                        'orderby' => 'rand',
                    ) );
                 
		if ( $fuzz_query->have_posts() ) :
			
			/* Start the Loop */
			while ( $fuzz_query->have_posts() ) : $fuzz_query->the_post();
				get_template_part( 'template-parts/content', get_post_format() );
			endwhile;

                        wp_reset_postdata();
		else :
			get_template_part( 'template-parts/content', 'none' );
		endif; ?>

     <!-- LOOP TWO: MODULATION -->
     
		<?php
                $modulation_query = new WP_Query( array(
                        'category_name' => 'distortion', 
                        'posts_per_page' => '3',
                        'orderby' => 'rand',
                    ) );
                 
		if ( $modulation_query->have_posts() ) :
			
			/* Start the Loop */
			while ( $modulation_query->have_posts() ) : $modulation_query->the_post();
				get_template_part( 'template-parts/content', get_post_format() );
			endwhile;

                        wp_reset_postdata();
		else :
			get_template_part( 'template-parts/content', 'none' );
		endif; ?>
             

Now if you test your home page, you will see that you now are getting random posts from two separate categories.

In the example code above, we are selecting posts by category and in random order. We can, however, select by tag, by post format, by custom post type, by not being in a category, etc. And we can arrange our content in chronological or reverse chronological order. We can sort by number of comments, etc.

If you’re wondering what the wp_reset_postdata function does: it restores the original page query object, in case other parts of the page uses it. Use it after after any custom queries.

Getting comfortable with WP_Query allows you to easily pull practically anything you want from the site database. The WordPress Codex article in exceptionally helpful in figuring out how to retrieve that content.

Your Lab Task

Please complete the site. If you look at the screenshots, you will notice that our home page needs one more loop (right at the beginning of the posts generation).

Specifically, we need three posts from the Super Series category. Make this query not random. Instead, have it output the three most recent posts in the Super Series category.

(My screenshots of the home page don’t show the latest Super Series posts, but please make sure that output does.)

Apart from that (and the single space ahead of each post title), please style the site as closely as possible to the examples in the screenshots. I have given you screenshots for Home, Category, and Search Results.

At this point, don’t worry about the single view of any posts.

Notice, also, that the content output varies a little bit in those places. For example, the Search output does not have post thumbnails. Do not just hide them with CSS. Use template-parts to output the desired content.

Bonus Lab Mark

If you look at the screenshots, you will notice that each pedal has a date of first manufacture and a price (both are under the title).

This is done with Custom Fields. These fields allow us to add additional data beyond the standard fields that show up when we make a new post.

If you don’t see the custom fields in the Dashboard, go to Screen Options (top right of screen when you’re editing a post in classic view, or the ) and choose Custom Fields.

For a 100% bonus (meaning you’ll get credit for two lab exercises), figure out how to output and style the custom fields where and how we want them (ie as in the screenshots).

For assistance in that task, consult this article.

(For some reason, the codex page on custom fields has lost the section on actually displaying the output and the new Developer’s area doesn’t appear to have anything on them).