Blog navigation

Last time I've added a page header and a page title to the rendering so the site can be navigated in a basic fashion. Adding those was possible because I added a render context that enables the rendering process to access more information it needs for rendering. The header works well for global navigation but I wanted to add a way to navigate between the blog articles.

At the moment we have a helper for creating a blog overview page. But the blog is an important entity on this site so I added a dedicated class to reify that. We use the new class in the build process like this

 FOBlog posts: (self root / #blog) allPages

The blog object is an important object we can use throughout the building. So I need to put at a more central place. I've added a properties dictionary to the website where I can store all sorts of objects that are used by the building and rendering but are not rendered themselves. With a few helper methods

blog
 ^ self propertyAt: #blog
 
blog: aFOBlog 
 self 
  propertyAt: #blog 
  put: aFOBlog 

it can be attached to the website object for further usage. Now that we have a blog object containing all our posts we can detect the order of the posts. In the blog object there is

FOBlog>>#sortedByPublishDate
 ^ self publishedPosts 
  sorted: #publishDate ascending

With the chronological sorted list of posts we are not able to acquire previous and next posts.

FOBlog>>#postBefore: aFOPillarPage 
 | list index |
 list := self sortedByPublishDate.
 index := list indexOf: aFOPillarPage.
 ^ (index > 1)
  ifTrue: [ list at: index - 1 ]
  ifFalse: [ nil ]

We just need one of the posts as an argument and can figure out which is the previous one. To add this to the rendering process all that is needed is

FORenderContext>>#previousPost 
 ^ website blog postBefore: self page

The render context knows the page it is rendering so it can give it to the blog for inquiring previous and next blog posts. Next step is to embed this into the HTML templates to make it visible.

In the blog template we add a new row with skeleton and add the mustache magic.

   <div class="row">
      <div class="three columns">
      {{# previousPost }}
          &lt;-- <a href="{{ pathString }}">{{title}}</a>
      {{/ previousPost }}

If the {{# previousPost }} marker is reached mustache calls the previousPost method we see above and we get back the blog post. The mustache section marker also changes the context to the blog post previousPost has returned. So if {{ pathString }} is evaluated it is being called on the blog post object returning the URI path to that post. Same goes for the {{ title }} marker that will get the title of the blog post in the context.

The mustache section marker does more for us. If the object that is returned by calling previousPost is nil then the whole section is just skipped which is exactly what we want: On the first blog post there should be no previous link and on the last post no next blog post link.

This went pretty quick to add it. It just needs a bit of polishing CSS wise but the functionality is there. With this addition to the code we left the context of a single page and started to add stuff between posts. The whole website model was created exactly for that purpose