Building the site (part 1)

June 12, 2012 16:41

Part 1: Using Jekyll and Liquid

As I’ve mentioned before, when redoing the site I wanted to use a system simple enough that I could understand it and modify it if necessary to do exactly what I need. I chose Jekyll.

At a future time I might go with something that gives some more standard features or is easier to set up. Just having the understanding after going through the design process gives me some insight into what I might want to do myself of have handled by the system. Even just taking Jekyll as a starting point, there’s Octopress, which adds a number of features and templates.

But for now I’ve got a set-up and design that I like, and that works. Getting Jekyll working wasn’t too hard. Here’s what I had to do.

Structuring the Site

The structure I wanted for the articles was the typical roll of recent posts, starting at the top and going back in time down the page. But I also wanted to be able to group some posts if they belong to a project or a specific set. I didn’t need ‘tags’ (multiple pieces of metadata per post) as such. I rarely use tags myself on other sites, since searching generally gets the job done. But if I do have a particular project, I wanted there to be some way to just go through that set. Finally, I also wanted a useful index and a single page for a post.

The roll of all articles is easy enough to do. All properly named files in the _posts directory become Jekyll’s posts array, sorted by date by default. Putting just recent ones on the front page is as simple as throwing in a limited for loop.

{% for post in site.posts limit:8 %}
    {% assign topic = post.category %}
        {{ post.content }}
            {% if topic %}...More in {{ topic }}...{% endif %}    
{% endfor %}

Marking the project topic wasn’t that hard either. Assigning a category in the post’s YAML front matter makes it available as a variable (i.e. post.category). The existence test (‘if topic’) only inserts the topic name if it has one.

Making the index was fairly easy as well. Using the variable ‘category’ is useful since Jekyll has support for filtering this variable. It’s intended to be used for tags, but there’s no problem with having just one category for a post.

The articles are listed with the date, title, and the blurb. This defaults to just the first couple lines of text, but it could be defined in the Front Matter for posts that need it. The method of trimming the lines isn’t so great, but it works well enough.

{% for post in site.categories[topic] %}
            {% assign number_of_articles = forloop.length %}
            {% if post.category == page.topic %}
            {% if post.blurb %}
                         {% assign blurb = post.blurb %}
                    {% else %}
                         {% capture blurb %}
                            {{ post.content | strip_html | truncate: 300 }}
                         {% endcapture %}

Note: I eventually changed this to use tags instead of categories. Categories serve a similar purpose but are meant as a way to reflect the internal directory organization in urls. In order to maintain uniformity of the urls categories get automatically downcased, and that would restrict the way I could name my topics. Tags aren’t treated in any special way, so it’s smarter for me to use them instead.

A New Liquid Tag

There was one more thing I wanted to add. The ‘Topics’ page, which provides an index of all the categories. For each topic I wanted to give a short description with a link, similar to the article blurbs. The topic index page itself already has the long description. Just truncating that wouldn’t really do. I wanted to avoid adding a plug-in to Jekyll if I could do it all with templates.

I might have done that with a set of includes (one for each topic). This would require creating and maintaining two separate files per topic. Instead I ended up with a plug-in — creating a new Liquid tag. It’s called “page_lookup”. What this does is read a variable that’s defined on another page. The URL of the other page and the variable name is given. Here’s how it’s used on the topics page:

{% for category in site.categories %}
    {% cycle 'new row': '<div class="grid-display-row">', nil, nil %}
    {% assign topic = category.first %}
    {% capture topic_url %}/topics/{{ topic | downcase | cgi_escape }}.html{% endcapture %}
        {% page_lookup  topic_url var:description %}
     {% cycle 'end row': nil, nil, '</div>' %}
{% endfor %}
{% cycle 'end row': nil, '</div>', '</div>' %}

The ‘description’ is defined in the YAML Front Matter for the topic index. Thus all the details for one project’s topic are in one file.

You can also see how using the ‘categories’ variable makes this easier to work with. Only the topics that actually have posts will be included in this index. There’s no need to do anything other than create the topic’s index page, which can even be created in advance of any posts for it. Those index pages are simple, as they contain nothing more than the short and long description of the topic. The layout template handles the rest.

page_lookup returns nothing if it fails, so the index page at least doesn’t mess up if I reference a topic that doesn’t have an index page. The topic will be named and given a blank description. Though of course the link will be bad.

This page uses the cycle tag to keep the rows formatted correctly as well. Every three topics is on a new row, and the ‘end row’ cycle closes it out evenly no matter how many are left on a line. Assigning a name to the cycle lets it be referenced later, which is what makes the final ‘end row’ cycle work : it only closes the div tag if the last entry was number one or two on the row. Otherwise it’s closed within the normal loop. This excerpt is practically the whole of the topic index page.

The rest of the site is fairly simple, building on a few basic layouts inside another very basic HTML layout. As of now the Photos page uses Rhotoalbum for its layout and styling, but I hope to make a change to that in the future.

That’s all for the dive into Jekyll and Liquid. Next time, I’ll talk about migrating from Textpattern and getting the site up and running.