whateverthing.com

Portfolio and Technology Blog
by Kevin Boyd

Excerpts, Summaries, and Breakpoints in Sculpin

... and some Twig tips, too.

One feature that bloggers like is the ability to add an "excerpt" or automatically cut off text after a certain number of words. This is often used in RSS feeds as a sneaky way to increase hits, or more legitimately as a consistent way to place a "Read More »" link in listings of posts.

I'm going to demonstrate three methods for doing this, because each of the three methods reveals something useful about Sculpin and its templating system, Twig.

What are Sculpin and Twig?

Sculpin is a Static Site Generation tool, like Jekyll or Octopress. It's written in PHP using the Symfony components, and I'm a big fan. I currently run three sites that use Sculpin as the back-end: Whateverthing.com, WTBoard.com, and the Gibson Index. The basic premise of a Static Site is that you build the site layout (or install a theme) and then use efficient text files to store your blog posts. Then, everything is compiled together, rendered down to raw HTML/CSS/JavaScript/Images, and uploaded to your host of choice. The host can be a full server or even just a file storage service like Amazon's Simple Storage Service (S3). The basic requirements are very easy to satisfy, and the end result is a server that is safer and easier to maintain.

Twig is a PHP-based templating engine, like Smarty or Jinja. Twig's sandboxed templating is a nice safety net to prevent intermingling of business logic and output. The syntax is also very easy to work with. Twig allows for advanced techniques like macros, inheritance, and Edge Side Includes (for caching small, reused chunks of web pages). The Twig parser actually compiles the templates down to PHP classes so they can be cached in APC (or other opcode caches) for faster page loads. Of course, most of that isn't a concern for Static websites - but it's a good refresher for the following tips.

Excerpts (Sculpin-only)

Excerpts can be inefficient, but they are also the most customizable method, because the excerpt is allowed to differ from the post itself. This enables the author to create a proper summary if they so choose, which can entice more readers to check out the full post. The lack of efficiency comes when the excerpt matches the first paragraph or two exactly; then, you're just repeating yourself. This happens often on the Gibson Index. :)

The first step is, when creating a new post, add a line to the YML "front matter". Example:

---
layout: post
title: ERMAGHERD I MAED A BLERG PERST
excerpt: ERMAGHERD GERSEBERMPS!
---
Four score and five XBoxes ago ...

Then, in sections of the Sculpin templates where articles are looped through (homepage, RSS feeds) instead of outputting {{post.blocks.content|raw}} you change it to output {{post.meta.excerpt}}. Easy as pie.

One caveat is that you might want to check if post.meta.excerpt is defined before you try accessing it. For instructions on how to use if statements in Twig templates, check out the documentation.

Summaries (Sculpin and Twig)

This method is not a true summary, nor is it a MS Word style autosummary. Nope, this is just a fancy truncation. First, we can truncate by character count. In this example, let's terminate the output at 140 characters with HTML formatting removed:

{{ post.blocks.content|raw|striptags|slice(0,140) }}

You can also write it as:

{{ post.blocks.content|raw|striptags[:140] }}

Alternatively, you could split it into an array of words and output the first X words (this would likely look nicer to the end user):

{% set summary_array = 
    post.blocks.content
      |raw
      |striptags
      |split(' ') 
%}
{{ summary_array|slice(0,50)|join(' ') }}...
<p>
    <a href="{{ site.url }}{{ post.url }}">
        Read more of this post &raquo;
    </a>
</p>

This chunk of code breaks the post content into an array of individual words, then outputs the first 50 elements of that array joined by spaces. It trails off with an ellipsis and provides a useful "Read More" link for the reader.

The cutoff for this sort of summary is rather abrupt, so it may not be entirely desirable for your blog. You might want to adapt the concept to split on '. ', so that you can string sentences together for a more natural summary.

Breakpoints (Sculpin and Twig)

The final method borrows some ideas from both the Excerpt method and the Summary method. Breakpoints are special strings of text supported by many blog platforms or plugins, and they allow the author to specify a cutoff point for summaries directly in the post itself.

For this example, our breakpoint will look like this: <!-- break -->

The code to analyze the breakpoint will look like this:

{# Split the post into an array using explode(). 
   Because we provide a length of 2, the "rest" 
   of the post will be stored in the second array 
   element, even if there are multiple breakpoints. #}
{% set break_array = 
    post.blocks.content|split('<!-- break -->', 2) %}

{# Output the first element of the array in raw mode #}
{{ break_array[0]|raw }}

{# Detect if there is more to the post. If the post 
   was only one array element with no breakpoints, 
   it would all have shown up. This Read More link should 
   only show up if there is overflow to the post. #}
{% if break_array|length > 1 %}
    <p><a href="{{ site.url }}{{ post.url }}">
        Read more of this post &raquo;
    </a></p>
{% endif %}

Put that into your index.html, and it should work right away.

This version does have one quirk - by default, the text we use as a breakpoint will show up in the "full" view. This is why I went with an HTML comment; it will only be visible if users click "View Source". Of course, if you are concerned about this, you can modify the regular post output to strip out the breakpoint text.

I hope you find these Sculpin and Twig tips useful. Please remember to subscribe to the newsletter to receive updates, tips, and information about new projects of mine.

Thanks for checking in!

Published: June 18, 2013

Categories: coding

Tags: coding, sculpin, twig

comments powered by Disqus