Sculpin Extended: Customizing Your Static Site Blog

If you’re a PHP developer and currently running a blog with a static site generator such as Octopress or Jekyll, wouldn’t it be great if you could use your primary language for it? Yes, it’s healthy for us developers to use more than one language, but let’s be honest – we often want to add some functionality to our blogs, but it’s difficult to accomplish in unfamiliar syntax. In this article, we’ll set up Sculpin, a static site generator for PHP. Just like any other static site generator, it uses markdown files and HTML templates to generate your blog, so the transition should be easy.

Installing Sculpin

Installing requires use of the command line and an installed modern version of PHP (5.6 onwards preferably).

wget https://download.sculpin.io/sculpin.phar

Once it’s done downloading, we make it executable:

chmod +x sculpin.phar

Then we move it to the executable directory of our operating system:

sudo mv sculpin.phar /usr/local/bin/sculpin

Alternatively, you can just copy it to any directory where you want to use it.

Once it’s done cloning, navigate inside myblog and execute sculpin install. This will install all the dependencies needed by Sculpin to run.

cd myblog
sculpin install

This command uses Composer behind the scenes (you can open the sculpin.json file to see the similarity). Sculpin actually bundles an alternative version of Composer, so Composer isn’t needed outside it. If you need third-party packages to be installed just add them inside the require object then execute sculpin install to install them. By default, the packages are installed inside the source/components directory.

Once Sculpin is done installing the packages, execute the following command to generate the site. The watch option means that the site will be automatically re-generated once you change any of the configuration files or the files inside the source directory. The server option runs a server which will serve the generated site. By default, this can be accessed at http://localhost:8000, but if you’re using a good VM environment, the setup will vary depending on your open ports. See this post about Spress, a Sculpin alternative to learn how to set it up in a VM.

sculpin generate --watch --server

The generated site will be stored in the output_dev folder. This is only used for development purposes. If you’re already going to deploy your blog over to something like Github pages, you have to specify the env option:

sculpin generate --env prod

This will create an output_prod directory which you can then push to Github pages. We’ll go through this in a later section.

Configuring Sculpin

We can configure Sculpin by snooping around the two files inside the app/config directory:

sculpin_site.yml allows us to edit global options such as the title of the blog, and our disqus username.

sculpin_kernel.yml allows us to specify the theme to be used by Sculpin, and the permalinks format.

Other configuration files, such as the one for Amazon S3 bucket deployment, are in the root of the directory. We won’t really be using Amazon S3 in this tutorial, so we can just leave it as it is.

Blogging Basics

If you’re coming from Octopress or Jekyll, you’ll feel right at home with Sculpin because it uses markdown files for blog posts, only instead of .markdown you’ll have to use the more standard .md as the file extension. Another thing to note is that the Sculpin CLI doesn’t have a command for generating a new markdown file for housing a blog post. This means that you’ll have to use the touch command to create a new file:

touch 2016-05-17-getting-started-with-sculpin.md

Typing this out is really a pain though, so here’s a touch.php file which you can put in the root of your blog’s directory:

With this. you can execute the following command to create a new blog post:

php touch.php getting_started_with_sculpin

And it will create a source/_posts/2016-05-17-getting-started-with-sculpin.md file.

If you want a postdated blog post, you can specify a date as the second argument:

php touch.php getting_started_with_sculpin 2017-01-01

This will also add in the boilerplate front-matter contents for you:

---
title: Getting Started With Sculpin
tags: []
categories: []
---

Customizing the Site

Now it’s time to customize the site so it looks exactly how we want it. Here’s what the final output will look like:

We’ll be primarily working inside the source directory, so go ahead and enter it. Once there, open the index.html file. This is the file that Sculpin serves for the homepage of the site. In the first few lines, you’ll see the meta block which is used for specifying the layout, the title of the page, the generator used in the page, and how many posts to show per page.

If you’ve ever used Twig, Blade or any other templating engine before, layouts should be pretty familiar. index.html inherits from the default layout. Layouts are stored in the _layouts folder. Templates use html files, so the actual file would be _layouts/default.html. Open that file up, clear its contents and paste the following:

This is the main layout we’ll be using. Just concentrate on the code inside the <main> tag for now. We’ll demistify the rest later.

Only the contents inside the <main> tag change. What it means is: render the block named content_wrapper, and inside it render the block named content. This is where Twig really shines because we can override the contents of an inner block (content) if we define an outer block (content_wrapper). We’ll see this in action when we look at the _views/post.html file later on. For now, just keep in mind that either the content_wrapper or the content block should be defined in the templates that will inherit from this template.

We’ve established earlier that index.html inherits from layouts/default.html. But if you open the index.html file, you’ll see that we haven’t actually defined a content block. This is because Sculpin considers anything you add after the meta block to be the content. There is default content in there, added by the skeleton site, but we’ll use the content below. Let’s replace the default with the following:

This brings us to the next topic: generators. Out of the box, Sculpin has a generator called pagination, which allows us to easily paginate through a collection. In this case, the collection consists of the posts that we currently have in the source/_posts directory. The code below loops through the posts based on the current page number. On the index page, this will only return the last three posts (posts are ordered from newest to oldest).

This displays the title of the post, its contents, and a read more link. The read more link is implemented by creating a variable called break_array which stores the first half and second half of the article as two separate array items. This looks for the <!-- more --> comment as the delimiter. HTML comments aren’t visible in the page, so it’s the perfect delimiter.

{% set break_array = post.blocks.content|split('<!-- more -->', 2) %}

Next, we render whatever it is that’s in the first index of the break_array. The raw filter is used so that HTML gets rendered instead of escaped.

{{ break_array[0]|raw }}

We then check if there is more than one item stored in break_array, and in that case we render a link for viewing the whole post.

Now that we’ve figured out how the index page is being rendered, let’s return to the _layouts/default.html file. For the main stylesheet we use Picnic.css. We’re loading it from a CDN, but you can also download the files to your source/css directory and link to them.

This is mostly based on the individual post template from the Sculpin Blog Skeleton, with added date, and removed categories and pagination links.

You may have noticed that we’re using a different syntax for extending the default template:

{% extends "default" %}

This is because post is considered to be a layout. In Sculpin, anything that you put inside these directories: _views, _layouts, _partials, includes is considered a layout. This means that any template can inherit from these files, or include the partials.

We mentioned content_wrapper; the block that we we’re trying to render in the _layout/default.html file. Inside it is the content block:

We already know that the content block doesn’t need to be explicitly defined because Twig assumes that anything below the meta block is the content. This means that we can actually have only the following code in _views/post.html and the post would still be rendered:

{% extends "default" %}

But this will only render the content of the post, so the title, the date and any other information about the post that we want included wouldn’t be.

However, if we try to override the contents of the content block like so:

This means that we can’t really override what’s inside the content block. This is where the content_wrapper block comes into play. By defining this block, we can override the content block. This is because the content_wrapper block is wrapping the content block. Now we can do things like output the title and the date of publication.

If your username is captain then the repository name should be captain.github.io. This is pretty much the standard for Github pages, which also means that you can only create one Github page per account.

Next, go to the root directory of your blog and execute the following:

sculpin generate --env prod

This will generate a site for production. The generated site will be stored in the output_prod directory. Once generated, you can go ahead and delete the .git directory. If you remember from earlier, we have cloned the Sculpin Blog Skeleton. We’re not really going to contribute code to the repository so we can delete its local repo.

We now need to initialize a new git repository inside the output_prod folder. Navigate inside the directory and execute git init. Then, execute the following to commit the changes:

Wait for a few minutes before your Sculpin blog becomes live at http://your_github_username.github.io. Congrats!

Conclusion

In this tutorial, we looked at Sculpin, a PHP-based static site generator. As you have seen, Sculpin is a really good option for your static site generation needs. You can access the code used in this tutorial in this Github repo.

Did you do any extensive customization on your Sculpin blog? Is there any other static site generator solution you’d prefer instead? Let us know!

Wern is a web developer from the Philippines. He loves building things for the web and sharing the things he has learned by writing in his blog. When he's not coding or learning something new, he enjoys watching anime and playing video games.