A Deeper Look Into WordPress; The Loop.
WordPress has changed a lot over the last 10 years, but one thing that has remained virtually unchanged over those years, is the loop. And also, the way that WordPress relies on the loop to handle it’s most important business, showing visitors the right content.
In this series, we’re going to take a deeper look into different working parts of WordPress, starting with the block of code that populates WordPress sites with the main content; the loop.
What The Loop Looks Like
The loop is what displays shows posts and pages when you go to different urls on a WordPress website. WordPress looks at the permalink, and either finds the ID for the single post or page that
There are technically two ways to write the loop, first is the new standard for conditional statements used in recent WordPress versions:
if (have_posts()) : while (have_posts()) : the_post(); the_content(); endwhile; endif;
And the second one we can make by using curly brackets, which used to be standard in PHP and also in older versions of WordPress years ago:
if (have_posts()) { while (have_posts()) { the_post(); the_content(); } }
The Basics of How The Loop Works
If you know the building blocks of WordPress, you know that the part of storing and retrieving content is mainly PHP and MySQL(or other databases). MySQL is a type of database that you can communicate with using SQL(that you can use inside PHP).
The first step of the loop happens before the loop even begins. WordPress checks what type of posts/content the loop should look for.
WordPress finds this out based on the permalink of the page. If it’s a post-id or post-url, it will tell the loop to look for that post. If it is a category url, the loop will look for posts in that category, if it’s a dated archive url, it will find all posts from that date, if it’s the homepage, then it will search for all posts.
Then the loop comes into play:
- The loop takes it’s terms from WordPress on the relevant page.
- The loop calls the MySQL database to check if any posts at all matches it’s terms.
- Then it moves on to collect the relevant information from the Database.
- Then it shows the data for a single post or page formatted according to the active WordPress theme’s template.
- Then it checks if there are more posts that fit the criteria. If there are more, it keeps going through steps 4 and 5 until, finally there is no more data in the database that matches it’s terms, and it closes the loop.
The Individual Functions Of The Loop
If you have no coding experience whatsoever, you may think that it’s great that php is a language that works in such plain English. You just ask the database, does it have any posts? And if it does, you serve them up, all using plain English. Except(and most of you will know this already), other than if, while, endif and endwhile, there are no php commands in this piece of code. The plain English words refering to posts and content are all functions contained within WordPress.
have_posts()
This is the function that calls the mySQL (or other) database connected to your WordPress site, and politely asks it if there are any posts around that matches it’s criteria.
In PHP, a simple query to a MySQL database to accomplish the same as this very basic functionality in the have_posts() function would look something like this:
$id="123" /*Wordpress automatically gets the appropriate id from the permalink, so it's working with a variable, not a set number. The point of PHP and MySQL is to avoid having to physically make and upload endless individual HTML page every time you want to add more content to a website*/ $prep = sprintf("SELECT * FROM POSTS WHERE ID ="%s" "mysql_real_escape_string($id)); /*You have to use sprintf and string to be able to indclude a string in your MySQL query.*/ $post = mysql_num_rows($prep); /*Mysql_num_rows just counts the rows of results from the database. It's often used in PHP to check for results before starting more queries for more information.)*/ if ($post == 0) : $continue = true ; else: $continue = false /*We then check if the number of rows is NOT 0 (there are two equal signs), and give the okay sign to the rest of our code to continue. If the result is indeed 0 there is no point to run the rest of the code that would still try to print out data, even if there was no data there*/
This is one of the easiest ways to check for a single post in a database. But have_posts is smarter than that and does a lot more.
If we look at the source code:
public function have_posts() { if ( $this->current_post + 1 < $this->post_count ) { return true; } elseif ( $this->current_post + 1 == $this->post_count && $this->post_count > 0 ) { /** * Fires once the loop has ended. * * @since 2.0.0 * * @param WP_Query $this The WP_Query instance (passed by reference). */ do_action_ref_array( 'loop_end', array( $this ) ); // Do some cleaning up after the loop $this->rewind_posts(); } $this->in_the_loop = false; return false; }
We can see that 1: it already has the results from the database in the form of the current_post and post_count. It then checks to see if current_post + 1 is larger than post_count or not.
This means that as the loop is cycling through the same code for each new post that it finds, eventually it runs out of results that matched the criteria of the query, and when there are no more posts following, have_posts() does something else instead of continung, it calls the rewind_posts() function to end the loop.
public function rewind_posts() { $this->current_post = -1; if ( $this->post_count > 0 ) { $this->post = $this->posts[0]; } }
Which will return 0 the next turn the initial query is run to check if there are any posts, causing the next part of the whole function to not be called. Closing the loop.
If the loop hadn’t been properly closed, you can end up with endless code that doesn’t stop, as it tries to print out blank nothingness from an empty result from the database.
So now that we know that the have_posts() function handles finding out if posts exist, collecting information from the database and also closing out the loop, it’s time to move on to what it doesn’t do: populate content.
the_content()
Quite self explanatory, the_content is used to display the content of the post that have_posts has found in the database.
In normal PHP, doing this would be almost as simple.
After making the query to check that there were results, we simply have to call out content from the correct row.
$prepcontent = sprintf("SELECT CONTENT FROM POSTS WHERE ID ="%s"" mysql_real_escape_string($id)); /* Notice how this time the query is only getting data from Content */ $thecontent = mysql_query($prepcontent); /* This time a standard mysql query to get the data, not just count the rows. */ echo $thecontent; /* Basic php code for displaying content. */
the_post()
Again quite self explanatory, the_post is used to display the content of the post that have_posts has found in the database.
the_title()
And yet again quite self explanatory, the_title is used to display the title of the post that have_posts has found in the database.
Conclusion
Hopefully this post gave you a deeper look into just how exactly the loop worse. We hope to see you next time when we tackle another of WordPress’ essential building blocks.
Leave a Reply