iCalvin.org

Static Blog Generator In Swift

I was inspired by micro.blog, a Kickstarter project I found this week, to try to move from posting on Twitter & Facebook to a self-hosted blog. I really liked the idea of maintaining my own content, but also the ability to control comments to weed out trolls is really appealing.

I started by looking into existing projects like jekyll but I had a lot of trouble getting it configured like I wanted to. Jekyll seems to be focused more about generating an entire website to host blog content, but I didn't really want to gut and re-write my website twice in a few months, and it was more difficult that I imagined to simply get Jekyll to output a few pages that would link well to the rest of the website.

I ended up deciding to write my own, which I've done before to varying degrees of success in PHP, but it seemed silly to rewrite all I had done before in a language that I really don't have too much interest in doing much more in. So I figured it'd be a good oppertunity to get more Swift experience, and try taking advantage of the open source Swift compiler for Linux at the same time.

I've done a couple Swift projects in the past, mostly just small personal project applications and small data model classes at work. At this point I'm pretty comfortable with the language, but it's still difficult to write code without Xcode autocomplete helping me along. They decided to include Foundation in the open source implementation of Swift though, which really helps keep things familiar. I was able to use the FileManager classes I'm familiar with from iOS for instance, rather than having to find a project that replicates the functionality.

There's a more technical write up of the project in the projects page, so check it out if you're interested. It was a fun experience writing this up, but I'm gonna want to figuere out a few ways to improve the process, first and foremost I need to iron out my process for working on this.

Essentially I was writing the Swift code from a local Xcode project, then I would save the files, run a scp to my home directory to copy the source files over, and the ssh from a different terminal tab to execute and run the project. To manage the template files I would just use vim to edit the HTML directly, which is not my favorite way to edit HTML.

The next time I need to do any work on the project I think I'm going to install the Swift compiler to my Mac and copy over the entire website to a local folder (I do have a local backup, but was not using it for active work) where I can do all of the work until it's 100% done and I can upload it then. There were a few hours yesterday where my home page showed {BLOG_CONTENT} instead of any actual content, so that's less than ideal. I'm also considering just adding the entire website to git so I can manage it that way. There's plenty of options that I think I'm going to decide on in the next couple of days.

All in all I'm very pleased with the experience. Swift on the server worked very well, but I did find some weird behavior that made things more difficult that I would have liked. It seems like some methods from Foundation aren't quite working yet.

To read the HTML content from files I was using the String.init(contentsOfFile:usedEncoding:) initializer, but when I tried to compile it I got a message saying >fatal error: init(contentsOfFile:usedEncoding:) is not yet implemented: file Foundation/NSString.swift, line 1255. As annoying as that was I was happy that it gave a very clear message and I was able to find a workaround by using NSString instead, which was included as part of Foundation.

What worked less well was NSString.replacingOccurrences(of:with:). I had to run it in two places, replacing a placeholder in a blog post preview with the URL that directs to the full post, and in the landing page of the site where I would replace a placeholder with the last five blog posts. It worked fine the first time, but the second time would cause a crash. I spent a good while trying to figure out what was going on and wasn't able to get anywhere and had to find a workaround. Rather than having a indexTemplate.html file with a placeholder for the blog content I created two files, indexHeaderTemplate.html & indexFooterTemplate.html, and I would create the index.html file by writing {indexHeaderTemplate.html}+blogContent+{indexFooterTemplate.html}.

I'm going to do a bit more research into the problem and do a thourough write up and potentially add an issue to the Swift project on GitHub.

So anyway, long story short, I should be posting here a bit more regularly once I make some apps for Mac & iOS that allow me to write up posts, upload them as HTML files, and rebuild the website automatically. Still plenty of work to be done, but I'm feeling good about the project and am glad I was able to take advantage of Swift some more.