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, tag 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
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 Codex article on the subject is very, very helpful. A number of code snippets are provided 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 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 and install it in your testing environment (typically MAMP or WAMPServer, etc). Please download with Chrome rather than Safari: Safari automatically unpacks ZIP files unless a preference setting is changed.
Unpack the zip file by double-clicking it (Mac), then open the duplicator-parts folder and put the files that are inside it into a new folder called pedalmania2017 inside the htdocs folder in your MAMP installation (assuming you’re using MAMP, of course).
Start MAMP, make a database called pedalmania2017 and and then run through the Duplicator process. Add a new Admin user (you) as part of that process.
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 Netbeans project, this time with SASS support. Step-by-step instructions are here.
In the WordPress dashboard, set your new starter theme as the Active theme.
As I have likely mentioned in class, I like to duplicate index.php so that this fallback file is left untouched. That also means that I 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 Netbeans editing window. Our loop looks more or less like what is below (I have removed one 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() ) : ?> <header> <h1 class="page-title screen-reader-text"><?php single_post_title(); ?></h1> </header> <?php /* 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 this this. We are changing what posts get shown. In this case, we are getting a single random post 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' => '3', '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', 'home'); endwhile; the_posts_navigation(); // 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 three new random posts from that 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' => '3', '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', 'home'); endwhile; the_posts_navigation(); 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', 'home'); endwhile; the_posts_navigation(); 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 3 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.
In short, 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.