A stupid (but small) site generator written in Golang mainly for silly blogs
Why not!? There's an insane amount of static site generators already but reinventing the wheel isn't bad to do if it's to see how the wheel works or because you want to constrain yourself when making it.
It feels a little like cheating by putting this after I've made the stuff, but my ideas haven't changed too much from the start. I wanted to make a markdown->html generator in less than 200 lines of (formatted) Golang that did not rely on external dependencies. I knew I would have to throw out a chunk of valid markdown and only use a subset. I definitely wanted anchor tags and embedded images, along with headers for a minimum. Aside from that, I was fairly fluid on other details.
Stuff I was able to fit into 200 lines: headers, links,bolded underlined, italics, strikethrough, all together now and images, The title text would go here for this sample image and now
console.log("hello world")
!
To have nice http display, the program generates a folder with the name of the file and then creates an index.html. This is so the end result can be accessed as www.example.org/example/
instead of www.example.org/example.html
. The posts folder is given special treatment but any other folder can be used as a regular endpoint (about, contact and such pages).
Posts are ordered by last date modified
A lot of features I wanted to support wouldn't fit in the constraint I gave myself (aside from all missing markdown like lists and tables)
Code blocks are not implemented but can be cheesed in through the markdown. A warning that it will be extremely annnoying and removes the readability of unprocessed markdown (defeating an important feature markdown has but this had to be accepted)
I implemented most of the stuff with some simple regex rules, but Golang does not support some of the required expressions I need to be able to do escape chars in a 1 chunk of regex (which would probably have its own bugs but didn't think too much about it). I could do it without the extended regex but would need to add some lines and I didn't think it would be used that often.
Adding a config reader would add way too many lines that I can't afford to spend on just increasing developer experience. I had to hardcode several features forming a 'fake' config but I conceded that as a neccessary evil for keeping the limit.
Code blocks with automatic syntax highlighting would be great (and should only be a few lines) but at the time of writing this, I have 199 lines so very little to spare.
I originally wanted to include the dates next to the title on the index page, but couldn't really manage without introducing some more lines. I already have the modified time accessible easily but I would need to change some function signatures around and mess with stuff
As with most code I write, there's always issues that can be seen and make you twitch
I mentioned this above, but not having the ability to have a nice config format really kills you inside. It means the markdown files need to follow a very specific format that isn't very untuitive at first glance and I think that tends to be bad and easily leads to issues later.
The markdown file 'spec' (if you can call it that) for MFSSG is the template location, followed by the title of the page, and finally the content
This is a slight issue which can be resolved but I would still consider it an existing issue. To simulate static assets, one would link to them such as '/static/foobar.png' in the markdown. In the out directory (which is hardcoded), one would make a directory (static) and place the file there. Since MFSSG doesn't delete files, they would be there permanently. It's an ok fix so I'm alright with it
I fixed this, so I'm happy. Now the data can be in a /static/
folder at the root level and it'll auto get copied over. Then just link it in the html or markdown as /static/
In my makeFile function (which renders the templates) that is called for each markdown file, it gets passed a slice of previous Pages. The issue is that the list is only used for the index page and if it is called before all the posts, the posts that follow will be excluded.
I've tried to mitigate this (in getFiles) by doing two things. By making it recursive, and adding files at the end while adding directories instantly. So what should happen is that it sees the index file (and any others in the root) and the posts dir. The index file gets added to a temp slice while the posts' files get appended to the outgoing slice immediately. then the temp slice gets appended to the outgoing allowing the sub-directories contents to be put before the current directories'.
I'm not sure if this might have unintended behavior because of how naive it is, but I was pretty proud of solving it like this since it was a 'dense' solution (solving a large problem in a few lines).
Not sure if you can call it injection or XSS but anyway, the markdown isn't escaped. So putting any raw html in the markdown will be left as html and work. I could be sneaky and call this a feature to supplement all the other features I left behind, but I really don't like that. I would rather have needed features implemented than leave an option to allow raw html
It should be a fairly easy fix, but once again it's too many lines to allow it
I'd like to make a more fully featured SSG (probably in Golang because this was pretty fun) but I think I'll use this and see how far I can push it before I feel like I need to switch.