If you’ve seen or written any L&L markup, you’re undoubtedly familiar with the legendary Loop—the queen of queries and the tag to end all tags. The Loop tag is one of the most useful and important tags available in the L&L templating language. So important, in fact, that we named the plugin after it! And while its core concept is simple, mastering this tag requires having a good mental model of why and how it works. In this post, we’ll dive deep into what the Loop tag does and how you can use it as the foundation for any L&L template you could imagine.

What does the Loop tag do?

A loop can be thought of as an instruction that tells WordPress to look through the items in your site’s database to find every piece of content that matches a certain set of criteria. For each post that matches that criteria, the inner content of the loop runs once, allowing you to display the fields of each post or do any number of things using the other tags available in L&L. For a more detailed explanation of the <Loop> tag, take a look at our absolute beginner’s guide to Loops & Logic.

We should note that we didn’t invent the name; WordPress’s own theme development handbook refers to the PHP mechanism of getting post content as “The Loop”.

When should the Loop tag be used?

The Loop tag should be used any time data from the WordPress database needs to be fetched, compared, or modified before being displayed or used by other dynamic tags.

When should the Loop tag not be used?

If you only need to work with fields from the current post (the post on which you’ve placed your Tangible Template), then there’s no need to use the Loop tag to get the content. Using tags like <Field title /> at the top level of your template (i.e. not nested inside other tags or loops) will get field data from the current post.

How does a loop affect the context of other tags?

One of the most important things to wrap your mind around when working with L&L is the context of your tags. It’s a pretty simple concept, but it’s worth spending some time on the topic because it’s so important when writing L&L markup that does what you want it to do.

All of the dynamic tags in L&L (like Loop and Field) understand the context in which they’re placed. That’s why placing <Field title /> directly into a template on a blog post shows the title of the post, whereas placing that same tag inside a post loop (like <Loop type=post><Field title /><Loop>) shows the title of each of the posts in the loop. In the first case, you can imagine that the <Field title /> tag looks around, sees that it’s been placed inside a Tangible Template block which is itself inside a blog post, and understands that the title field it should display is the one from the current blog post. In the second case, the <Field title /> tag isn’t just sitting by itself on a blog post, it’s sitting inside of a Loop tag. So each time the loop runs (once for each post in the query), the <Field title /> tag looks around, sees that it’s inside the current item in the loop (in this case, a new blog post each time the loop runs) and understands that the title field it should display is the one from the current blog post inside the loop. Every time you use a dynamic tag in L&L, the behaviour of that tag will be affected by the context it’s placed in.

Hopefully, by this point, you have an intuitive understanding of how dynamic tags get their context. But what happens when you’re not just placing a dynamic tag by itself on a page or inside a loop? If you use a dynamic tag as an attribute value (like <Loop type=post author="{Field name}">), where is that Field name tag getting its context? To illustrate that, take a look at the real-world L&L markup example below. Don’t worry if you don’t understand what’s going on at first glance, we’ll go over it piece by piece.

<h2>Recent posts by <Field author_full_name /></h2>
<ul>
  <Loop type=post author="{Field author}" count=5 orderby=date order=desc>
    <li>
      <a href="{Field url}"><Field title /></a>
      <Loop taxonomy=category post=current>
        <If check="{Field name}" value=best-practices>
          ⬅ Useful tips!
        </If>
      </Loop>
    </li>
  </Loop>
</ul>

If we placed this template on this blog post, it would output something like this:

You can see that we’ve used the Field tag in several different places in that markup, but in each case, it’s getting field data from a different place on my site. It starts by getting Field author_full_name from the current post that this template is placed on, then further down it gets Field url and Field title from posts written by the same author as this post, and then a bit further it checks the name of the category term associated with each of the blog posts using Field name. Let’s take a look at where each of those tags get their context.

<h2>Recent posts by <Field author_full_name /></h2>

Here, the <Field author_full_name /> tag is placed inside a template and that template could be placed on a page, post, or archive. In our example, we’ve decided to place the template on a blog post, so the tag will get its data from the current blog post on which the template has been placed.

<Loop type=post author="{Field author}" count=5 orderby=date order=desc>

We then open a loop and we’ve decided to use the author="{Field author}" query parameter to make it so that the loop only shows posts written by the same author as the post on which the template has been placed. Remember that tags get their context based on what’s around them. For the Field authortag in this case, that tag wouldn’t get its context from the loop since we haven’t actually opened our loop yet, we’re still just defining what we want to loop through. This means that Field author, just like Field author_full_name above, gets its context and data from the blog post on which we’ve placed our template.

But get ready because once we get inside the loop (everything between the > above and the closing </Loop> tag), we’ll be in a different context!

<a href="{Field url}"><Field title /></a>

All right, now we’re inside a loop, which means that these two Field tags get their context from the current item in the loop, not the current post on which we’ve placed the template.

<Loop taxonomy=category post=current>

And now we’re opening another loop; a loop within a loop! This one exists so that we can loop through the taxonomy terms of each blog post being displayed by our outer loop. Notice the query parameter post=current. Because this taxonomy term loop is inside a post loop, that parameter refers to the current post from the outer loop, not the current post that the template is placed on. Context is important!

  <If check="{Field name}" value=best-practices>
    ⬅ Useful tips!
  </If>

We’ve made it to the last bit of markup before we close all our tags. What we’re doing here is that for each taxonomy term in the taxonomy loop (the one we just opened above), we want to check whether the term matches “best-practices”. We’re doing this so that if ever one of the blog posts is in our blog’s Best Practices category, we can emphasize it with a little “⬅ Useful tips!” note. Here again, we’re using Field name to get the name of the current item. Where does this tag get its context? From the taxonomy term loop that surrounds it!

Minor note: you would probably usually use the field=name attribute here instead of check="{Field name}", but we decided to do it this way to show an extra example of how context works in L&L.

How can data be passed from the inner content of one loop to the inner content of another?

We’ve seen in the examples above where tags placed in different parts of your L&L markup get their context. But what happens when you want to pass data from one loop to the inner content of another loop? This isn’t a complete example, but imagine something like this:

<Loop type=post>
  <Loop type=taxonomy_term>
    Here's some data from the post loop: <Field name />
    And here's some data from the taxonomy term loop: <Field name />
  </Loop>
</Loop>

Hopefully, by now you see that this structure wouldn’t work. In that example, both Field tags are in the taxonomy term loop, so they would both get their context from that inner loop. Without any additional L&L magic, it wouldn’t be possible to dynamically refer to the fields of the post loop. Luckily, L&L is full of magic. The solution is to work with variables using the Get and Set tags. Here’s how we would use the Get and Set tags to pass data from one loop to the inner content of another based on the example above:

<Loop type=post>
  <Set name=data_from_post_loop><Field name /></Set>
  <Loop type=taxonomy_term>
    Here's some data from the post loop: <Get name=data_from_post_loop />
    And here's some data from the taxonomy term loop: <Field name />
  </Loop>
</Loop>

How should L&L markup be organized so that the context of a tag is clear?

A useful way to visualize the context of any part of your L&L markup (i.e. to check whether a tag placed directly on the template or if it’s placed inside of a loop) is to properly indent your markup just as you would if you were writing HTML. If your markup isn’t indented properly, it may not be obvious just from looking at your template that one loop might be nested inside another or that a Field tag might getting its context from a loop instead of from the post on which the template is placed.

Luckily, L&L’s template editor makes it really easy to indent your markup. If you select all of your template (ctrl+a), you can use shift+tab to make your code automatically indent itself correctly (assuming you’ve written all your opening and closing tags properly).

Leave a Reply

Your email address will not be published. Required fields are marked *