Hyde Press

Jekyll Style Guide (Book Edition)

by Ben Balter et al

An opinionated guide to common Jekyll design patterns and anti-patterns.

Contents

Preface

Note: The book edition is still an early release and a work-in-progess.

This is the (official) style guide for the Jekyll static site builder / generator reformatted in a single-page book edition.

See the source repo for how the book gets auto-built with "plain" Jekyll - of course - and hosted on GitHub Pages.

Onwards.

Acknowledgments

Thanks to Ben Balter and all style guide contributors for making it all possible.

Part 1 - Style Guides

Chapter 1.1 - Welcome

Contents

Why write this?

Jekyll’s incredibly flexible, but in some instances, the lack of common conventions make things harder for users.

For one, there are many common design patterns that are still relatively unknown to new users (e.g., using permalink: /about/ in about.md, rather than creating /about/index.md).

For another, when writing a plugin or theme intended to be used across sites, should it look for site.title or site.name? site.description or site.tagline? Moar options, moar problems.

This style guide aims to make it easier to create awesome Jekyll sites by codifying and surfacing Jekyll best practices.

Want to contribute?

This style guide is intended to be a collaborative resource for the Jekyll community. Please help improve it.

If you’d like to propose a change to the style guide, please suggest the added or modified rule as a pull request so that the community can discuss the merits of the proposed change a bit more tangibly.

A note on the style guide’s style

When it comes to software, there are a lot of personal preferences, and Jekyll is no exception. Whenever possible, please try to explain each rule’s logical justification and the rule the value provides to end users.

Chapter 1.2 - The config file

Contents

The format

Config files should be YAML.

Arrays

Prefer multi-line arrays for readability and version control purposes.

Good:

numbers:
  - one
  - two
  - three

Bad:

numbers: [one, two, three]

Variables

Use the following site-wide variables, where appropriate:

Baseurl

The site’s base URL is only to be used when the resulting site lives at a subpath of the domain. Otherwise, the subpath should be nil, not /.

The site.github namespace

When your site is intended to be hosted on GitHub Pages, prefer values in the site.github namespace to manually specified values. In additional to reducing configuration noise, this will save headache if your repository is renamed, you add a CNAME, the project is forked, or if you preview the site locally.

URL

Prefer site.github.url when using GitHub Pages. To ensure your site renders properly locally, add the following to your site’s config (which will be overridden by GitHub Pages):

github:
  url: http://localhost:4000

Chapter 1.3 - Filenames

Contents

Extensions

When a post contains markdown, use .md for the file extension. While .markdown will still render, many implementations assume three- to four-letter extension names, as will many developers.

Numbering page names

Whenever possible, avoid prefixing page filenames with numbers (e.g., 01-about, 02-contact). When order must be specified, prefer other means of ordering page navigation such as storing the ordering in YAML front matter, the site’s config or a data file.

Filename-based ordering makes it difficult to add additional pages cleanly, and may trick novice Jekyll users into thinking such numbers have special meaning (like Pages date prefixes do). More often than not, hard coded navigation (potentially in an include) will suffice.

Chapter 1.4 - .gitignore

Your site should have a .gitignore file, with a minimum of the following Git-ignored paths, which are local, unversioned artifacts created during the Jekyll build process:

_site
.sass-cache
.jekyll-metadata

Gemfile.lock

If the built site is served via GitHub Pages, you should also add Gemfile.lock to your site’s .gitignore. The github-pages gem strictly versions dependencies, rendering versioning the lockfile unnecessary, and potentially could result in using outdated gem versions.

Chapter 1.5 - Information architecture

Contents

When to use posts

Post are to be used for the site’s primary (or only) chronologically ordered content. Examples of this may be blog posts or news articles.

When to use collections

Use collections for any logically grouped content, chronological or not, that are not posts. Examples of collections might be employees, puppies, or releases. Each logical group of documents should be their own collection. For more information, see explain like I’m five: Jekyll collections.

When to use pages

Use pages for any non-chronological content that cannot be logically grouped together (and thus are not posts or collections). Examples of pages might be the index page, an about page, a contact us page, or a resume page.

When to use data

Use data (YAML, JSON, or CSV files in the _data folder) for site-wide configuration, settings, or other primarily static information. Examples of data might be the site’s authors, a list of press clippings, or a glossary of terms. Generally, the distinction between collections and data is that data files do not have a large markdown body, and live in a single file, rather than multiple files. Unlike collections, data files cannot render as individual files.

Chapter 1.6 - Layouts and includes

Contents

The site’s primary layout

The site’s primary layout should be called default.html. Where possible, all other layouts should inherit from the default layout.

Unless unusually complex, do not delegate header and footer markup to dedicated includes. This adds unnecessary complexity for simple sites. While many WordPress themes, for example, may do this, Rails, and the majority of the Ruby world (from which Jekyll gets its roots), do not.

Chapter 1.7 - Permalinks

Contents

Regardless of the permalink structure, prefer collection and per-file permalinks that end with a trailing slash, rather than .html. Pretty permalinks are intended to be read by humans, not machines, and contain no extraneous information (format information otherwise conveyed by the response header).

Good:

permalink: pretty
permalink: /:year/:month/:day/:title/

Bad:

permalink: date
permalink: /:categories/:year/:y_day/:title.html

Don’t hide markdown files in subfolders to achieve pretty permalinks. Doing so is unnecessary, adds additional steps to most editing workflows, and makes distinguishing between numerous index.md files more difficult, when open in a text editor. Generated permalinks should have a logical relationship to the source filename.

Good:

In about.md (accessible as /about/):

---
title: About
permalink: `/about/`
---

Bad:

In about/index.md (accessible as /about/):

---
title: About
---

Chapter 1.8 - Plugins

Contents

Plugins generally

For common use cases, prefer plugins with shared templates or logic over hard-coded HTML.

Gem-based plugins

Prefer Gem-based plugins over individual files in the _plugins folder.

Security

When writing plugins that may be run with untrusted user content, prefer liquid tempting and logic over Ruby, and internal Jekyll implementations over plugin-specific methods to minimize the surface area that needs to be secured.

Naming

Plugins should be descriptively named and preceded by jekyll-, (e.g., jekyll-avatars).

Plugins should be namespaced within the Jekyll module. The top-level class should not be prefixed with Jekyll.

Chapter 1.9 - Posts

Contents

Dates in front matter

Unless you need to specify the time your post was published, prefer the date in the filename to explicit YAML frontmatter post dates. This reduces duplication of information and reduces frontmatter noise that may not otherwise be necessary in most implementations.

Chapter 1.10 - The GitHub repository

Contents

If your site is hosted in a GitHub Pages repository, prefer the following:

The default branch

If your site uses only the gh-pages branch, set the gh-pages branch to your default branch and delete the master branch. This will ensure that when users visit your site’s repository, they see your site’s content, and that you don’t accidentally commit to the master branch, allowing the two to get out of sync. It will also set the default target for pull requests, ensuring contributors can’t do the same.

Chapter 1.11 - Syntax highlighting

Prefer backtick-style fenced-code blocks to Liquid-style highlight tags. This allows the markdown to render both within Jekyll and to be previewed on GitHub.com. Note: You may need to configure your markdown engine to properly support them. For Kramdown, that’s:

kramdown:
  input: GFM