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

Filed Under: Craft CMS