Published on

New Blog for 2024

Author

I migrated off of WordPress.com for my blog hosting, to my own blogging software. All the important URLs should remain the same. It looks a bit nicer now, and I've got some other functionality running through here.

Background: WordPress

Originally, I decided to get set up on WP.com in 2020 after a long period of not having a blog at all. I figured WP was good software, and I'd be more likely to write posts if I didn't need to spend my energy constantly updating WordPress. I can do that -- I know how to run it, and I've customized a WordPress MU install pretty heavily for our briefly-run Yasashii Blogs service -- but I don't wanna because it needs a lot of ops work to maintain.

WP was pretty okay. I didnt like not being able to add my own plugins or themes, but I could live with that. There were some powerful features too: the media manager was really great for my posts with big tasting menu galleries. I could bulk-upload from my phone, then crop on my desktop via the media manager's tools, and then easily build galleries right in my posts.

I blogged a reasonable amount in 2020 and 2021, but fell off hard in 2022. You can see the post before this one was six months ago ... whoops!

I'd started to dislike the WordPress Gutenberg editor too. That long Fediverse post required constantly reloading the editor because it would slow down so much. And it was just a text post 🤔

Beginnings: Fedi Bots

The first months of this site's life were an entirely headless Laravel app for running my @gw2updates@botsin.space bot. This was a simple Mastodon bot to read the feed for a specially-prepared invisionboard search on the GW2 forums, and relay posts to the fediverse. There are other bots for their Twitter/blog, but the forums have patch notes that don't get posted elsewhere, so this was a win for the GW2 community on fedi.

Eventually, I added an admin backend written in Filament for managing the bots. Last week, I even built a new bot through the UI: @LastEpochUpdates@botsin.space , for posting news about Last Epoch (coming out Wednesday, woohoo!).

I can turn any collection of RSS feeds into a bot through my admin backend now, so if you want any bots to follow, I can hook that up pretty easily.

The Blog

After the CEO of WordPress (and tumblr) blogged earlier this month about how layoffs are good for employees, actually, I decided it was time to decamp.

The tech stack was Laravel, Tailwind, and Livewire (which is not used on the frontend -- yet -- I have some plans for that). The theme you're looking at is a slightly-customized riff of the Tailwind Nextjs Starter Blog v2.0. It had a good dark mode and looked way better than the WP theme I had ended up on, so I ran with it.

The posts are written in markdown and rendered using league/commonmark, the best PHP markdown library. I added a custom markdown tag to insert my galleries into posts -- each image is a model with some metadata (alt text, caption, etc) that I can organize into a gallery and embed or publish as its own page.

This code is kind of horrifying and I don't want to share it. In retrospect, after using a bunch of CRUD screens to re-make my galleries, I think I would have been happier making a more complicated markdown extension to do the whole gallery in the markdown editor instead. Something like this maybe:

{{{
- ![alt text A](./img-path-1.png "Caption one")
- ![alt text B](./img-path-2.png "Caption two")
- ![alt text C](./img-path-3.png "Caption three")
}}}

The benefit here is that my markdown editor will let me paste images right in...so then it would all be possible from the post editor. It wouldn't be hard to insert that markup into the posts based on their current gallery tags and swap to it, so I may still do that one day.

One upside to having the metadata for images stored in the DB is it's easier to set appropriate tags for thumbnails/etc in opengraph tags, so I'm not sure how I'd deal with that.

One thing I made sure to plug in everywhere was stripping exif data from JPEGs and TIFFs. PHP can do that natively, but you need to know about one simple trick1.

<?php

use Imagick;

class Exif
{
    /**
     * Strips everything but the ICC profiles from the EXIF metadata of relevant images.
     */
    public function stripMetadata(string $filePath): string
    {
        if (! $this->hasMetadata($filePath)) {
            return $filePath;
        }

        $img = new Imagick($filePath);
        if (! $img->valid()) {
            throw new \Exception('Image is not valid');
        }

        $img = $this->strip($img);
        $img->writeImage($filePath);
        $img->clear();
        $img->destroy();

        return $filePath;
    }

    public function hasMetadata(string $filePath): bool
    {
        $contentType = mime_content_type($filePath);
        $typesWithExifMetadata = ['image/jpeg', 'image/tiff'];

        return in_array($contentType, $typesWithExifMetadata, strict: true);
    }

    private function strip(Imagick $image): Imagick
    {
        $profiles = $image->getImageProfiles('icc', true);

        $image->stripImage();

        if(! empty($profiles)) {
            $image->profileImage('icc', $profiles['icc']);
        }

        return $image;
    }
}

Getting this to play nicely with Filament wasn't hard either. For the Markdown editor:

Forms\Components\MarkdownEditor::make('content')
		// ... whatever config ...
		->saveUploadedFileAttachmentsUsing(function (TemporaryUploadedFile $file, Forms\Components\Component $component, Exif $exifTool) {
				$exifTool->stripMetadata($file->path());
				return \Livewire\invade($component)->handleFileAttachmentUpload($file);
		}),

There is an invade() in there, so it's not ideal, but I didn't see a better way to hook that.

Converting Posts

I converted the posts mostly by hand, and took the opportunity to ensure all my images had alt text in their metadata.

I only had a couple posts, so I figured it wouldn't take that long2.

Big shout out to https://mixmark-io.github.io/turndown/ though -- I copied the HTML from the WP post, put it in there, and it got the formatting almost perfect. The WP code blocks with line numbers broke it, but that was easy to clean up.

Future

I have some ideas on stuff I want to add.

The first thing I'll probably do is a thread unroller for fedi. I always liveblog my notes for my Spinach Inquisition TTRPG campaigns on Friday nights, and I think it might be nice to have a tool that'll grab all that content and make it into a draft blog post. The I can clean it up, add a little more context, make it flow better, and use it as a sort of campaign log.

I want to add a projects page and some kinda blogroll/webring/links area.

And I need to make a section just for my various characters in games, campaigns, etc so I can post art and bios and stuff.

There's a fediverse tool I want to add to the site too: something to do lookups on a username and explain how it's resolving it. That's a basic troubleshooting tool ("did you fuck up your webfinger config?") that could be handy to have.

Hopefully I'll be blogging more in the coming months...


  1. Which I didn't know about until I was looking at the comments on the PHP docs. Thanks for the insight about the colour profiles, Max Eremin. 

  2. It took like five hours, so I probably should have just written a script. Welp.