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.
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.
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.
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