The Mijingo Blog

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

Using Categories in Craft CMS

by Ryan Irelan

Let’s say you have a website that displays recipes for beer brewing and you want to assign a category to each recipe to note the beer style (IPA, Stout, etc). Doing so will make it easier for visitors to sort through the recipes and find a recipe they would like to make.

Lucky for us this site exists. It’s called Crafty Brewery. If you followed the Craft video course then you recognize this from the Matrix videos.

Crafty Brewery Sample Site

If you’ve worked with other CMSes, Craft’s category setup is similar but, I think, a lot better.

During this tutorial we’re going to cover:

  • Creating a Category Group
  • Creating Category Fields
  • Displaying and linking to categories in Craft.entries loop
  • Creating a category page that lists all categories in a group

Let’s jump in.

The video version of the tutorial is available as part of the Learning Craft course. 3 ½ hours of learning over 11 videos. Download or stream right here on the site.


While going through the tutorial, please follow along with your own copy of the Crafty Brewery website. All of the files you need are available for download.

Start with the download for Craft Categories Begin, which contains the starter templates and database. The download Craft Categories End contains the complete project as it would be if you completed this tutorial.

Don’t forget to import the database beforehand and adjusting the config file per your local environment.

The sample project does not include the Craft app directory. You’ll need to provide that yourself by downloading it from the Craft website.

If you don’t want to set up your own copy of Craft, you can spin up a free demo at the Craft website. You won’t be able to do everything in the tutorial using the Craft demo but will be able to follow along with the control panel sections.

Creating a Craft Category Group

First, we need a place to store our categories. We use a Category Group to do this. This is a similar setup as most other CMSes you’ve worked on.

Navigate to Settings > Categories in the Craft control panel. Create a new Category Group.

Creating a new Craft Category Group

In the Category Group setting, we give the group a name, a handle (how we can refer to the group in our template), and then define the URL format and the template we want to use.

For our category group we will give it the name of “Beer Styles” and the handle will be populated automatically for us based on that name. The name and handle should be descriptive of what the category group is. If you find your name is long and the handle is also long, you can manually trim the handle so you don’t have to type a Tolstoy novel into your template just to access the field.

Some important settings for our new Category Group:

  • We want to enable categories to have their own URLs via the checkbox. This is going to be key for us because we want the visitors to Crafty Brewery to be able to view recipes by style (e.g. show all Ale recipes or all Stout recipes). We know this is important because we have a solid understanding of how our target audience searches for beer recipes.

  • For the category URL formats we need to set the URL to exactly how we want that category page URL to structured when somebody clicks on a category link. For beer styles, I want the category URL structure to be recipes/styles/{slug}. If I was accessing the IPA category, this will give me the URL of http:/ That’s nice and clean and makes sense structurally.

  • For nested categories, we can leave the default behavior of using the parent URI, which is the one we just set, and then the slug of the category.

  • For the Category Template field we need to tell Craft which template to use when viewing the category page. Because this is a category that is for the brewing recipes, I’ll assume I want to place it in my recipes template directory (although I haven’t created that template yet). Let’s call it category.html.

We still need to create the category template and will do that in just a minute. But first let’s create the fields we need to store information about each category.

Creating Category Fields

Craft gives us the option to define our Field Layout (via the “Field Layout” tab at the top of the form) when creating the category group. However, we don’t yet have the fields we need created. Let’s do that first and then come back and set the Field Layout.

Next, navigate to Settings > Fields.

The category name (or the style name in this implementation) we will input using the Title field that we get automatically. But I’d like to also have a description of the beer style to display on the category page.

Let’s create a new field to store that style description.

We will save it in a group called Recipes (which already exists in my implementation of the site), and give it the name of Style Description (the handle is created automatically as styleDescription) and the Field Type of Plain Text.

Now that we have the field created we can then add it to the category group field layout.

Creating the Category Field Layout

Navigate back to the Category Group we created (Settings > Categories).

At the top of the Category Group form, tap/click the Field Layout tab.

Just like we do with Sections in Craft, we can create a Field Layout for a Category Group.

If we don’t define any fields for our Category Group Field Layout, the only field that will be available to us is the Title field. Just having the title field–where you store the name of the category–may be all you need sometimes. But we need to store a little extra information for our beer styles categories via the Style Description field.

Create a new tab under “Design Your Field Layout” and name it “Beer Style.” From the Recipes group below it, drag the Style Description field into the new layout tab.

It should look something like this:

Field Layout for Categories in Craft

At the top of the Control Panel is a new navigation items named Categories. Click on that navigation item and use the New Category button to create some categories for the group.

Alongside each category, you will see the URI for the category, which tells you exactly how someone can access this category on the front end of the website. In fact, you can even click on that URI and Craft will take you to the front-end of the site to preview how the category page will look.

But it won’t work yet! We first have to implement the template so we can see the category pages.

Adding Category Field to an Entry Form

Before we can output our new categories, we need to assign a Beer Style category to existing recipes. There are two steps to do this:

  1. Add a category field to the Recipes Field Layout.
  2. Assign a category to each Recipes entry.

Adding a Category Field

The great part about Craft versus other CMSes is that category fields aren’t special fields. They’re just like any other field, meaning you’re not tied to some pre-defined naming convention or paradigm that harkens back to a day when many of the CMSes were used just for blogging.

Navigate to the Fields area in Settings (Settings > Fields) and select the Recipes group.

Create a new field called “Style” with the Field Type of Categories.

The Categories field type in Craft gives us access to the categories one category group. We select that category group under Source (choose “Beer Styles”).

We’ll input 1 in to the Limit field blank (we want to restrict the field to only allowing one category to be selected) and give the select field a label of “Add Beer Style.”

Adding a category field in Craft

Save that new field and we’re almost there! Next step is to add the new field to the Recipes Field Layout.

Go to Setting > Sections and then tap/click on the Entry Types link at the far end of the row for the Recipes section. Next, click on the Recipes entry type (it should be the only one there). You can also use the upside down triangle to access the entry type directly.

Now we have access to the Field Layout for the Recipes section (and entry type). Drag the new Style field up into the Recipes tab in the layout. Save your changes.

Adding a Style field to assign a category

The final step is to go through each entry in the Recipes section and add a style. Once you’ve done that you are ready to move on to creating the templates and code to display our new categories.

Implementing the Template & Code

To add the categories to the front-end of our site the first thing we need to do is create the template Craft will use to display the category listing page.

In the case of our sample site Craft Brewery, we will have a page that will list all of the recipes for a particular style.

Back when we created the category group, we specified the template recipes/category.html as the location of the template we want Craft to use. Let’s create that now.

In your IDE or code editor, create a new file inside of the recipes directory (if you don’t have the recipes directory, create that, too) called category.html.

Paste in the starter template (get it here, called category-static.html) and let’s bring it to life with some Twig code.

Let’s review the overall structure before we move forward.

At the top of the template, we already have our layout tag, which inherits the base layout for this site. That’s going to give us everything we need to render a styled page.

Because we defined this URI as being a category page, Craft gives us some category data automatically. It’s available to using the category object and we can access its properties (the fields) easily, like this: {{ category.title }}.

We’ll first fill out the h2 for the title:

<h2>{{ category.title }}</h2>

And then add in the description:

<p>{{ category.styleDescription }}</p>

Now we need to populate the table with the brew recipes that are categorized with the style we’re viewing.

To do that we’ll use a for-loop to loop over entries returned by Craft. But in order to make sure we only have entries that are categorized under the current category page, we have to use the relatedTo() method and pass in the category.

{% for entry in craft.entries.section('recipes').relatedTo(category) %}

{% endfor %}

We are requesting from Craft the entries in the Recipes section but limiting it to those that are categorized as the style we’re viewing. We do that by passing category to the relatedTo() method.

Craft returns an array of entries that we then loop over and print out in our table.

We link to the entry using entry.url and print the title using entry.title. All standard stuff for returning entry data in Craft.

    <td><a href="{{ entry.url }}">{{ entry.title }}</a></td>  
    <td>{{ entry.originalBrewDate | date('F Y') }}</td>  
    <td>{%  for category in %}{{ category.title }} {% endfor %}</td>  

Getting and printing the category (the style of brew) is a bit trickier. This is because categories in Craft are a collection (like an array), and even if we only have on category assigned, we have to iterate over that collection to get.

The table cell in the row has another for-loop. It loops over, which contains our collection of categories. We then print the category name out using style.title.

    <td><a href="{{ entry.url }}">{{ entry.title }}</a></td>  
    <td>{{ entry.originalBrewDate | date('F Y') }}</td>  
    <td>{% for style in %}{{ style.title }} {% endfor %}</td>  

An alternative to this is to set to a variable and then iterate over that. There’s no real advantage there other than code clarity.

{% set styles = %}
    <td><a href="{{ entry.url }}">{{ entry.title }}</a></td>  
    <td>{{ entry.originalBrewDate | date('F Y') }}</td>  
    <td>{%  for style in styles %}{{ style.title }} {% endfor %}</td>  

The Twig code is certainly now more readable but not any more functional that what we had before. It’s up to you on how to approach it for your projects.

Having the category listed on a category page is probably redundant and unnecessary but now you know how to output categories, right? Totally worth it.

Okay, I’m getting thirsty, so let’s finish up.

Linking to Category Pages

Speaking of outputting categories, let’s update the other recipe listing to include a link to the category, so visitors can access the category listing page.

We’ll do this on the Recipes page where we list out all of the brewing recipes:

Navigate to the recipes/index.html template in your IDE or code editor.

In the template is the same table markup we just used in the recipes/category.html template. Add a table header column called “Style” and td for the style name right below the brew date cell. Use the same code as before but wrap it in an anchor tag and then link it up.

    <td><a href="{{ entry.url }}">{{ entry.title }}</a></td>  
    <td>{{ entry.originalBrewDate | date('F Y') }}</td>  
    <td>{%  for style in %}<a href="{{ style.url }}">{{ style.title }}</a>{% endfor %}</td>  

We automatically get the URL to the category page via style.url. Add that as the value of the href property and we’re done!

Load the page and you should see the style names linked up for each recipe. Click on the style and you’re brought to the Style (category) page.

Creating a Category Listing

What is missing from our beer styles implementation on Crafty Brewery is a page listing all of the styles, with links of to each style page.

This a practical implementation for visitors of the site. Many home brewers have an idea of which style beer they want to brew and need an easy way to drill down to a particular style.

The page will be similar to the others we created: a table with a list of styles and the descriptions. The new page will be located at This will go nicely with our category page, which is located at:

Here are the steps needed to get that up and running:

  • Create a new template in the recipes template directory called styles.html. Paste in the starter template located at public/recipes.html.
  • Around the sample table row, add a for-loop that iterates over the categories returned from Craft and outputs the title and description.

{% for style in'beerStyles') %}
        <td><a href="{{ style.url }}">{{ style.title }}</a></td>
        <td>{{ style.styleDescription }}</td>
{% endfor %}

To access the categories we use and pass in the group we want to retrieve. In this case it’s beerStyles, which is the handle of the Beer Styles category group we created earlier.

We iterate over the return object, and for each category returned we print out the URL, title, and description.

The result is a two-column table that lists the available styles and then a link (by clicking on the title) to access the individual style page, which is the category page we set up earlier.

With this final addition our category work for Crafty Brewery is complete.

Sit back, take a sip, and admire your work.

Get the Video of this Tutorial

A video version of this tutorial is available as part of the Learning Craft course.

It’s more than 3 hours of training over 11 videos. When you go through the course you learn everything you need to know to get started building websites with Craft–for yourself or for your clients. It’s an investment that will pay for itself over and over again.

Get Immediate Access

Ryan on ALA: On Air Panel

by Ryan Irelan

This coming Tuesday, August 25, 2015, I will be on the ALA: On Air panel all about content management systems.

CMSes help and hinder; they inspire rapture and incite table-flipping. I’m thrilled to moderate the next ALA: On Air event, where Karen McGrane, Jeff Eaton, and Ryan Irelan will join me to discuss what they love about working in CMSes (administrative UX!), what drives them to frustration (decoupling!), and what meaty problems (integration with design systems!) they hope to dive into next.

The panel will cover a handful of topics, including decoupling systems and headless CMSes.

If you work with CMSes at all, this is the must see panel. It’s free, online, and if I do my job, fun and informative.

Learn more about the event and then register to attend.

See you there!

Craft Plugins in Craft 3

by Ryan Irelan

Ben Croker, the author of Craft Plugin Development, recorded a free bonus update to his course. The update covers some initial considerations for making your plugin Craft 3 compatible.

First, a side note: Craft 3 is in developer preview and still a ways off. You don’t need to build or ship Craft 3 plugins just yet.

In the short video Ben walks through the changes he needs to make to the Entry Count plugin (that’s the plugin he builds in the course) so it will work with Craft 3.

If you already purchased the course then this bonus video will appear in your Course Library inside the Craft Plugin Development course.

But we also wanted to make the video available for everyone. Here it is:

Ready to develop your first Craft plugin?

Ben’s Craft Plugin Development course is 90+ minutes, broken up into several videos for easier learning and reference. Ben will get you from not knowing how to develop plugins to having your first plugin done and working!

Get Immediate Access

Learn Craft’s Matrix Field

by Ryan Irelan

The Learning Craft course now has new videos covering the Matrix field type.

I broke the new tutorial up into 7 short videos so you can easily reference back to just the topic you want (like coding templates for Matrix or using the switch tag).

If you already purchased the course then you’ll have the videos in your Course Library as part of the course.

Inspiration for Your First Craft Plugin

by Ryan Irelan

This is a part of an interview with Craft Plugin Development author Ben Croker. Ben had a lot of great stuff to share; this is the third part. Read Part 1 and Part 2.

Can you recommend a couple existing Craft plugins that someone could look at to get inspired as to what’s possible?

For a beautiful UI and wonderful use of dashboard widgets take a look at Dukt’s Analytics plugin.

For a feature packed maps plugin check out Smart Map by Double Secret Agency.

For a solution to simple payments in Craft check out Charge by SquareBit.

For a plugin that you can learn plugin development from, check out the free Entry Count plugin that accompanies the Craft Plugin Development video course.

You can find a full list of Craft plugins on StraightUpCraft.

Is anyone creating plugins to sell?

Yes, there are many commercial plugins already available, including two of my own. Here are just a few sites that are selling plugins:

Ready to develop your first Craft plugin?

Ben’s Craft Plugin Development course is 90+ minutes, broken up into several videos for easier learning and reference. Ben will get you from not knowing how to develop plugins to having your first plugin done and working!

Get Immediate Access

3 Things to Know About Craft Plugin Development

by Ryan Irelan

This is a part of an interview with Craft Plugin Development author Ben Croker. Ben had a lot of great stuff to share; this is the second part. Read Part 1 on getting started with Craft plugin development.

What are three things someone starting out with Craft plugin development should know?

Ben Croker: Plugins in Craft can be very, very simple. Literally, with a single file and several lines of code you can create a plugin that actually does something. Obviously things can get much more complex, but with a little knowledge you can certainly go a long way!!

Mastery is a journey. When I first started plugin development in Craft there were no docs. I ripped open the core and learned through persistence. And I am still learning. Come at this from a place of curiosity and experimentation and you will come a long way!!

You are not alone. There are many other people out there who are learning Craft plugin development, as well as many who are already building their own plugins. Get involved in the Craft Slack Group and use them, in my experience they are all very welcoming and happy to help.

Ready to develop your first Craft plugin?

Ben’s Craft Plugin Development course is 90+ minutes, broken up into several videos for easier learning and reference. Ben will get you from not knowing how to develop plugins to having your first plugin done and working!

Get Immediate Access

Getting Started with Craft Plugin Development with Ben Croker

by Ryan Irelan

This is a part of an interview with Craft Plugin Development author Ben Croker. Ben had a lot of great stuff to share; this is the first part.

What made you learn Craft plugin development?

Ben Croker: By nature I’m someone who likes to tinker with things and figure out how they work. That’s why I can often be found in my garage replacing parts on my motorcycle or tweaking my bicycle.

When Pixel & Tonic first released Craft (initially codenamed “Blocks”) I was very keen to take a look at the UI and the underlying code and I absolutely loved what I saw. It was obvious that they had put a huge amount of thought into building the CMS they wish they had had when they were developing their ExpressionEngine add-ons.

What resulted was a purely content focused CMS with a gorgeously minimalistic UI, as well as a framework for plugin development. Once I saw what this framework looked like and what I could do with it, I was hooked (excuse the pun).

Craft is built on the Yii framework. If I want to create a plugin, how much Yii do I need to know?

BC: You don’t need any knowledge or experience of Yii to create a plugin, although by developing plugins in Craft you will be inadvertently learning Yii’s coding conventions. As you start working with ActiveRecord and the database you’ll want to do some reading up on Yii’s docs, but it is certainly not a prerequisite.

How easy will it be to update plugins based on the changes in future versions of Craft?

BC: Craft 3 is bringing some changes to how plugins will work, however the update process for plugin developers is very simple and I am actually working on a bonus video that will cover this. There is already some documentation on how to do this as well as a recording of Brandon Kelly’s workshop at Peers 2015.

Thanks, Ben!

We’ll have two more installments of this interview coming in the next couple of days.

Ready to develop your first Craft plugin?

Ben’s Craft Plugin Development course is 90+ minutes, broken up into several videos for easier learning and reference. Ben will get you from not knowing how to develop Craft plugins to having your first plugin done and working!

Get Immediate Access

Learn Craft Plugin Development

by Ryan Irelan

In our new course, Craft Plugin Development, Ben Croker will guide you step-by-step toward building your first Craft plugin.

The course is broken up into small, absorbable chunks so you can learn in small increments and easily reference the material later. You’ll pull this course off the shelf from time to time to help you work through a problem during plugin development.

Here’s a preview of what’s covered:

As new versions of Craft come out, you will get free resources to help you update your plugin.

Ready to learn Craft plugin development? Get immediate access to the course.

Using Variables in Twig and Craft CMS

by Ryan Irelan

Twig allows us to set variables in our templates so we can repeatedly output a value without calling another method. It also helps make our templates cleaner because a variable can be a shorthand way to reference a value.

There are a few different ways to create and assign values to variables, and they all use the set tag.

The simplest way is like this:

{% set title = "About Happy Lager" %}

by defining the variable name using the set tag and then assigning a value (in this case a string).

This variable can now be used throughout the template using the double curly braces syntax:

{{ title }}

If we had multiple variables to set at once–perhaps some metadata for the page that we wanted to use in multiple places–we can do that by separating both the variables names and their values by commas.

Here’s a simple example:

{% set title, subtitle, description = 'About Happy Lager', 'The history behind the company.', 'Learn more about the history of the this mobile design and development agency.' %}

Each of those variables would then be available in the template, using the double curly brace syntax:

{% set title, subtitle, description = 'About Happy Lager', 'The history behind the company.', 'Learn more about the history of this mobile design and development agency.' %}

  <title>{{ title }}</title>
  <meta name="description" content="{{ description }}">
  <h1>{{ title }}</h1>
  <h2>{{ subtitle }}</h2>
  <p class="description">{{ description }}</p>

One last way of setting variables in Twig also uses the set tag but instead of as a single tag, we use it as a tag pair. Using it as a tag pair allows us to capture a block of text or code and assign it to the variable. This is handy for assigning a chunk of markup and content to a variable.

{% set description_formatted %}
    <p class="description>Learn more about the history of this mobile design company.</p>
{% endset %}

And that is the basic usage of variables in Twig and Craft CMS.

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

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 %}
    {% 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 %}

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 %}

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: "" },
    facebook: { name: "Facebook", url: "" },
    instagram: { name: "Instagram", url: "" }

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="{{ | lower }}"><a href="{{ network.url }}">{{ }}</a></li>
    {% endfor %}
{% 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="">Twitter</a></li>
    <li class="facebook"><a href="">Facebook</a></li>
    <li class="instagram"><a href="">Instagram</a></li>

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

Key Value Arrays in Twig

by Ryan Irelan

Twig doesn’t refer to a key, value array as an array. It calls it a hash.

A hash is one of several types of literals available in Twig. It has a key and a value. The pairs are separated by a comma and enclosed in curly braces.

{ key: value, key: value } 

Here’s a hash with some information about a page:

{ title: 'About', subtitle: 'About Mijingo', slug: 'about' }

Let’s assign this hash to a Twig variable using the set tag.

{% set page = { title: 'About', 
                subtitle: 'About Mijingo', 
                slug: 'about' } 

To get the values out of the hash and output them to the template, we use the following syntax:

{{ variable_name.key }}

To get the title from the hash we assigned to the page variable, we use:

{{ page.title }}

This would output:


This example has the key as a name but the key could be a string, integer, or expression.

Hashes can also be nested. Here’s a good example from the Craft sample site Happy Lager (provided by Pixel & Tonic for everyone to use and explore):

{% set nav = {
    about:    { title: "The Brewery", desc: "About Us" },
    services: { title: "How It’s Made", desc: "Services" },
    work:     { title: "What’s On Tap", desc: "Our Work" },
    news:     { title: "Brew News", desc: "The Latest" }
} %}

We’re setting the nav variable to a nested hash. To access an individual value, we use the dot syntax again:

{{ nav.about.title }}

To iterate over the hashes in the nav variable, we use a for-loop (while adding in a little markup):

    {% for item in nav %}
        <li>{{ item.title }}</li>
    {% endfor %}

To add in the hash key as the slug for the URL, we use the for-loop again and the key,value pattern to access both the keys and the values.

We iterate over it like this (look at the Happy Lager base layout template for an example of this):

    {% for slug, item in nav %}
        <li><a href="/{{ slug }}">{{ item.title }}</a></li>
    {% endfor %}

I’ll dig through more of the Happy Lager site again soon and highlight more examples of how Twig works.

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

Brief Overview of Craft Routing to Templates

by Ryan Irelan

How does Craft know which template to render when? It all starts and ends with Craft’s request routing.

The Craft documentation for Routing starts us off perfectly:

When a request comes in, Craft goes through several checks when determining where to route the request.

Craft does a routing check sequence that every request goes through so it ends up at the right place, delivering the right page or asset.

Pull up the routing documentation page and let’s talk through it.

The first three checks in the routing sequence:

  • “Should Craft handle this request in the first place?”
  • “Is it a resource request?”
  • “Is it an action request?”

cover whether Craft should take the request at all (sometimes it’s not necessary), if it’s a request for a Craft-managed resource, or if it’s an action request (like submitting a form or other actions from third-party plugins).

The fourth check is if the request is for an entry or category page. If there is a URI match then Craft will load the proper template (the one you specified when setting up the category or section).

The fifth check is if the request matches any Dynamic Routes you set up in the Craft control panel. Dynamic routes are hugely powerful in allowing you to create custom URIs that don’t necessarily match the template path. This saves you from having to conceive an unusual template directory and file naming scheme just to get the URLs to be how you want. If there is a match then Craft will render the template specified in the matching Dynamic Route.

The second-to-last check in the sequence to see if the request URI matches a template. If the URI is a valid template path (directory + template), then Craft will render that template.

This is a literal routing of the URI to the template.

If you have a request for template offices/austin.html and Craft goes through its checks and doesn’t find a match before it gets to the template check then it will render the offices/austin.html template. If you had an entry with that URI then it would render the entry instead (using whichever section entry template you specified).

At the end of the check sequence, if there are no matches, Craft will return a 404 error. If you don’t have a custom 404 template, Craft will render the default view. To create a custom 404 template, add a 404.html template file in the root of your craft/templates directory and Craft will use it.

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

Three Twig Tag Types in Craft CMS Explained

by Ryan Irelan

Templating in Craft using Twig can, at first, be a little confusing. If you, like me, come from other systems that have a proprietary template tag system, then it might take a little time to wrap your head around how Craft and Twig work.

But once we learn about the different types of tags things will be clearer and you’ll discover the power of using Twig in Craft. This tutorial will give you the direction and guidance you need to get started.

Let’s jump right in.

There are three tag types in Twig and Craft:

  • Statement/Logic Tags
  • Output Tags
  • Comment Tags

You will always use the first two in your Craft templates. The third, comment tags, are optional but a handy way of documenting anything that isn’t obvious by reading the code.

Statement/Logic Tags

Statement or logic tags use the curly brace plus percent sign delimiter. In Twig and Craft they can come in multiple forms.

Some are just a single tag, like this Craft-specific Twig tag:

{% requireLogin %}

which you would put at the top of a template in Craft to require a logged-in state. If a visitor is not logged in than Craft will automatically redirect them to the log-in page.

Other logic tags take parameters, like the redirect tag in Craft:

{% redirect "about/tos" %}

The redirect tag takes one parameter, which is the URL or path to where you want to redirect the visitor. This is a tag specific to Craft but there are some Twig tags you should know, too.

Another type of tag is one that has an opening and closing tag, like the for tag in Craft.

{% for %}
{% endfor %}

The tag pairs have an opening tag and a closing tag. The closing tag will typically have an “end” prefix, like endfor, endpaginate, and endblock.

Even the set tag we use to set a variable can be used as a tag pair. The simple version looks like this:

{% set author = "Ryan Irelan" %}

But using a tag pair for set, you can assign a block of text to a variable. Here we’re setting the variable socialLinks to an unordered list of social network links:

{% set socialLinks %}
<ul class="social">
    <li class="twitter"><a href="">Twitter</a></li>
    <li class="facebook"><a href="">Facebook</a></li>
    <li class="googleplus"><a href="">Google+</a></li>
{% endset %}

Another example of a tag pair–and by far your most used tag while writing Twig template code for Craft–is the for-loop. It’s how you will loop through and display section entries in your templates and output other lists, like categories.

This is a for-loop to display content from an array of blog posts:

{% for entry in craft.entries.section('blog') %}
    {{ entry.body }}
{% endfor %}

It uses the curly brace plus percent sign delimiter for both the opening and closing tags of the for-loop. This delimiter tells Twig that what’s between needs to be executed as a statement (in this case a for-loop).

Output Tags

The code with the double curly braces are output tags. They print variable contents to the screen (i.e. output content in your template).

{{ author }}

The author variable would output my name (because we set it in the previous example).

If you want to use an output tag to pass in data to another tag, like when we set a variable in Twig, then you don’t need to use the double curly braces.

{% set name = author %}

If we printed out the value of the name variable we just set than it would render:

Ryan Irelan

But output tags can generate the output on the fly and then print it to the screen. How about a little math?

{{ 4 * 4 }}

This output tag will do the multiplication of 4 and 4 and print out the product. I’m unsure how practical it is to do math like this in the template but there you have it.

The Twig documentation calls out that the curly braces are not part of the variable itself but instead an indicator that the value of the variable contained within should printed to the screen.

Comment Tags

This tag type is straight-forward but perfect for adding comments to your templates but not have those comments render in the page source like HTML comments would.

{# Begin logic for sidebar #}

Using a single opening curly brace paired with a pound sign, we can create the un-rendered comments. They’ll always be available in your template file but never rendered by Twig.

Any code that is inside the comment tag will not be executed by Twig.

{# removing this for now to debug
    {% for entry in entries %}
        {{ entry.body }}
    {% endfor %}

There’s a lot more to templating with Twig in Craft but this introduction to three different tags will get you set off in the right direction.

Don’t miss my new course on Craft + Twig

Coming soon is a brand new video course on Twig & Craft that will help you grasp what Twig is, how Craft and Twig work together, and some templating best practices. Sign up below to get notified when the course is ready!

Ready to learn more about Craft?

If you want to learn more right now about Craft, I have a popular 2 ½ hour video course that will get you started on the right path.

Get the Craft video course

Previous Page  

What are our customers saying?

"Just purchased your Flexible Twig course. Love it!"
Tyler Morrison
"Been enjoying @mijingo 's Learning Craft video tutorials. Feeling like I've got a good basic understanding of #craftcms Very impressive"
Laura Montgomery
"I bought your Craft Starter Pack a year and a half ago. Worth every dollar. In fact, I would've paid twice as much for it, because you saved me so much time."
Timothy Ingram
"Ben's knowledge of Craft combined with his relaxed and informal teaching style makes for a great learning experience."
Steve Abraham
"Ben puts a lot of thought into his teaching approach and has the ability to explain complex concepts in a way that just make sense"
Gareth Redfern
"Ben is great at taking a complex subject and breaking it down in a way that you can wrap your mind around. I thought that plugin development was something I would never understand, and happily Ben proved me wrong!"
Jonathan Melville
"I really appreciate all the videos and writing you have done. Your work has given me a jump start on my front end development business."
Shan Ricciardi

Perfect for Small Teams & Companies

Mijingo's courses are perfect as the training curriculum for both small teams and entire companies.

Our courses are offered in Team Packs (up to 5 people) and Company Packs (up to 25 people), so you can make one simple, fast purchase to train your entire staff.

Prices are listed with each course. Need more than 25 or something custom?

Send Your Requirements
Team Pack2-5 People
Company Pack6-25 People
Custom Pack25+ People