Structuring a jekyll theme
How to plan for and use a structure for your theme
Index file *
This is the starting point of your site or blog. There's not much to talk about for this page. The page itself shouldn't contain much aside from some YAML front matter.
---
title: Home
layout: index
---
Everything that you see on, for example my landing page isn't generated in \index.html
. Rather, it's generated in _layouts\index.html
. This separation of content
from layouts is very similar to what you might see in a MVC-oriented framework.
Additionally, actual content isn't output in our layout either. The layout only determines in which, and in what order, layouts should be included.
{% include header.html %}
{% include index.html %}
{% include footer.html %}
There's 3 includes to take note of here:
header.html
Contains the header element and everything associated with this. Also starts thehtml
andbody
elements.footer.html
Pulls in any javascript and finishes thehtml
andbody
elements.index.html
Generates and output content.
The index
include isn't very big and should be more or less self-explanatory
{% assign link = true %}
{% for post in site.posts %}
<article>
{% include preview.html %}
</article>
{% endfor %}
All it does is enumerate the last 10 posts on the site and includes preview.html
, which expects a variable named post
to be set and assigned a post object.
preview.html
is very simple:
<h1>
{% if link %}
<a href="{{ post.url }}" title="{{ post.title }}">{{ post.title }}</a>
{% else %}
{{ post.title }}
{% endif %}
</h1>
<p>
{{ post.summary }}
</p>
And finally, this is where things are output and actually rendered. Setting a variable named link
to anything but false
or null
will render the h1
-element as a link.
The reason why I pulled out preview.html
instead of writing the markup directly in the post-loop in (the include) index.html
is because I want my theme to be as modular and
atomic as possible.
Anytime I want a preview (wherever that might be) I can just assign a variable named post
with the correct data and {% include preview.html %}
and it should work OOB.
Posts *
The structure and flow for rendering of single post pages isn't much different.
Probably the biggest difference is the entry point to the layout. In any post I want rendered with the post
layout, I use
---
...
layout: post
---
Now, in the layout post.html
there's 3 files included
{% include header.html %}
{% include post.html %}
{% include footer.html %}
The first and last are included in every layout for obvious reasons, the middle one though is different:
<article>
{% assign post = page %}
{% include preview.html %}
{{ content }}
</article>
Here you see why I pulled out preview.html
as a separate module.
Since preview.html
requires a post
variable assigned a post object, we assign post
to page
(which is the current post object).
Finally, since we don't assign anything to link
, we won't get our h1
as a link.
Conclusion *
This work, together with learning the syntax of liquid, took me about a day in effective time. As far as I'm concerned, that's very, very little time for setting up a whole site, even a static one.
This post is one in a series of posts on building a site with Jekyll. These are the articles I have written so far, in no particular order: