Tour of a theme

This article will take a tour of a Chyrp Lite theme, to help you understand the things you'll need to know before developing a theme of your own or customising an existing theme. For this article, we will be taking a tour of Blossom, the default theme for Chyrp Lite. Many of the elements we will encounter are common to all Chyrp Lite themes.


If you're making a theme, you need twigs. Twigs are text files filled mostly with HTML but also with some instructions for Chyrp Lite to follow, so that the twig can tell Chyrp Lite what to do with it. When someone visits your website, Chyrp Lite will build a web page by combining twigs together in various ways.

You can think of a twig as a fragment of a web page, just like a twig in real life is a fragment of a tree. The final product of every twig will be a piece of the page to be served to the visitor. When you view a twig, bear that in mind: nothing but the HTML will remain in the final web page served to the visitor.

The Tour

Download the latest release of Chyrp Lite and expand the zip archive. Now take a look inside the expanded chyrp-lite/themes/blossom/ folder. We're going to take a tour of the key elements in here.


The first twig we'll look at is default.twig in the layouts directory. Open the file in your favourite text editor. If you have a text editor with syntax highlighting, switching it to HTML mode will make it a lot easier to inspect twigs.

default.twig is different from most twigs: the contents of this twig look almost like a normal web page with a head and a body. That's because default.twig is the basis for all the other twigs, like the trunk of a tree. No matter what page a user visits on your website, default.twig will be used as the basis to build it.

Amongst the <head> and <body> tags and the other things you'd expect to see in a HTML file, you'll see strange bits of syntax that aren't markup. These are the instructions – otherwise known as statements – that allow twigs to make choices and give orders. Anything you see between a {% %} is a statement for the template engine to follow.

Perhaps the most important statement is {% block content %} {% endblock %} which tells the template engine “whatever other twigs you add to this one, add them at this location in the page.” Depending on what page the user has asked to see, this content block might be filled with a bunch of blog posts, or just one, or a login form.

You'll also see conditional statements: {% if this %} {% else %} {% endif %}. If you've ever dealt with JavaScript , you'll understand what's going on here. The twig is telling the template engine to use different markup under different circumstances, for example the twig might choose to add some admin controls to the page if the visitor is logged in and has admin privileges.

The other oddity you'll see repeated in twigs is text inside a set of double curly brackets like this: {{ }}. These are variables that will result in the template engine replacing this bit of text with a corresponding value. For example, {{ theme.stylesheets() }} will be replaced with a set of <link> tags to the theme's stylesheets, and {{ "Search" | translate }} will be replaced with the word “Search” possibly translated into another language if a translation file is available.


You'll be seeing this twig a lot on your site – it's the twig that outputs the basic markup that surrounds all blog posts. The obvious choice with post.twig is to have it output an <article> element to contain each of your blog posts, so that you can easily arrange and style your posts using a stylesheet – and that's exactly what Blossom does.

A few lines into the twig, you'll see something familiar: {% block content %}. What's going on here? Content blocks can be nested, so default.twig tells Chyrp Lite where in the page to insert the next twig, and that next twig might be post.twig, in which case post.twig adds a few elements of its own to the page and also provides a place for the next twig to be inserted. That next twig will be different depending on the kind of post this is: text, photo, etc.

After the content block, this twig adds some metadata that are useful for any type of post: the date of the post, the tags, categories, and comments associated with it, and buttons to edit or delete the post. Remember what we learned about conditional statements when we looked at default.twig? Look closely at post.twig and you'll see a lot of conditional statements, displaying comments only if the commenting module of Chyrp Lite is enabled, displaying the edit and delete buttons only if the user viewing the page has the rights to perform these actions, and so on.

If you're building a custom theme just for your own use and you don't want some of these features, don't include them – it's that simple. You can rearrange, add, remove, and customise the appearance of your blog as much as you like.


Let's suppose a visitor to your site lands on the index page of your blog. The template engine will fill the page with several instances of post.twig (how many posts are displayed depends on your administration settings). We've seen that post.twig reserves a content block for the blog post but itself doesn't display blog posts, so what twig is responsible for that task? Well, if your post is plain text then text.twig is responsible.

text.twig is a special kind of twig that allows the template engine to render different types of content in your blog posts. Each twig in this folder corresponds to a Chyrp Lite feather: an extension that enables Chyrp Lite to support different content types in blog posts. Take a look in the feathers directory and you'll see the names of several other twigs dedicated to certain types of content – photos, quotes, links, and so on. The simplest kind of blog post is plain text, and that's what text.twig is here to display. First of all, this twig declares which twig it's here to extend with an extends statement. Then we get down to business. Plain text is so simple that text.twig is very simple too. It adds a title element to the page if one exists, and it tells Chyrp Lite where to insert the content of the post using the variable {{ post.body }}.

We won't cover the other feathers, but you should take a look at them now. Next up, we'll check out some forms.


This twig displays a form that allows visitors to your blog to log in, if they are registered users. Even if your blog doesn't allow users to register you'll still see this form every time you log in to write a post.

Firstly login.twig declares it's here to extend layouts/default.twig. This means any HTML this twig outputs will be inserted in default.twig's content block. The rest of the twig is a fairly straightforward HTML form with just a few variables such as {{ url('login') }} that will be replaced with the correct URL for logging in, and some translation filters such as {{ "Username" | translate }}. You will see translation filters quite often as we continue our tour of the Blossom theme.


The pages directory contains many twigs of a type distinctly different from feathers and forms. All these twigs are templates that extend default.twig for different route actions. What is a route action? If a visitor lands on the index page of your blog – that's one route action. After the index page, perhaps the most commonly seen action is the "permalink" or "view" context; this is a page that displays just one particular blog post in isolation, and view.twig is responsible for that context.

Firstly view.twig announces that it's here to extend default.twig then it gets started adding content to the page. If the blog post being viewed has other posts before and after it chronologically, the twig adds links to them.

Next we have something new: include. Actually, if you had been looking closely you would have seen something similar in default.twig. This is an include statement, and default.twig uses one to add a sidebar to the page. The include statement is similar to block but it's used in situations where the twig knows exactly what content it wants to add to the page, similar to a CSS @import rule that injects one stylesheet into another. A block says: “if you've got something to add, add it here.” An include says: “I want this specific thing injected into the page here.”

In this case the twig is telling Chyrp Lite to inject the suitable twig for the feather type of the blog post the visitor is viewing. For a text post that means text.twig, and because text.twig extends post.twig that means post.twig is coming along as well. What we'll end up with in the rendered page is a nest of twigs, each adding its own little bit of content to the page:

After the include statement, view.twig adds some content to the page only if Chyrp Lite's commenting module is enabled.


This is your blog's index, a very simple twig that fills the page with blog posts. The index is what visitors will see when they arrive at your blog. The number of posts on the page is controlled in the administration console, and if there is more than one page of posts, default.twig will add hyperlinks to the next and previous pages of the index (if applicable). If your blog is configured to display 4 blog posts per page, your page will be constructed as follows:


This twig displays the results of a search. If your blog has a search bar, this is the page where visitors will come to view the search results. A for loop iterates through the search results and includes the appropriate twig for each blog post. It also displays a summary of any pages returned by the search.

Further Reading

Here our tour ends. You haven't seen everything that's needed to build a Chyrp Lite theme, but you've seen enough to figure out the rest on your own. If you want more technical detail about themes, read the article Anatomy of a Theme and if you want to learn more about Twig read the Twig Reference.