-
Notifications
You must be signed in to change notification settings - Fork 4
Layouts
Layouts let you to define shared HTML used by your pages. For example, a main layout can contain the header and footer of your site, so that you can focus on the content of each page instead of including these elements everywhere.
By default, Frontman assumes your layouts are located in the views/layouts/
directory. You can change the location Frontman should look in by setting the :layout_dir
configuration value in your config.rb
.
Frontman::Config.set :layout_dir, 'my-layout-dir/'
There are two ways you can define what layout Frontman must use to render your page: globally (based on the URL) or via a YAML front matter. By default, when you initialize a new Frontman project, we add a line to your config.rb
that renders all your pages using the main.haml
layout.
You can define the layout for your pages globally, based on the URL structure. For example, if you have a blog and you want to use the views/layouts/blog_post.haml
layout to render all the pages under posts/
, you can register this layout in your config.rb
file:
register_layout 'posts/*', 'blog_post.haml'
Frontman uses glob matching to find the first matching layout for any page. If you register a layout with '*'
as the URL pattern, make sure to register it last so that it doesn't override other, more specific layouts.
You can use YAML front matter in your pages to define a layout
key with the relative path to your layout. By default, Frontman looks for layouts in the views/layouts/
directory.
---
layout: blog_post.haml
---
The layout you define in the front matter takes precedence over any matching layout registered in your config.rb
file. Therefore, you should only use layout definitions in front matter as an exception, and prefer to define your layouts globally when possible.
You can extend layouts by wrapping them within each other with the wrap_layout
method. Consider the following layouts in your project:
-# views/layouts/main.haml
%html
%head
%title
My site
%body
= yield
-# views/layouts/blog_post.haml
= wrap_layout 'main.haml' do
%article.content
= yield
And imagine we have the following source/posts/my-first-post.html.md
page:
Hello, world!
If we register blog_post.haml
as the layout for all our posts, Frontman generates the following HTML for my-first-post.html.md
.
<html>
<head>
<title>My site</title>
</head>
<body>
<article class="content">
<p>Hello, world!</p>
</article>
</body>
</html>
Sometimes, you need to forward data from a page to the layout you render it in. You can do this using the yield_content
, content_for?
, and content_for
methods.
In your pages and layouts, you can define content for content slots using the content_for
method:
<% content_for :page_title, current_page.data.title %>
You can use the content_for?
method to check if there is any content for a given slot.
content_for? :page_title # false
content_for :page_title, 'Hello, world!'
content_for? :page_title # true
Finally, in your layouts, you can use yield_content
to output the content for a given block.
content_for :page_title, 'Hello, world!'
puts yield_content :page_title # outputs "Hello, world!"
You can leverage content blocks, for example, to set the page title from a page's front matter. In your main layout, you can use yield_content
if the page title is set.
%html
%head
%title
= content_for?(:page_title) ? yield_content(:page_title) : 'Welcome'
%body
= yield
Then, in views/layouts/blog_post.haml
, you can define the content block with content_for
.
- content_for :page_title, current_page.data.title # current_page.data.title is the `title` property in your page's front matter
= wrap_layout 'main.haml' do
%article.content
= yield
Finally, in source/posts/my-first-post.html.md
, you can set the title
property in the front matter.
---
title: This is the title of my page!
---
Hello, world!
This results in the following HMTL:
<html>
<head>
<title>This is the title of my page!</title>
</head>
<body>
<article class="content">
<p>Hello, world!</p>
</article>
</body>
</html>