A render context for a header

The last milestone improved the blog generation situation significantly. A model on which I can operate has certain advantages I do not want to miss. After writing the article I refactored the website model a bit further to separate reading from disk and model objects more. There is no microdown page in the model anymore because it is converted to pillar and that should be the central page model.

With the new model I can generate dynamic content and place it somewhere in the site. But I still lack navigation support to make the pages reachable. Until now there is the entry page and back links to the former pages but not more. In order to have an about page that is reachable a navigation header would be useful.

Page template structure

At the moment I have one template for the rendering of a blog post. The template contains the HTML head section and basic setup of the skeleton grid. In the center I have the { { body } } mustache marker to embed the content rendered from pillar. But having multiple pages like an about page raise the need to have more than a single template. Having more than one template raises the need for managing common page parts.

By using mustache partials I can easily achieve this . Let's take the example from the mustache page

templateString := '<h2>Names</h2>
{{# names }}
    {{> user }}
{{/ names }}'.
userTemplateString := '<strong>{{name}}</strong>'.
templateString asMustacheTemplate
    value: {
       'names' {
           { 'name' -> 'Username' } asDictionary } } asDictionary
    partials: {'user' ->  userTemplateString} asDictionary

We can call mustache with partials, a dictionary with more HTML templates. The syntax { { > partial } } embeds the partial with that name.

Mustache takes as the value for template either a dictionary or an object. The difference is the usage of an accessor. In the dictionary case it will access it with #at: key and if it is an object it accesses it by calling #perform: selector on the object. For the partials it must be dictionary meaning the object we give it for the partials will be accessed with #at:.

I make use of this by providing two special objects to mustache for rendering.

A render context as template value

FORenderContext>>#renderTemplate: mustacheTemplate
 ^ mustacheTemplate 
  value: self 
  partials: self partials.

When rendering a page the FORenderContext uses itself as an argument to the mustache template. Every property that is accessed by mustache will be called on that object. We can now put every information there we need for rendering. The last articles had a dummy page title because I had no way to change that. Now I've put the page object in the FORenderContext and made it accessible by calling the #page method.

Mustache can have nested calls by using a . (dot) between properties. This way I can use in the head section the following

<title>{{page.title}}</title>

to have mustache calle #page on the render context and title on the object that is returned. This makes it quite easy to collect enough context information for rendering.

Partials for common rendering parts

The FORenderContext also returns another object that we can use as partials argument for mustache

FORenderContext>>#partials 
 ^ FOPartialProvider new 
  layout: page layout; 
  website: website

And in the PartialProvider I added

FOPartialProvider>>#at: key
 ^ (website templatePathForLayout: layout partial: key) asMustacheTemplate 

If we now use something like

<body>
{{> page_header }}

it will look up a file called page_header in the template directory and uses it as embedded template.This way we can have templates and their partials just on disk next to each other.

By introducing the render context object and the partials provide I can now have common parts in the site and render more information into each individual page. With the header I can now have the about accessible