Jekyll One

The Asciidoc skeleton multi-document a helper for setting up a base file and folder structure for multi-chapter AsciiDoc projects based on Jekyll and J1 Template. You need both to use this skeleton creating AsciiDoc documents from it.

Multi-chapter documents are used for more complex articles of a website. If the number of chapters is or exceeds three for an article, it could make sense to split a larger documents chapter-wise into separate files. This document type is based on multiple Asciidoc documents and make use of (local and global) Asciidoc include files and attributes.

Moving documents based on the skeleton

All Asciidoc Document Skeletons are fully relocateable and can be placed in any subfolder of your Jekyll site.

Configuration

Jekyll allows you to configure your sites in any way you can dream up, and it’s thanks to the powerful and flexible configuration options that this is possible.

These options can either be specified in a _config.yml file placed in your site’s root directory, or can be specified as flags for the jekyll executable on command-line.

Global Configuration

The table below lists the available settings for Jekyll, and the various options (specified in the configuration file) and flags (specified on the command-line) that control them.

Table 1. Global Configuration Options
Setting Option Flag Description

Site Source

source: DIR

-s, --source DIR

Change the directory where Jekyll will read files

Site Destination

destination: DIR

-d, --destination DIR

Change the directory where Jekyll will write files

Safe

safe: BOOL

--safe

Disable non-whitelisted plugins, caching to disk, and ignore symbolic links.

Exclude

exclude: [DIR, FILE, …​]

na

Exclude directories and/or files from the conversion. These exclusions are relative to the site’s source directory and cannot be outside the source directory.

Include

include: [DIR, FILE, …​]

na

Force inclusion of directories and/or files in the conversion. The file .htaccess is a good example since dotfiles are excluded by default.

Keep files

keep_files: [DIR, FILE, …​]

na

When clobbering the site destination, keep the selected files. Useful for files that are not generated by jekyll; e.g. files or assets that are generated by your build tool. The paths are relative to the destination.

Time Zone

timezone: TIMEZONE

na

Set the time zone for site generation. This sets the TZ environment variable, which Ruby uses to handle time and date creation and manipulation. Any entry from the IANA Time Zone Database is valid, e.g. America/New_York. A list of all available values can be found from here. The default is the local time zone, as set by your operating system.

Encoding

encoding: ENCODING

na

Set the encoding of files by name (only available for Ruby 1.9 or later). The default value is utf-8 starting in 2.0.0, and nil before 2.0.0, which will yield the Ruby default of ASCII-8BIT.

Destination folders are cleaned on site builds.

The contents of <destination> are automatically cleaned, by default, when the site is built. Files or folders that are not created by your site will be removed. Some files could be retained by specifying them within the <keep_files> configuration directive.

Do not use an important location for <destination> instead, use it as a staging area and copy files from there to your web server.

Build Command Options

Table 2. Build Command Options
Setting Option Flag Description

Regeneration

na

-w, --[no-]watch

Enable auto-regeneration of the site when files are modified.

Configuration

na

--config FILE1 [,FILE2, ..]

Specify config files instead of using _config.yml automatically. Settings in later files override settings in earlier files.

Drafts

show_drafts: BOOL

--drafts

Process and render draft posts.

Environment

na

na

Use a specific environment value JEKYLL_ENV=production in the build.

Future

future: BOOL

--future

Publish posts or collection documents with a future date.

LSI

lsi: BOOL

--lsi

Produce an index for related posts.

Limit Posts

limit_posts: NUM

--limit_posts NUM

Limit the number of posts to parse and publish.

Force polling

na

--force_polling

Force watch to use polling.

Verbose output

na

-V, --verbose

Print verbose output.

Silence Output

na

-q, --quiet

Silence the normal output from Jekyll during a build

Incremental build

incremental: BOOL

-I, --incremental

Enable the experimental incremental build feature. Incremental build only re-builds posts and pages that have changed, resulting in significant performance improvements for large sites, but may also break site generation in certain cases.

Liquid profiler

profile: BOOL

--profile

Generate a Liquid rendering profile to help you identify performance bottlenecks.

Serve Command Options

In addition to the options below, the serve sub-command can accept any of the options for the build sub-command, which are then applied to the site build which occurs right before your site is served.

Table 3. Serve Command Options
Setting Option Flag Description

Local Server Port

port: PORT

--port PORT

Listen on the given port.

Local Server Hostname

host: HOSTNAME

--host HOSTNAME

Listen at the given hostname.

Base URL

baseurl: URL

--baseurl URL

Serve the website from the given base URL

Detach

detach: BOOL

-B, --detach

Detach the server from the terminal to run the Jekyll executeable in background. NOTE: The parameter Detach is not available on Windows.

Skip the initial site build

na

--skip-initial-build

Skips the initial site build which occurs before the server is started

X.509 (SSL) Private Key

na

--ssl-key

SSL Private Key if HTTPS connections are used

X.509 (SSL) Certificate

na

--ssl-cert

SSL Public certificate if HTTPS connections are used

Do not use tabs in configuration files.

This will either lead to parsing errors, or Jekyll will revert to the default settings. Use spaces instead.

Custom WEBrick Headers

The Jekyll serve command enables an internal Web server - WEBrick - to serve your site without the need of an external Webserver (like Apache or Nginx). To control the internal server, you can provide custom headers for your site by adding them to _config.yml

  # File: _config.yml
  webrick:
    headers:
      My-Header: My-Value
      My-Other-Header: My-Other-Value
Jekyll provide by default Content-Type and Cache-Control response headers: one dynamic in order to specify the nature of the data being served, the other static in order to disable caching so that you don’t have to fight with Chrome’s aggressive caching when you are in development mode.

Jekyll Environment

Folder structure

Jekyll is, at its core, a text transformation engine. The concept behind the system is this: you give it text written in your favorite markup language, be that Markdown, Textile, or just plain HTML, and it churns that through a layout or a series of layout files. Throughout that process you can tweak how you want the site URLs to look, what data gets displayed in the layout, and more. This is all done through editing text files; the static web site is the final product.

A basic Jekyll site usually looks something like this:

.
├── _config.yml
├── _drafts
|   ├── begin-with-the-crazy-ideas.textile
|   └── on-simplicity-in-technology.markdown
├── _includes
|   ├── footer.html
|   └── header.html
├── _layouts
|   ├── default.html
|   └── post.html
├── _posts
|   ├── 2007-10-29-why-every-programmer-should-play-nethack.textile
|   └── 2009-04-26-barcamp-boston-4-roundup.textile
├── _data
|   └── members.yml
├── _site
├── .jekyll-metadata
└── index.html

Files and Folders

An overview of what each of these does:

Table 4. Files and Folders
File|Folder Description

_config.yml

Stores all side-wide used configuration data. Many of these options can be specified from the command line executable but it’s easier to specify them in a file so you don’t have to remember them.

_drafts

Drafts are unpublished posts. The format of these files is without a date: title.MARKUP.

_includes

These are the partials that can be mixed and matched by your layouts and posts to facilitate reuse. The liquid tag {% include file.ext %} can be used to include the partial in _includes/file.ext.

_layouts

This folder contains the templates that wrap posts and pages. Layouts are chosen on a file-by-file basis in the YAML Front Matter, which is described in the next section. The liquid tag {{content}} is used to inject content into the web page.

_posts

The folder contains your blog post content. The naming convention of these files is important, and must follow the format: YEAR-MONTH-DAY-title.ext. The permalinks can be customized for each post, but the date and markup language are determined solely by the file name.

_data

Well-formatted site data should be placed in that folder. The Jekyll engine will autoload all YAML files in this directory (using either the .yml, .yaml, .json or .csv formats and extensions) and they will be accessible via site.data. If there’s a file e.g. members.yml under the directory, then you can access contents of the file through site.data.members.

_site

This folder is where the generated site will be placed (by default) once Jekyll is done transforming it. It’s probably a good idea to add this to your .gitignore file if you’re using Git for version control.

.jekyll-metadata

This file helps Jekyll keep track of which files have not been modified since the site was last built, and which files will need to be regenerated on the next build. This file will not be included in the generated site. It’s probably a good idea to add this to your .gitignore file if you’re using Git for version control.

index.html

index.html and other HTML, Asciidoc, Markdown, Textile files. If the file contains a YAML Front Matter section, it will be transformed by Jekyll. The same will happen for any .html, .adoc, .markdown, .md, or .textile file in your site’s root directory or directories not listed above.

Other Files or Folders

Every other directory and file except for those listed above such as css and images folders, favicon.ico files, and so forth will be copied verbatim to the generated site. There are plenty of sites already using Jekyll if you’re curious to see how they’re laid out.

Set a Jekyll environment

You can specify a Jekyll environment at build time. In the build (or serve) arguments, you can specify a Jekyll environment and value. The build will then apply this value in any conditional statements in your content.

For example, suppose you set this conditional statement in your code:

  {% raw %}
  {% if jekyll.environment === "production" %}
     {% include disqus.html %}
  {% endif %}
  {% endraw %}

When you build your Jekyll site, the content inside the if statement won’t be run unless you also specify a production environment in the build command, like this:

  JEKYLL_ENV=production jekyll build

Specifying an environment value allows you to make certain content available only within specific environments.

The default value for JEKYLL_ENV is development. Therefore if you omit JEKYLL_ENV from the build arguments, the default value will be JEKYLL_ENV=development. Any content inside

  {% if jekyll.environment == "development" %}

tags will automatically appear in the build.

Your environment values can be anything you want (not just development or production). Some elements you might want to hide in development environments include Disqus comment forms or Google Analytics. Conversely, you might want to expose an "Edit me in GitHub" button in a development environment but not include it in production environments.

By specifying the option in the build command, you avoid having to change values in your configuration files when moving from one environment to another.

Front Matter defaults

Using YAML Front Matter is one way that you can specify configuration in the pages and posts for your site. Setting things like a default layout, or customizing the title, or specifying a more precise date/time for the post can all be added to your page or post front matter.

Often times, you will find that you are repeating a lot of configuration options. Setting the same layout in each file, adding the same category - or categories - to a post, etc. You can even add custom variables like author names, which might be the same for the majority of posts on your blog.

Instead of repeating this configuration each time you create a new post or page, Jekyll provides a way to set these defaults in the site configuration. To do this, you can specify site-wide defaults using the defaults key in the _config.yml file in your project’s root directory.

The defaults key holds an array of scope/values pairs that define what defaults should be set for a particular file path, and optionally, a file type in that path.

Let’s say that you want to add a default layout to all pages and posts in your site. You would add this to your _config.yml file:

defaults:
  - scope:
    path:     ""        # an empty string here means all files in the project
    values:
      layout: "default"

Please stop and rerun jekyll serve command.

The _config.yml master configuration file contains global configurations and variable definitions that are read once at execution time. Changes made to _config.yml during automatic regeneration are not loaded until the next execution.

Note Data Files are included and reloaded during automatic regeneration.

Here, we are scoping the values to any file that exists in the path scope. Since the path is set as an empty string, it will apply to all files in your project. You probably don’t want to set a layout on every file in your project - like css files, for example - so you can also specify a type value under the scope key.

defaults:
  - scope:
    path:     ""      # an empty string here means all files in the project
    type:     "posts" # previously `post` in Jekyll 2.2.
    values:
      layout: "default"

Now, this will only set the layout for files where the type is posts. The different types that are available to you are pages, posts, drafts or any collection in your site. While type is optional, you must specify a value for path when creating a scope|values pair.

As mentioned earlier, you can set multiple scope/values pairs for defaults.

defaults:
  - scope:
    path:     ""
    type:     "posts"
    values:
      layout: "my-site"
  - scope:
    path:     "projects"
    type:     "pages" # previously `page` in Jekyll 2.2.
    values:
      layout: "project" # overrides previous default layout
      author: "Mr. Hyde"

With these defaults, all posts would use the my-site layout. Any html files that exist in the projects/ folder will use the project layout, if it exists. Those files will also have the page.author liquid variable set to Mr. Hyde.

collections:
  - my_collection:
      output: true
defaults:
  - scope:
    path:       ""
    type:       "my_collection"   # a collection in your site, in plural form
    values:
      layout:   "default"

In this example, the layout is set to default inside the collection with the name my_collection.

Precedence

Jekyll will apply all of the configuration settings you specify in the defaults section of your _config.yml file. However, you can choose to override settings from other scope/values pair by specifying a more specific path for the scope.

You can see that in the second to last example above. First, we set the default layout to my-site. Then, using a more specific path, we set the default layout for files in the projects/ path to project. This can be done with any value that you would set in the page or post front matter.

Finally, if you set defaults in the site configuration by adding a defaults section to your _config.yml file, you can override those settings in a post or page file. All you need to do is specify the settings in the post or page front matter.

For example:

# In _config.yml
...
defaults:
  - scope:
    path:       "projects"
    type:       "pages"
    values:
      layout:   "project"
      author:   "Mr. Hyde"
      category: "project"
...
# In projects/foo_project.md
---
author: "John Smith"
layout: "foobar"
---
The post text goes here...

The projects/foo_project.md would have the layout set to foobar instead of project and the author set to John Smith instead of Mr. Hyde when the site is built.

Default Configuration

Jekyll runs with the following configuration options by default. Alternative settings for these options can be explicitly specified in the configuration file or on the command-line.

There are two unsupported kramdown options.

Please note that both remove_block_html_tags and remove_span_html_tags are currently unsupported in Jekyll due to the fact that they are not included within the kramdown HTML converter.

# Where things are
#
source:           .
destination:      ./_site
plugins_dir:      _plugins
layouts_dir:      _layouts
data_dir:         _data
includes_dir:     _includes
collections:
  posts:
    output:       true
# Handling Reading
#
safe:             false
include:          [".htaccess"]
exclude:          []
keep_files:       [".git", ".svn"]
encoding:         "utf-8"
markdown_ext:     "markdown,mkdown,mkdn,mkd,md"
# Filtering Content
#
show_drafts:      null
limit_posts:      0
future:           false
unpublished:      false
# Plugins
#
whitelist:        []
gems:             []
# Conversion
#
markdown:         kramdown
highlighter:      rouge
lsi:              false
excerpt_separator: "\n\n"
incremental:      false
# Serving
#
detach:           false
port:             4000
host:             127.0.0.1
baseurl:          ""          # does not include hostname
show_dir_listing: false
# Outputting
#
permalink:        date
paginate_path:    /page:num
timezone:         null
quiet:            false
verbose:          false
defaults:         []
liquid:
  error_mode:     warn
# Markdown Processors
#
rdiscount:
  extensions:     []
redcarpet:
  extensions:     []
kramdown:
  auto_ids:       true
  footnote_nr:    1
  entity_output:  as_char
  toc_levels:     1..6
  smart_quotes:   lsquo,rsquo,ldquo,rdquo
  input:          GFM
  hard_wrap:      false
  footnote_nr:    1

Liquid Options

Liquid’s response to errors can be configured by setting error_mode. The options are

  • lax --- Ignore all errors.

  • warn --- Output a warning on the console for each error.

  • strict --- Output an error message and stop the build.

Markdown Options

The various Markdown renderers supported by Jekyll sometimes have extra options available.

Redcarpet

Redcarpet can be configured by providing an extensions sub-setting, whose value should be an array of strings. Each string should be the name of one of the Redcarpet::Markdown class’s extensions; if present in the array, it will set the corresponding extension to true.

Jekyll handles two special Redcarpet extensions:

  • no_fenced_code_blocks --- By default, Jekyll sets the fenced_code_blocks extension (for delimiting code blocks with triple tildes or triple backticks) to true, probably because GitHub’s eager adoption of them is starting to make them inescapable. Redcarpet’s normal fenced_code_blocks extension is inert when used with Jekyll; instead, you can use this inverted version of the extension for disabling fenced code.

Note that you can also specify a language for highlighting after the first delimiter:

  # ...ruby code

With both fenced code blocks and highlighter enabled, this will statically highlight the code; without any syntax highlighter, it will add a class="LANGUAGE" attribute to the <code> element, which can be used as a hint by various JavaScript code highlighting libraries.

  • smart --- This pseudo-extension turns on SmartyPants, which converts straight quotes to curly quotes and runs of hyphens to em (---) and en (--) dashes.

All other extensions retain their usual names from Redcarpet, and no renderer options aside from smart can be specified in Jekyll. [A list of available extensions can be found in the Redcarpet README file.][redcarpet_extensions] Make sure you’re looking at the README for the right version of Redcarpet: Jekyll currently uses v3.2.x. The most commonly used extensions are:

  • tables

  • no_intra_emphasis

  • autolink

[redcarpet_extensions]: https://github.com/vmg/redcarpet/blob/v3.2.2/README.markdown#and-its-like-really-simple-to-use

Custom Markdown Processors

If you’re interested in creating a custom markdown processor, you’re in luck! Create a new class in the Jekyll::Converters::Markdown namespace:

  class Jekyll::Converters::Markdown::MyCustomProcessor
    def initialize(config)
      require 'funky_markdown'
      @config = config
    rescue LoadError
      STDERR.puts 'You are missing a library required for Markdown. Please run:'
      STDERR.puts '  $ [sudo] gem install funky_markdown'
      raise FatalException.new("Missing dependency: funky_markdown")
    end
    def convert(content)
      ::FunkyMarkdown.new(content).convert
    end
  end

Once you’ve created your class and have it properly set up either as a plugin in the _plugins folder or as a gem, specify it in your _config.yml:

  markdown: MyCustomProcessor

Incremental Regeneration

Incremental regeneration helps shorten build times by only generating documents and pages that were updated since the previous build. It does this by keeping track of both file modification times and inter-document dependencies in the .jekyll-metadata file.

Incremental regeneration is still an experimental feature.

While incremental regeneration will work for the most common cases, it will not work correctly in every scenario. Please be extremely cautious when using the feature, and report any problems not listed below by {uri-jekyll-submit-issue}[opening an issue on GitHub].

Under the current implementation, incremental regeneration will only generate a document or page if either it, or one of its dependencies, is modified. Currently, the only types of dependencies tracked are includes (using the {% include %} tag) and layouts. This means that plain references to other documents (for example, the common case of iterating over site.posts in a post listings page) will not be detected as a dependency.

To remedy some of these shortfalls, putting regenerate: true in the front-matter of a document will force Jekyll to regenerate it regardless of whether it has been modified. Note that this will generate the specified document only; references to other documents' contents will not work since they won’t be re-rendered.

Incremental regeneration can be enabled via the --incremental flag (-i for short) from the command-line or by setting incremental: true in your configuration file.

Jekyll Variables

Jekyll traverses your site looking for files to process. Any files with YAML front matter are subject to processing. For each of these files, Jekyll makes a variety of data available via the Liquid templating system.

The following is a reference of the available data.

Global Variables

Table 5. Global Variables
Variable Description

site

Sitewide configuration settings from _config.yml.

page

Page specific information. Custom variables set via the YAML Front Matter will be available here.

layout

Layout specific information. Custom variables set via the YAML Front Matter in layouts will be available here.

content

In layout files, the rendered content of the Post or Page being wrapped. Not defined in Post or Page files.

paginator

When the paginate configuration option is set, this variable becomes available for use.

Site Variables

Table 6. Site Variables
Variable Description

site.time

The current time (when you run the jekyll command).

site.pages

A list of all Pages.

site.posts

A reverse chronological list of all Posts.

site.related_posts

If the page being processed is a Post, this contains a list of up to ten related Posts. By default, these are the ten most recent posts. For high quality but slow to compute results, run the jekyll command with the --lsi (latent semantic indexing) option. Also note GitHub Pages does not support the lsi option when generating sites.

site.static_files

A list of all (i.e. files not processed by Jekyll’s converters or the Liquid renderer). Each file has three properties: path, modified_time and extname.

site.html_pages

A subset of site.pages listing those which end in .html.

site.html_files

A subset of site.static_files listing those which end in .html.

site.collections

A list of all the collections.

site.data

A list containing the data loaded from the YAML files located in the _data directory.

site.documents

A list of all the documents in every collection.

site.categories.CATEGORY

The list of all Posts in category CATEGORY.

site.tags.TAG

The list of all Posts with tag TAG.

site.[CONFIGURATION_DATA]

All the variables set via the command line and your _config.yml are available through the site variable. For example, if you have url: http://mysite.com in your configuration file, then in your Posts and Pages it will be stored in site.url. Jekyll does not parse changes to _config.yml in watch mode, you must restart Jekyll to see changes to variables.

Page Variables

Table 7. Page Variables
Variable Description

page.content

The content of the Page, rendered or un-rendered depending upon what Liquid is being processed and what page is.

page.title

The title of the Page.

page.excerpt

The un-rendered excerpt of the Page.

page.url

The URL of the Post without the domain, but with a leading slash, e.g. /2008/12/14/my-post.html

page.date

The Date assigned to the Post. This can be overridden in a Post’s front matter by specifying a new date/time in the format YYYY-MM-DD HH:MM:SS (assuming UTC), or YYYY-MM-DD HH:MM:SS +/-TTTT (to specify a time zone using an offset from UTC. e.g. 2008-12-14 10:30:00 +0900).

page.id

An identifier unique to the Post (useful in RSS feeds). e.g. /2008/12/14/my-post

page.categories

The list of categories to which this post belongs. Categories are derived from the directory structure above the _posts directory. For example, a post at /work/code/_posts/2008-12-24-closures.md would have this field set to ['work', 'code']. These can also be specified in the YAML Front Matter.

page.tags

The list of tags to which this post belongs. These can be specified in the YAML Front Matter.

page.path

The path to the raw post or page. Example usage: Linking back to the page or post’s source on GitHub. This can be overridden in the YAML Front Matter.

page.next

The next post relative to the position of the current post in site.posts. Returns nil for the last entry.

page.previous

The previous post relative to the position of the current post in site.posts. Returns nil for the first entry.

Use Custom Front Matter

Any custom front matter that you specify will be available under page. For example, if you specify custom_css: true in a pages front matter, that value will be available as page.custom_css.

If you specify front matter in a layout, access that via layout. For example, if you specify class: full_page in a pages front matter, that value will be available as layout.class in the layout and its parents.