Feeds and Things

I mentioned in my last post (New blog, who dis?) about some of the outstanding issues with (re)Bloggy. This post is written a few days later and I've already made great progress.

Issues

There have been a few hiccups, not-limited to:

  1. content other than posts / index page isn't generated
  2. non .md files aren't handle
  3. very specific handlers for loading files
  4. Split between rust struct and the ObjectView impls offered by liquid-rs

The main thing I wanted to address was getting the RSS feeds ready to go but this meant building out a new way of loading files as currently I was only looking for .md files in the _posts directory. Ideally I would be able to run:

$ rebloggy 
Generating site .. 
Output 
  dist/
    index.html
    atom.xml
    feed.xml
    about/ 
        index.html
    p1/
        index.html
    2023/
        01/
            11/
                new-blog-who-dis/
                    index.html
    public/ 
        ...
    

Where this structure can be generated for a given directory and a mix of named _post, _layout etc type dirs and more flexible ./atom.xml or even ./about.md.

I could read through Jekyll and see how they do it but I'm far more interested in learning this for myself and making mistakes along the way.

Gotchas

Rust

There was certainly a lot of roadbumps, some of it was keeping a picture what each part of rebloggy was doing (admittedly that's a nightmare of my own making given it's still all written in main.rs) but also some rust things I was yet to learn.

For instance, did you know you can't pass an optional closure to a function? I wanted to create a generic load_files but then parse the file name differently depending on whether it was a _post or not. I wrote something like this:

fn load_files_with_file_name_parser<F>(
    dir_path: &Path,
    file_name_parser: F,
    site: &Object,
) -> Result<Vec<(FileDetails, String)>, std::io::Error>
where
    F: Fn(&str) -> (Vec<String>, Option<Vec<String>>),
{
        ...
}

This isn't entirely what I wanted but it does the trick, for the case where I don't need to use a file name parser I created a load_files which contains the "default" file name parser impl. (In researching this post I found this article which looks to use a dedicated struct implementing a trait with a default function that's not overridden).

Refactors

Piece by piece I have been refactoring the impl and I now have a pretty good sense of how this will all hang together if I fancy an larger rewrite.

In general now I can handle different file types I can use a more general file parser. I still need to find a better way of working between ObjectView and Yaml etc which are both necessary for building up the picture of the site.

In the future I would like to generate a Page struct which contains everything that's necessary, rather than arrays of different representations of the same file.

Neovim

In the interim I have also updated my VSCode to use Neovim as the backend. For some reason vscode-vim was misbehaving and some of my go-to operations weren't working as expected (undo for some reason was only one operation).

I saw a post on Mastodon (which is great for tech discovery it seems, props to following hashtags) and they mentioned the neovim backend. I had to try it. So far it's working great.

To build, or rebuild?

I think I want to do a bit of a refactor first before trying to build any new functionality, this is mostly code complete from a functionality point of view - just the architecture sucks.

I wondered if I could pull in some SQLite here too and then I can parse everything into a DB, generate templates etc and then dirty check for updates - this would also help with incremental builds etc. That said we're compiling at 110ms on the debug build right now so it's not like it's slow.

First appeared on Trusty Interior, last update 2 Nov 2024