Layouts

A layout can be thought of as a containing body or wrapper for a given page body content.

Philosophy

Layouts work as a wrapper. This is different from include style layouts covered in the examples below:

Layout wrapper strategy

  • layouts
    • pages.html
  • pages
    • index.html

pages/index.html

... page content ...

layout/pages.html

<div id="header">stuff</div>

<div id="content"> {{{ content }}} </div>

<div id="footer">stuff</div>

Here the mustache variable "content" will inject the page content body into the layout.

Layout includes strategy

  • partials
    • header.html
    • footer.html
  • pages
    • index.html

partials/header.html

<div id="header">stuff</div>
<div id="content">

partials/footer.html

</div>
<div id="footer">stuff</div>

pages/index.html

{{> header.html }}

... page content ...

{{> footer.html }}

Here the partials are been injected into the page body content. This means you need to set these partial includes in every page body which is not DRY.

Create

Layouts are placed either in the layouts folder at the base of your website, or within your theme's layouts folder:

  • layouts
    • common.html
  • theme-twitter
    • layouts
      • default.html
      • posts.html
      • pages.html
    • media
    • stylesheets

Note theme-level layouts will overload blog-level layouts.

Create via the Command-line

The Ruhoh command-line client can automatically create layouts for the active theme.

$ ruhoh layouts new splash

The command will create a file at:

  • theme-twitter
    • layouts
      • splash.html

Edit your layout as desired, then make sure to specify your new layout within the pages' YAML meta-data:

---
layout: splash
categories : ruby
---

No Layout

A page does not have any layout by default. You can give every page it's own full HTML document if you want:

  • posts
    • cool-post.html

posts/cool-post.html

---
date: '2012-09-13'
tags : "chair"
---

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>{{ page.title }}</title>
    {{# stylesheets.load }}
      style.css
    {{/ stylesheets.load }}
  </head>
  <body>
      <div class="content">
        <p>A cool post about stuff.</p>
        <ul>
          <li>a</li>
          <li>cool</li>
          <li>list</li>
        </ul>
      </div>
  </body>
</html>

Single Layout

But we like separation of content and presentation so we can refactor this to use a layout:

  • layouts
    • my-layout.html
  • posts
    • cool-post.html

layout/my-layout.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>{{ page.title }}</title>
    {{# stylesheets.load }}
      style.css
    {{/ stylesheets.load }}
  </head>
  <body>
    <div class="content">
      {{{ content }}}
    </div>
  </body>
</html>

Note we use the triple mustache syntax and call "content" which injects the calling page's or sub-layout's content body into the layout.

posts/cool-post.html

---
layout: "my-layout"
date: '2012-09-13'
tags : "chair"
---

<p>A cool post about stuff.</p> <ul> <li>a</li> <li>cool</li> <li>list</li> </ul>

Note we tell the page which layout it should use in the Top meta-data.

Sub-Layout

Suppose we have many types of collections like essays, posts, and pages. We may want to display these collections differently from one another but have a more generic global website skin for them to load into.

  • layouts
    • global.html
    • posts.html
    • essays.html
  • posts
    • cool-post.html
  • essays
    • hello-world.html

layouts/global.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>{{ page.title }}</title>
    {{# stylesheets.load }}
      style.css
    {{/ stylesheets.load }}
  </head>
  <body>
    <div class="content">
      {{{ content }}}
    </div>
  </body>
</html>

layouts/posts.html

<h1>My Post: {{page.title}}</h1>
<div class="inner post-body">
  {{{ content }}}
</div>

layouts/essays.html

<h1>Cool essays: {{ page.title }}</h1>
<div class="left"> {{{ content }}} </div>
<div class="right"> Hello </div>

posts/cool-post.html

---
layout: "posts"
date: '2012-09-13'
tags : "chair"
---

<p>A cool post about stuff.</p> <ul> <li>a</li> <li>cool</li> <li>list</li> </ul>

essays/hello-world.html

---
layout: "essays"
---

Hello!

Nesting

since 2.4

Layouts may be nested as many levels deep as you want. That is, a page can define a layout which defines a layout which defines a layout. Note it's not common to need more than two nested layouts.

Example

  • layouts
    • one.html
    • two.html
    • three.html
  • pages
    • index.html

pages/index.html

---
  "layout": "one"
---

... page content ...

layouts/one.html

---
  "layout": "two"
---

<div class="one-layout">{{{ content }}}</div>

layouts/two.html

---
  "layout": "three"
---

<div class="two-layout">{{{ content }}}</div>

layouts/three.html


<div class="three-layout">{{{ content }}}</div>