Two Key Principles for Understanding WordPress Functions

two hand | two principles of wordpress functions

If you don’t understand WordPress functions, your code will do a lot of things the hard way.

One of WordPress’s greatest strengths is its library of hundreds of predefined PHP functions. These functions are the correct way to do a lot of crucial things—everything from writing reliable permalinks inside a plugin to retrieving the username of a post’s author to querying the WordPress database directly. If you don’t understand them, foundational elements of WordPress like the_post will be a mystery to you, and your own code will end up doing an awful lot of things the hard (and hacky and fragile) way.

At the same time, trying to use a hundreds of irregularly named functions can be intimidating. So today I thought I’d give you two key principles for understanding WordPress functions. These are logical principles that are widely (although not universally) applicable across the function library, and that will help you understand at a glance what a given WordPress function does.

Let’s get started!

1. get_ Functions Return Things, the_ Functions Echo Things

David covered this in a post a while back, but it bears emphasizing:

  1. get_ functions return a value, letting you manipulate them in subsequent code.
  2. the_ functions echo a value, printing them onto the HTML page in the place where they’re called.

To illustrate, let’s look at the source code for two WordPress functions, the_ID() and get_the_ID():

function get_the_ID() {
    $post = get_post();
    return ! empty( $post ) ? $post->ID : false;
}

function the_ID() {
    echo get_the_ID();
}

Without describing get_the_ID() in full, what it does is give you back the numerical ID of the post. That’s what return means here: “Give it back to whomever asked for it.” Once you’ve got it, you can do anything with in subsequent code: multiply by 20, chop off the last digit, whatever. (By the way, if you’re wondering about the rest of that line of code, it means “return the ID, or return false if we can’t find the post that should have an ID in the first place.”)

Now let’s look at the_ID(). All it does does is echo the returned result from calling get_the_ID()! In other words, it just takes the number returned from get_the_ID() and, instead of using it in some way (multiplying it by 20, etc.), prints that number out onto the HTML page.

So let’s pretend you’re editing a PHP page template, like your theme’s index.php file, and want to print the post title onto the page. Here are some options:

<h1><?php get_the_title(); ?></h1> <!-- Nothing echoed, so results in an empty h1 element :( -->

<h1><?php the_title(); ?></h1> <!-- Prints out the post's title inside the h1 element -->

<h1><?php echo get_the_title(); ?></h1> <!-- Prints out the post's title inside the h1 element -->

<h1><?php echo 'My title: ' . get_the_title(); ?></h1> <!-- Prints out "My title: " and the post's title inside the h1 element -->

This relationship holds across the WordPress function library—with (sigh) the exception that the_post() does something important and doesn’t echo anything. With that caveat, though, it’s really helpful to know about and you can use it with confidence.

2. Inside or Outside the Loop?

The Loop is perhaps the core technical principle of WordPress. David’s explained the inner workings of The Loop very well here and, especially, here; I’d urge you to read those posts, particularly if the discussion below confuses you.

Now: Some functions must be called within The Loop, and some shouldn’t be.

To be clear, here’s what “inside The Loop” means; this would be in a PHP page template like your theme’s index.php file:

//OUTSIDE The Loop

if ( have_posts() ) : while ( have_posts() ) : the_post();

// INSIDE The Loop; post content goes here

endwhile; endif;

// OUTSIDE The Loop again

If that’s still confusing, please read David’s excellent posts on the topic.

To distinguish between “inside-The-Loop” and “outside-The-Loop” functions, we’re going to use an extended metaphor for The Loop’s place within WordPress:

WordPress as a car factory

First, our basic terms:

  • WordPress is a car factory.
  • Posts are individual cars.
  • The Loop is the factory’s assembly line.

Let’s explain the relationships between these terms in more detail:

  • An assembly line is what raw car materials (car parts) move through to be turned into a buyer-ready car.
  • In the same way, The Loop is what raw post materials (post content and metadata) move through to be turned into browser-ready HTML.

Now for the important part:

  • Every process that changes or retrieves information about individual cars must either be located on the assembly line, or must be told which car to act on in some other way. Processes that don’t act on individual cars shouldn’t be located on the assembly line.
  • Similarly, every function that retrieves, alters, or displays post properties must either take place inside The Loop, or must be given the ID of the post to act on as a function parameter. Functions that don’t act on individual posts shouldn’t be located inside The Loop.

Practically, this means the following:

  1. the_ functions and most get_the_ functions assume knowledge of the current post, so they only make sense inside The Loop.
  2. Outside The Loop, get_the_ functions that do work need to be told what post to act on—meaning they need a post ID as a function argument.
  3. Functions that aren’t used to retrieve, alter, or display post properties shouldn’t be called in The Loop.

On the assembly line: the_title(), a Loop-only function

To be able to refer so confidently to “the title” on a site that might have 1,000 posts, we clearly know which post we’re talking about.

For a painting machine to paint a car properly, the machine must know whether it’s a compact car or a full-sized sedan, and a lot of other car-specific information. That’s why you’ll find that machine on the assembly line: it gets its “current car” information that way, and it’s also located in the correct spot to paint the car at the right time in the manufacturing process.

Our “post-painting” function in this case is the_title(). It only works inside The Loop, and it “paints” the webpage that our factory is designed to create with the title of the current post.

To be able to refer so confidently to “the title” on a site that might have 1,000 posts and pages, we clearly know which post we’re talking about. What’s more, a function that simply prints out a single post’s title (with no additional options) makes very little sense outside the context of a webpage being constructed from that post.

So call the_title() inside The Loop. It’s the only thing that makes sense, just like you wouldn’t put a painting machine in the factory’s lobby.

On or off the assembly line: get_the_title(), an on- or off-Loop function

We could find out the paint color of a given car either on or off the assembly line; but if it’s off, you’ll need to specify which car you’re interested in.

Let’s say we want to find out (that is, “get”) the paint color of a given car.

This might make a lot of sense on the assembly line, in which case you could build a machine that would simply get the color of the car rolling along in front of it.

But you might also want to, say, send a quality inspection team out to the shipment area to get the color of a particular already-completed car. This could be done, but the team would need to be told exactly which car to inspect, or they won’t be able to report anything back.

In other words, you could do this on or off the assembly line; but if it’s off, you’ll need to take the extra step of specifying which car you’re interested in.

So it is with get_the_title(), a WordPress function that can either work in The Loop with no function arguments, or outside The Loop when given a post ID as a function argument. In other words:

get_the_title(); // Called inside The Loop, retrieves the current post title.
// Called outside The Loop, doesn't work.

get_the_title('121'); // Called inside or outside The Loop, retrieves the title of the post with ID 121.

Off the assembly line: wp_enqueue_script(), an off-Loop function

You wouldn’t want to put your accounting offices along the assembly line.

So far, we’ve been talking a lot about the factory’s assembly line. However, the factory also probably contains a warehouse, a front desk, a shipping department, management offices, accounting, etc. None of these departments need to know what specific car is currently being worked on—and you certainly wouldn’t want to put, say, your accounting offices along the assembly line itself!

So it is with wp_enqueue_script(), a function that makes very little sense to call inside The Loop. wp_enqueue_script() is used to require that the page being constructed include a specific JavaScript resource.

That JavaScript resource is not part of the post (or posts) being created by The Loop in any meaningful way. It doesn’t interact with individual posts in the same way that the accounting department doesn’t interact with individual cars. When there’s a shipment of cars ready, accounting will want to make sure that the shipment has an invoice attached to it, but it certainly doesn’t make sense to plunk them onto the factory floor (and sew an invoice into every driver’s seat) to make this happen.

So don’t use wp_enqueue_script() in The Loop. Much better in the cozy corner offices of a functions.php file or a plugin.

Make sense?

Get Cracking!

Well! I’ve pushed myself to the limit of my knowledge about car factories, and possibly hyperextended the metaphor-making area of my brain. In the process, I hope I’ve taught you some key principles that will enable you to wade into WordPress functions with confidence.

If you have any questions or comments, we’d love to hear them in the comments below. And if you enjoyed this post, please share with your friends—through the bar to your left or however you like. Thanks!

Image credit: ion-bogdan dumitrescu


7 Responses

Comments

  • Tom Dana says:

    Thanks the the article on functions. Your metaphor works great and it helped me understand the WordPress function world a little bit better.

  • Senff says:

    Great article, makes a lot of sense. But I’m still breaking my head over one thing…

    Why can’t the_title( ) be called outside the loop exactly?

    I know you don’t have to (because you can use get_the_title()), but if this is possible outside the loop:

    echo get_the_title(‘121’);
    echo get_the_title(‘123’);
    echo get_the_title(‘128’);

    Why isn’t this:

    the_title(‘121’);
    the_title(‘123’);
    the_title(‘128’);

    Again, not that I need/want to use it like that, but I’m just trying to understand the underlying reason why the_title() can’t be used like that.

    • Fred Meyer Fred Meyer says:

      Hey Mark,

      That’s a good question; I definitely understand the logic behind it.

      I think the answer has more to do with WordPress history than any deep principle of programming. Basically, the_title() has three arguments: “before” (arbitrary HTML before the title), “after” (arbitrary HTML after the title), and “echo” (whether to echo or return the generated markup).

      None of these arguments allows you to pass in a post ID. So the_title can only work when we can already take the post ID for granted—that is, inside The Loop.

      So why not just change the_title() to accept more arguments? The answer likely involves WordPress’s emphasis on backwards-compatibility. In other words, WordPress will generally stick with old, imperfect decisions rather than risk breaking people’s sites/themes/plugins/etc. in the process of overhauling the existing way things work.

      (Supporting this conclusion: the_title() has been around since WordPress 0.71, which is a very low number…)

      So the answer’s more a bit of a history lesson than anything to do with logic or programming. As you spend more time in WordPress you’ll find tons of things like this; in my opinion, the best thing in general is to roll with them, and to be philosophical about the value of backwards-compatibility over absolute cleanliness and consistency in the codebase.

      Hope that helps? Thanks for writing!

      Fred

      • Senff says:

        I will accept this answer! 😉

        Seriously though — that makes perfect sense, to not mess around with “established” functions. And you’re right, sometimes it’s just better to accept things for what they are and not think too much about it.

Pingbacks