Rivulets
2020-02-10 20:25
Each Markdown page I'm creating has an optional meta data header with at least four possible fields that we can use to make nice HTML pages.

I Muck With MetaData

Each Markdown page I'm creating has an optional meta data header with at least four possible fields that we can use to make nice HTML pages.

For example:



---
date: 2020-02-06 10:24
description: Announcing Bill's Blog 
image:images/BillProfilePicWithHat.jpeg
tags: blog, technical
---
 

Except for the image, it's all pretty obvious. The various datum are available to personalize the HTML generaation.

In my world, there will be a lot of entries without images, so the layout might need adjustment accordingly. We'll try to bury that inside

I decided that if image metadata is present, I'll try to display that in every possible contexts, but with different styles,

I ended up defining a few Plot like functions that generate Nodes from the metadata, and then got this deployed in a few contexts including the basic Blog/Stream pages that Publish will generate.

Altering the CSS is not a simple matter of changing a file.

Instead, we need to tweak the swift code

try BillsBlog().publish(withTheme: .billsblog)

extension Theme where Site == BillsBlog {
// a custom theme for bands
static var billsblog: Self {
    Theme(
        htmlFactory: BillsBlogHtmlFactory(),
        resourcePaths: ["Resources/blogtheme/billsblogstyles.css"]
    )
}
private struct BillsBlogHtmlFactory: HTMLFactory {
 

While this might get done without much knowledge of swift, the body of BillsBlogHtmlFactory needs to get inserted. I took it from the FoundationHTMLFactory in the Theme+Foundation.swift file built into Publish .

⛑ I note that I had some trouble getting this to compile until I actually moved the Theme into another file. After adjusting the css files everywhere, I tweaked the bodies of some of the Publish code so that was more to my liking.

One of the things thats completely tweakable now is the homepage, so I used Plot (also by Mr Sundell) to write the swift/html code to my liking. I wrote a bit of Swift to make a .someItems function to limit the number recent posts displayed on the page.



fileprivate extension SortOrder {
    func makeASorter<T, V: Comparable>(
        forKeyPath keyPath: KeyPath<T, V>
    ) -> (T, T) -> Bool {
        switch self {
        case .ascending:
            return {
                $0[keyPath: keyPath] < $1[keyPath: keyPath]
            }
        case .descending:
            return {
                $0[keyPath: keyPath] > $1[keyPath: keyPath]
            }
        }
    }
}

extension PublishingContext  {
    /// Return someitems within this website, sorted by a given key path.
    ///  - parameter max: Max Number of items to return
    /// - parameter sortingKeyPath: The key path to sort the items by.
    /// - parameter order: The order to use when sorting the items.
    
    
   public func someItems<T: Comparable>(max:Int,
                                  sortedBy sortingKeyPath: KeyPath<Item<Site>, T>,
                                  order: SortOrder = .ascending
    ) -> [Item<Site>] {
        let items = sections.flatMap { $0.items }
        let x = items.sorted(
            by: order.makeASorter(forKeyPath: sortingKeyPath))
        return x.dropLast((x.count-max)>0 ? x.count-max : 0)
    }
}

To change the header and footer for each page I had to do even more Swift copy and tweak to rewrite these Node methods to my liking. I ended up rewriting the header completely, and moved things around inside a list of items. These are not hard things to do with Plot once you get it all functionally connected.

Tagged with: