Rendering posts differently
Articles, or posts as I unfortunately named them at the time (so that's how the code will refer to them further on), need a slightly different rendering than the pages. Not only should the site header and footer be consistent with the rest of the site, the structure of the content should also be consistent from one article to another: title, date and then the text of the article itself.
Let's see how to get to it!
Picking a different layout
The layout is handled by metalsmith-layout
. It comes with a built-in option to pick a specific layout for a page looking at its layout
property. This makes having the posts use a different layout a matter of adding that property in each front-matter.
---
layout: post.pug
---
Voilà! It could be automated further later on, assigning the layout based on the path of the file, for example. But for now it'll do. The articles will have a layout of their own… once that layouts/post.pug
exists that is.
Reusing layouts
The site-wide layout is already defined in layouts/site.pug
. Thanks to Pug's extending capabilities (like most template languages have), we can reuse that for the post layout. This will ensure any site wide change will also be reflected on the post pages, without us having to edit two files (or more if the number of custom layouts grows).
This requires to tweak the site layout a bit. For now, it simply outputs the contents
property inside the <body>
.
//- layouts/site.pug
//- ...
body
!= contents
//- ...
To allow extending layouts to tweak what goes in the body, it'll need to define a block
(let's name it contents
) that they'll then fill. If none is given (like when the layout is not being extended, on regular pages), it'll default to outputing the content like it does now:
//- layouts/site.pug
//- ...
body
block contents
!= contents
//-...
Now the site template is ready, we can create the layouts/post.pug
template that sets a common structure to all the posts:
- Title
- Date (for now, let's leave it out for a future article)
- Content of the post
//- layouts/posts.pug
//- Re-use the site.pug layout, note the lack of `.pug`
extend site
//- Pass the parent layout what goes in the `contents` block
block contents
h1= title
//- Date will come here in a future article ;)
!= contents
The layout is ready for displaying the articles now. Its code implies two constraints for the files that'll store the posts contents though:
- They'll need to provide a
title
property, that'll be use to create the<h1>
tag - This means the headings in the markdown will need to start at the second level (
##
, or underlined by---
instead of===
)
We can actually take advantage of that title
property to do something long overdue: set the document's title that appears in the browser tab.
Updating the title
When creating the site layout, that bit was [left out with a promise to take care of it later][../shared-layout/]. It's now time to make sure each page has its own title. It's very important as it helps user understand where they are on the site.
As it's a site-wide thing, it'll go in the layouts/site.pug
file. There we can set the <title>
tag to be prefixed by that title
property if it exists:
//- ...
//- Replacing `title Romaric Pascal`
title
if title
= title
= ' - ' //- To ensure the spaced do get there
= "Romaric Pascal" //- Otherwise it tries to create a <Romaric> tag
//- ...
This gives the articles their own layout and fixes a basic accessibility issue. Remains displaying the date of the article, which will be the topic of next article as internationalisation brings its lots of challenge there.