A website model

After the last milestoneon-to-number-2.html) of creating this blog I've chosen a simple approach of page generation. Files in a raw/_ folder are recursed and produced directly into the output directory as HTML. This is straightforward but not what is helpful in the long run. I want this library to be flexible and extensible.

As an object oriented programmer what do we do if we want to manage and modify things? We reify them so they can acquire meaning and we put them together into a model to define their interactions. Just like you would create a story (and you always should!).

What we need as a start:

  • WebSite that contains properties like paths, configuration, etc...
  • WebFolder that can contain other resources and allows us to organize the content in a hierarchical way. The hierarchical naming is being reflected by the hierarchical URI space that defines locatable resources to the outside. But as we are building a static site generator it will is being reflected in filesystem paths as well
  • MicrodownPage that can read microdown and produce a HTML page
  • PillarPage that can handle the pillar docment model and produce a HTML page
  • HTMLPage so we can have manually crafted HTML that more or less copied to the web site
  • Image that reflects images we want to use in the articles

With this basic model we can break up the building of the site into two parts:

  • traversing the filesystem and creating model entities that are placed in our model that almost looks like a virtual filesystem
  • traversing the model and publish HTML pages and binary resources in the output folder

In code this looks now like this

build 
    self importDirectory: self rawPath.
    self publish.

Now that we have broken the process into two parts we can have an arbitrary amount of processing in between.

A blog overview page

At the end of the last milestone I recognized that I can produce blog articels but there is no entry page on the web site. For a blog this is usually a list of abstracts of the latest articles.

The build process of the site now becomes

build 
    | blogOverview |
    self importDirectory: self rawPath.
    blogOverview := FOBlogOverviewBuilder new 
        folder: self root / #blog;
        overviewPage.
    self addResource: (blogOverview 
        path: (RelativePath from: 'index.md')).
    self publish.

After importing the files into our model we add another process for building a blog overview. We hand out the blog folder of our model to our builder defining that all pages in that folder are blog articles we want to have an overview from. The result should be a newly created page containing the overview. At this point we opened the model for in-memory dynamic pages. By adding this newly created page into our model at the location /index.md we are done because the publishing process now picks it up as any other page and produces an HTML page out of it.

The overview builder needs to find out the latest posts in chronological order by doing

publishedPosts
    ^ (folder allPages 
        select: #isPublished)
            sorted: [ :a :b | a publishDate > b publishDate ]

Having the list of posts the builder generates a new page from the blog post pages

overviewPage
    | posts abstracts |
    posts := self publishedPosts.
    abstracts := posts collect: [ :post |
        FOPillarTruncateVisitor new 
            size: 600;
            post: post ].
    ^ FOPillarPage new 
        metaAt: 'layout' put: 'page';
        pillar: (PRDocument new
            setChildren: (abstracts flatCollect: #children);
            yourself)

For every published post it duplicates the structure of the post until it collects up to 600 characters of text. The resulting documents are subsets of the original document. From this new abstract documents it collects all the children and puts them in a new combined document containt the list of abstracts.

That's basically it. With the website model we started not only to break up the building process into something adjustable but we also began to treat everything as a structure that can be parsed, modified and combined. The structures so far are the web site model being a virtual filesystem and the document structure being pillar. For querying purposes the line between the web site model and the document model can be blurred so that we can query the whole structure from web site root down to HTML element.

Now we have an index page and next should be adding a header

<-- On to #2