- Getting started
- Filters and Tags
- Variables
- Naming your files
- Sample themes
- Testing sites locally
- Further reading
- Other resources
- Contributing
Siteleaf uses the popular Liquid syntax for themes. If you can write HTML, you’ll have no problem using Liquid.
Here’s how a simple template might look:
<html>
<head>
<title>{{site.title}} | {{title}}</title>
</head>
<body>
<h1>{{title}}</h1>
<article>{{body}}</article>
{% if parent %}
<p><a href="{{parent.url}}">← Go back</a></p>
{% endif %}
</body>
</html>
As you can see, there are two types of markup in Liquid:
- Output markup (which may resolve to text) is surrounded by
{{ matched pairs of curly brackets (ie, braces) }}
- Tag markup (which cannot resolve to text) is surrounded by
{% matched pairs of curly brackets and percent signs %}
If you are new to the Liquid syntax, a good place to start is Liquid for Designers.
Siteleaf supports all Standard Liquid Filters and Liquid Tags.
Siteleaf is also compatible with Jekyll Liquid Filters.
In addition, Siteleaf adds the following custom filters:
Filter | Description | Example |
---|---|---|
fallback |
Provide a default value if variable is blank. | {{title | fallback:"Untitled"}} |
json |
Formats content as JSON (JavaScript Object Notation) | {{site.posts | json}} |
markdown |
Converts Markdown to HTML, use true to apply Smartypants. |
{{title | markdown:true}} |
smartypants |
Applies Smartypants (smart quotes, em/en dashes, etc). | {{title | smartypants}} |
slug |
Converts a string to its URL-friendly, slug form. | {{meta.custom_field | slug}} |
site
contains global variables available to all pages.
Variable | Description |
---|---|
site.title |
The title of your website. |
site.domain |
Your website’s domain name (ie. barlawrence.com ). |
site.permalink |
Your website’s full address (ie. http://barlawrence.com ). |
site.pages |
A nested array of pages. |
site.posts |
Array of all posts in all pages. |
site.feed_url |
URL to your website’s RSS feed (ie. http://barlawrence.com/feed.xml ). |
site.sitemap_url |
URL to your website’s Sitemap file (ie. http://barlawrence.com/sitemap.xml ). |
site.date |
Date of most recent publish. |
For example, use the following Liquid to get the title of your website:
{{site.title}}
Loop through site.pages
to build a menu:
<nav>
<ul>
{% for page in site.pages %}
<li><a href="{{page.url}}"{% if page.url == url %} class="selected"{% endif %}>{{page.title}}</a></li>
{% endfor %}
</ul>
</nav>
Variable | Description |
---|---|
type |
Can be page , post , archive , taxonomy , or tag . |
title |
Title of content. |
url |
URL to object without domain (ie. /blog/my-post ). |
permalink |
Full URL to object with domain (ie. http://mysite.com/blog/my-post ). |
body |
Body in HTML (rendered from Markdown), available in page and post types. |
body_raw |
Body in raw Markdown, available in page and post types. |
excerpt |
Shortened version of the body (use 2 empty lines to break), available in page and post types. |
excerpt_raw |
Excerpt in raw Markdown, available in page and post types. |
assets |
Array of assets, available on page and post types. |
meta |
Array of metadata, available on page and post types. |
taxonomy |
Array of taxonomy, available on post type only. |
tags |
Array of tags, available on taxonomy type only. |
pages |
Array of child-pages, available on page type only. |
posts |
Array of posts, available in page , archive , and tag types. |
previous |
The previous page or post , available in page or post types. |
next |
The next page or post , available in page or post types. |
current |
Alias of the curent page or post , available in page or post types. |
parent |
Parent page object (if exists). |
archive_url |
URL to archive page, available on page type only. |
date |
Date of publish, available in page and post types. |
author.fullname |
Full name of author, available in page and post types. |
author.firstname |
First name of author, available in page and post types. |
author.lastname |
Last name of author, available in page and post types. |
author.email |
Author’s email, available in page and post types. |
author.avatar |
Author’s Gravatar URL, available in page and post types. |
Get the title and body for the current page:
<h2>{{title}}</h2>
{{body}}
Check for parent page:
{% if parent %}
<a href="{{parent.url}}">← Back to {{parent.title}}</a>
{% endif %}
See Content for available variables.
Count the number of posts:
This page has {{posts | size}} posts.
Loop through the first 20 posts on the current page:
{% for post in posts limit:20 %}
<article>
<header><a href="{{post.url}}">{{post.title}}</a></header>
{{post.body}}
<footer>Posted on {{post.date | date: "%b %d, %Y"}} by {{post.author.fullname}}</footer>
</article>
{% endfor %}
See Content for available variables.
Count the number of subpages:
This page has {{pages | size}} subpages.
Loop through the subpages:
{% for page in pages %}
<article>
<h3><a href="{{page.url}}">{{page.title}}</a></h3>
{{page.body}}
</article>
{% endfor %}
Variable | Description |
---|---|
type |
Can be image , audio , video , or other . |
filename |
Name of file (ie. photo.jpg ). |
url |
URL to object without domain (ie. /assets/photo.jpg ). |
permalink |
Full URL to object with domain (ie. http://mysite.com/assets/photo.jpg ). |
content_type |
MIME type of asset (ie. image/jpeg ). |
filesize |
Size of file in bytes (ie. 1024 ). |
date |
Date asset was created. |
Count the number of assets:
{{assets | size}}
Loop through assets:
{% for asset in assets %}
{% if asset.type == 'image' %}
<img src="{{asset.url}}">
{% elsif asset.type == 'audio' %}
<audio><source src="{{asset.url}}" type="{{asset.content_type}}"></audio>
{% elsif asset.type == 'video' %}
<video><source src="{{asset.url}}" type="{{asset.content_type}}"></video>
{% elsif asset.type == 'other' %}
<a href="{{asset.url}}">Download {{asset.filename}}</a></li>
{% endif %}
{% endfor %}
Variable | Description |
---|---|
meta |
Array of all metadata key/value pairs. |
meta.KEY |
Get single metadata by key (ie. Color ). |
Available for each metadata:
Variable | Description |
---|---|
key |
Name of metadata key (ie. Color ). |
value |
Value of metadata (ie. Red ). |
Count number of metadata fields:
{{meta | size}}
Get metadata for key Color
:
{{meta.color}}
Get metadata for key My Color
:
{{meta['My Color']}}
Loop through metadata:
<dl>
{% for data in meta %}
<dt>{{data.key}}</dt> <dd>{{data.value}}</dd>
{% endfor %}
</dl>
Conditional for specific metadata value:
{% if meta.color.value == 'Red' %}
<p>This color is red!</p>
{% endif %}
Siteleaf allows you to use multiple tag sets called Taxonomy. By default, each site will have one set called Tags
.
Variable | Description |
---|---|
taxonomy |
Array of all taxonomy sets. |
taxonomy.KEY |
Get tags by set name, ie. Tags . |
Variable | Description |
---|---|
key |
Name of taxonomy set, ie. Tags . |
slug |
URI slug for set, ie. tags . |
url |
URL for set page without domain, ie. /blog/tags |
permalink |
URL for set page with domain, ie. http://mysite.com/blog/tags |
tags |
Array of tags in set. |
tags.KEY |
Get single tag by name, ie. Design . |
Variable | Description |
---|---|
value |
Name of tag, ie. Design . |
slug |
URI slug for tag set, ie. design . |
url |
URL for tag page without domain, ie. /blog/tags/design |
permalink |
URL for tag page with domain, ie. http://mysite.com/blog/tags/design |
posts |
Array of posts with this tag. |
Count number of tags in the default Tags
set:
{{taxonomy['tags'] | size}}
Count number of tags in the Colors
tag set:
{{taxonomy['colors'] | size}}
Get first tag in the Colors
tag set:
{{taxonomy['colors'].first}}
Loop through the Tags
set:
<ul>
{% for tag in taxonomy['tags'] %}
<li><a href="{{tag.url}}">{{tag.value}}</a></li>
{% endfor %}
</ul>
Loop through the Colors
set:
<ul>
{% for tag in taxonomy['colors'] %}
<li><a href="{{tag.url}}">{{tag.value}}</a></li>
{% endfor %}
</ul>
Loop through all tag sets:
<ul>
{% for set in taxonomy %}
<li>{{set.key}} ({{set | size}} tags)
<ul>
{% for tag in set %}
<li><a href="{{tag.url}}">{{tag.value}}</a></li>
{% endfor %}
</ul>
</li>
{% endfor %}
</ul>
Siteleaf themes may contain one or more templates.
Your base template should always be called default.html
.
Additional templates can be applied to other pages by following the same URL structure as your website:
URL | Template |
---|
-
| default.html (required, used by default)
/ | index.html /blog | blog.html (or blog/index.html) /blog/new-post | blog/default.html /blog/archive | blog/archive.html (or blog/archive/index.html)
Includes (or partials) can be added by using the include
tag:
{% include 'header' %}
{% include 'includes/menu' %}
Include files should be prepended with an underscore. In the above examples, Siteleaf will look for _header.html
and _includes/menu.html
respectively.
This repo contains the default Siteleaf theme as well as a basic barebones template to help you get started.
More sample themes can be found in the wiki:
https://github.com/siteleaf/siteleaf-themes/wiki/Siteleaf-themes-on-Github
If you have a theme you'd like to share with the community, feel free to add it.
To test and build themes locally, install the Siteleaf Gem
- Siteleaf overview - An overview of the top Siteleaf features
- Developing sites and themes - Video walkthrough of creating Siteleaf themes and developing locally
- An Introduction to Siteleaf
- Hello World, I'm Siteleaf
- Metadata in Siteleaf
- Taxonomy in Siteleaf
- Markdown in Siteleaf
- Porting a theme to Siteleaf
- Layouts in Siteleaf
Help us improve this documentation:
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request