Basic Layout

Where {{> body }} is the point of insertion for content from any pages that use this layout.

Defining layouts

In the Assemble task options you can either specify a general layout to be used for all pages in a project:

assemble: {
options: {
layout: 'layouts/default.hbs'
}
}

Multiple layouts

When your project has different types or groupings of pages, such as "docs", "blog" and "examples" for instance, and there are certain design or structural elements that are unique to each grouping, it often makes
sense to:

Create a different targets in the assemble task to accomodate each grouping,

Give each target (e.g. each grouping of pages) its own special layout containing the unique elements required by each grouping. For example, every page in the blog target might have a right sidebar, whereas every page in the docs target
might have a left sideabar:

Nested layouts

Layouts can also be "stacked" so that the parent-most layouts contain the most commonly used elements while "child layouts" contain elements that are only necessary for specific pages or groupings of pages.

If, for example:

all pages will require the same <script></script> and <link> tags,

some pages in your project should be rendered with a sidebar

and some without a sidebar

This is a good opportunity to use nested layouts that might look something like this:

Example Layout #2: child layout

Our "child" layout will contain additional markup for our sidebar, but it should also inherit all of the markup from the parent layout (since layouts are "flattened" before pages are rendered). For the markup to be inherited,
we need to specify a parent layout for our child layout.

Specifying a layout for a layout works the exact same way as specifying a layout for any reguar page. It can be defined in the options.layout property in the Assemble task config in the Gruntfile (at the task and/or target
level), or the layout can be specified in the child layout's YAML front matter. Here is an example of the latter:

You might recall that the {{> body }} tag is the "insertion point" in a layout, specifying exactly where the content from each page will be passed in. Layouts are no different. A child layout will be inserted (flattened)
into the parent layout at the point of the {{> body }} tag.

Example "flattened" result

Continuing with the example from the previous section, the flattened layout for pages that use the "child" layout might look something like this during build:

Layout FAQ

Layouts are optional. If you don't need one, don't define one.

At build time, nested layouts are "flattened" before content is passed in from pages (child layouts are progressively "merged" into their respective parent layouts until there are no parent layouts left in the stack.)

Layouts can be defined at the task-level, target-level, in the YAML front-matter of a page, or in the data.layout property for pages defined in an options.pages collection.

Layout Specificity

As with CSS, the more specific layout wins:

Level

Description

none

Layouts are optional.

Task

Defined at the task-level of the assemble task.

Project level

Target

Defined at the target-level in the assemble task.

Sub-project level

Layout property (data)

Defined in the data: {} object in a pages collection.

Page and/or sub-page level

Layout property (YFM)

Defined in the YAML front matter of a page.

Page and/or sub-page level

Layout example

Layouts are optional, but the {{> body }} tag is required for content to be pulled into a layout.

Granular control

Target options: Override the "project default" in the options for each target. Offers greater control over which "types" of pages get which layout.

Page-by-page: If you require more granularity you can define a layout in the
YFM of a page

Multiple layouts

Since you can create as many
targets as you require, defining layouts in the Gruntfile is a great way of quickly setting up your layout "defaults". In the assemble task in your Gruntfile.js, you can define a layout at the task-level, and/or a
different layout for each build target:

Page-specific Layouts

If you require a higher level of granularity than defining layouts in the Gruntfile, you may also define layouts on a page-by-page basis, thus overriding both the task-level ("global") defaults and the target-level defaults.

Nested Layouts

Layouts can be nested inside other layouts. This enables highly granular control over how pages and layouts are organized. A common strategy is to use a basic "master" or "default" layout for a site, which contains only
the most common, bare necessities for a site. This default layout is then inherited by other more specialized layouts.

For example, your default layout may contain the <head></head>, footer, common link and script tags for a site:

Layouts for other formats

Markdown layouts

Layouts don't have to be HTML, they can be whatever language you want them to be. If you're generating markdown pages instead of HTML, maybe for a project wiki or other markdown documentation, then you'll want to use a markdown
formatted layout.

In this example, instead of adding adding the traditional head and footer we'll add some link references to make sure the same ones are used on every generated page. This makes it easier to maintain links and it also cuts down on potential
for broken links: