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.
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
//- 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:
- 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
titleproperty, that'll be use to create the
- This means the headings in the markdown will need to start at the second level (
##, or underlined by
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.