The Mijingo Blog

Latest news, updates, free tutorials, and more from Mijingo.

What’s the best way to learn the Craft CMS?

by Ryan Irelan

I just rolled out a Craft learning page that contains everything published here at Mijingo. It highlights the two courses (and the handy Craft Starter Pack bundle), articles written right here on this blog, and the episode of the CMS Chronicles Podcast on Craft.

These resources are the best way to get up and running with Craft.

If you want to share a link to the Mijingo Craft courses, this page is the best way to do it!

Where am I in the Twig Loop?

by Ryan Irelan

Twig offers special loop variables that makes it easy to know which iteration of the for-loop, for example, we are on. This allows us to do different styling, markup, or other condition-based things.

In Craft, we typically loop through our section entries like this:


{% for entry in craft.entries.section('news') %}
    {{ entry.title }} 
{% endfor %}

Twig loops through the Craft data and displays each entry retrieved from the News section.

To check if this is the first iteration of the loop, we can use a conditional and check against the loop.first variable from Twig.

A conditional in Craft allows us to control flow in the template. We use the if tag in Twig to make this happen. We can check if an expression evaluates to true:


{% for entry in craft.entries.section('news') %}
    {% if loop.first %}
        First!
    {% endif %}
    {{ entry.title }} 
{% endfor %}

In this example we’re testing if the loop.first expression is true. loop.first is one of six special loop variables made available to us from Twig (not Craft). This evaluates true if it is the first iteration of the for-loop. Otherwise it will evaluate false.

We’re not just limited to the loop.first variable. We can check for the current count, how many iterations until we reach the end of the loop (very handy!), and more.

Here are the other variations of loop:

  • loop.index - This is the count of the current iteration, starting at 1. Handy if you’re used to starting at 1 for counts or need to output it for something like table rows.
  • loop.index0 - Add a 0 and you get the count of the current iteration, starting at 0, instead of at 1. This is a more traditional way of counting iterations and how you would want to use it for for-loops.
  • loop.revindex - How many loops until the end? This variable will output the number of iterations left, starting at 1. If you want to start at zero, use the next variable.
  • loop.revindex0 - The same as the previous variable but starting at 0 instead of 1.
  • loop.last - A good way of knowing that your loop is about to end. Maybe you want to close a HTML tag or do something else before the loop is over. loop.last evaluates true if it is the last iteration of the loop.
  • loop.length - How many items are in the loop? This variable will output the total number of items so you know the total number of loops that will happen.

With the loop variable variations, you should need to set up a counter while iterating over data sets in Twig. Even you if need to start at 0 or 1, loop has you covered.

Ready to learn more about the Craft CMS?

My Craft Starter Pack is 4 ½ hours of premium learning that will get you started building sites with Craft for yourself, your company, or your clients.

Get Immediate Access

Creating an Age Drop-down with Twig range()

by Ryan Irelan

Even though Twig is just (just) a templating engine for PHP applications (like the super smooth Craft CMS), it can also do lots of “programmy” things on its own, too.

Let’s say I need to create a form that includes a Age drop-down select field. I could populate the form element with data from a database or maybe some fancy library.

Or I could just build it in Twig. No outside data, like Craft data, is needed. Just Twig. All by itself.

Enough chit-chat, here’s the code:


<select name="age">
{% for age in range(1, 100) %}
    <option value="{{ age }}">{{ age }}</option>
{% endfor %}
</select>

In this example we’re creating a select field element called age and outputting an option element with a bunch of ages. 1 to 100 to be precise.

We use the range function that comes with Twig. It’s really just a mirror of PHP’s range function. But we don’t have to write PHP!

The range function returns integers, in order, based on the range you specify.

range(1, 100)

The number to the left of the comma is the beginning of the range. The number to the right is the end of the range. Everything in between–and including–those numbers will be outputted.

When we iterate over a range with a for-loop, and include an option tag, we get a handy age menu.


{% for age in range(1, 100) %}
    <option value="{{ age }}">{{ age }}</option>
{% endfor %}

We use the age variable to create a value for each option element, which we could then store when that option is selected.

When rendered, it looks like this:

Try it out in a Craft template to see it in action.

We can also use a shorthand version of the range function with the .. operator (in the docs they call it “syntactic sugar” mmmm). It’s a simpler way of writing the same thing:


<select name="age">
{% for age in 1..100 %}
    <option value="{{ age }}">{{ age }}</option>
{% endfor %}
</select>

And that’s how you generate a data-filled age field with just Twig.

Ready to learn more about the Craft CMS?

My Craft Starter Pack is 4 ½ hours of premium learning that will get you started building sites with Craft for yourself, your company, or your clients.

Get Immediate Access

New Course: Twig Templates in Craft

by Ryan Irelan

Twig Templates in Craft covers the how, what, and why of using Twig in Craft templates. It’s the perfect companion to the Learning Craft course (and you can get them together as a bundle).

In this course you will get a comprehensive overview of working with Twig templates in Craft. The goal is to get over the hump of writing Twig code, dispel any myth that using Twig is difficult, and help you take the next step in using Craft.

I’ve found that the big questions people new to Craft have are:

  • Where does Twig end and Craft begin?
  • Which tags are Craft and which are Twig?
  • Where should I look when I need help? The Craft documentation or the Twig documentation?

By understanding what’s Craft and what’s Twig we’ll be able to answer all three of those questions.

We will work together to review the basics of templates in Craft first, and the move into the basics of Twig, and, finally, into the Craft-specific implementation of Twig.

Ready to learn more about Twig and Craft?

The new course is ready for you to download or stream. It also include a 35-page PDF course book.

Get the Twig and Craft course

Using Macros in Twig and Craft

by Ryan Irelan

Macros are the Twig version of functions. Just like you would write a function in PHP to do something and return something, you can use a Twig macro to generate some output.

Macros are used for generating often used markup that might vary slightly each time. You put your skeleton markup in the macro and use parameters passed in to alter that markup and then output it.

Building a Twig Macro

A macro looks like this:


{% macro macroName(parameter1, parameter2) %}

    {# contents of the macro here #}

{% endmacro %}

Let’s take a look at an example for a list of social networking links that we want to include in several places on a site, but with different variations.

We’ll generate the list using a macro, so we can control which social networks are included, and add a class name to the ul element.

The first thing we need to do is define the data that we want to pass in to the macro. We’ll do that with a hash (more on Twig hashes).

The hash contains the information about each social network that we want to include in the list. Each network has a name and a URL. We set the hash to the variable networks.


{% set networks = {
    twitter: { name: "Twitter", url: "http://twitter.com/mijingo" },
    facebook: { name: "Facebook", url: "http://facebook.com/mijingo" },
    instagram: { name: "Instagram", url: "http://instagram.com/mijingo" }
    }
%}

Now, let’s build the macro. It’ll be our little factory for creating social link lists.


{% macro socialList(networks, className) %}
    <ul {% if className %}class="{{ className }}"{% endif %}>
    {% for network in networks %}
        <li class="{{ network.name | lower }}"><a href="{{ network.url }}">{{ network.name }}</a></li>
    {% endfor %}
    </ul>
{% endmacro %}

Let’s step through this macro line by line to understand what it does.

We’ll call the macro socialList. It takes two parameters; the first one is a hash of the networks we want to include, and the second one is the class name for the ul element.

The markup inside of the macro is an unordered list that outputs the list of social networks.

The class name is optional, and we add a conditional to only output a class name if one is passed in.

We use a for-loop to iterate over the hash passed in to the macro and then output a li element with the social network information for each social network.

In case we want to add additional styling or an icon, we populate the li elements with a class of the network name. We are taking the network name and passing it to the lower filter to make the name lowercase (another option would be to use the key name instead of lowercasing the network name).

So the links are clickable, the link to the social network is populated using the URL that is in the hash.

To wrap up, we close the for-loop and then close our ul element and, finally, close our macro tag.

Calling a Twig Macro

To call this macro right from the template it’s in, we use our output tags and the _self prefix on the macro name.

{{ _self.socialList(networks, "three-share") }}

This will call the socialList macro, passing in the networks hash, and the class name of three-share.

Our output will look something like this:


<ul class="three-share">
    <li class="twitter"><a href="http://twitter.com/happylager">Twitter</a></li>
    <li class="facebook"><a href="http://facebook.com/happylager">Facebook</a></li>
    <li class="instagram"><a href="http://instagram.com/happylager">Instagram</a></li>
</ul>

It’s not always practical to include the macro in the same template, especially you want to use this macro in other templates in your site. To centralize our macros, we can put them in their own template and import it.

Let’s put the socialList macro in a template called _macros.html (or _macros.twig), removing it from the previous template.

To include that template and get access to the macro, we need to import the _macros.html file in the template where we want to access the macro.

{% import '_macros' as siteMacros %}

We import it into the siteMacros variable so we have it handy and ready to use.

In our template, we can drop the _self prefix and instead call it like this:

{{ siteMacros.socialList(networks, "three-share") }}

And now not only do we have a macro that will generate a list of social networks for us, we also have it abstracted out into its own macros template so we can use it in any of our templates.

Ready to learn more about the Craft CMS?

My Craft Starter Pack is 4 ½ hours of premium learning that will get you started building sites with Craft for yourself, your company, or your clients.

Get Immediate Access