Moving from Medium

31st Jan '234 of your Earth minutes

I finally did it! I took the plunge and am running my own blog.

It's been many years since I ran my own site 'properly'. And now that it's practically free, it was about time.

For the eagle-eyed among you, you'll know that I sporadically published content to Medium. But with the sheer volume of content there—plus their approach to paywalling–I've really lost the desire to publish there.

There was a time when the writing experience on Medium truly was delightful, but I think that has disappeared too.

I'm sure it will do well for a while longer, but it's just not for me.

I haven't shut my account there down completely yet, but I'm sure it won't be long before I do.

But I am (at least to some degree) proud of the few things I wrote on there. So I wanted to make sure I kept those articles around.

I also have a lot of very old articles on Blogger that I've never done anything with. I'm sure there's some cringey nonsense in there.

What this runs on

I decided back in September '22 to pull all of my Medium content down using their export tool.

My site has been a Statamic-based, statically-generated, Netlify-served thing just for the homepage for almost 3 years, so it was about time I gave it something else to do.

I put all of the files from Medium's download into a folder and wrote a simple command:

1<?php
2 
3namespace App\Console\Commands;
4 
5use Illuminate\Console\Command;
6use Illuminate\Support\Facades\File;
7use Illuminate\Support\Facades\Storage;
8use Illuminate\Support\Str;
9use League\HTMLToMarkdown\HtmlConverter;
10use Statamic\Facades\YAML;
11 
12class MediumConverter extends Command
13{
14 /**
15 * The name and signature of the console command.
16 *
17 * @var string
18 */
19 protected $signature = 'convert:medium';
20 
21 /**
22 * The console command description.
23 *
24 * @var string
25 */
26 protected $description = 'Command description';
27 
28 /**
29 * Create a new command instance.
30 *
31 * @return void
32 */
33 public function __construct()
34 {
35 parent::__construct();
36 }
37 
38 /**
39 * Execute the console command.
40 *
41 * @return int
42 */
43 public function handle()
44 {
45 $converter = new HtmlConverter(['strip_tags' => true]);
46 
47 $files = Storage::files('medium-posts');
48 
49 foreach ($files as $file) {
50 // Make the filename Statamic friendly
51 $filename = Str::beforeLast(Str::replaceFirst('_', '.', Str::lower(File::name($file))), '-').'.md';
52 
53 $published = true;
54 
55 if (Str::startsWith($filename, 'draft')) {
56 $published = false;
57 
58 // Strip 'draft' from the filename
59 $filename = Str::replaceFirst('draft', date('Y-m-d'), $filename);
60 }
61 
62 $slug = Str::after($filename, '.');
63 
64 // Clear out the Medium CSS and meta
65 $html = preg_replace('/\<head\>.*\<\/head\>/ims', '', Storage::get($file));
66 
67 $markdown = $converter->convert($html);
68 
69 $collection = collect(explode("\n", $markdown));
70 
71 $title = $collection->shift();
72 $id = (string) Str::uuid();
73 
74 $collection = $collection->skipUntil(function ($item) {
75 return Str::endsWith($item, '---');
76 });
77 
78 $subtitle = trim(Str::replace('---', '', $collection->shift()));
79 
80 // Remove the Medium footer
81 $collection->pop(8);
82 
83 $markdown = $collection->implode("\n");
84 
85 $frontmatter = YAML::dumpFrontMatter(compact('id', 'title', 'subtitle', 'published'));
86 
87 File::put(base_path("content/collections/articles/{$filename}"), $frontmatter.$markdown);
88 }
89 
90 return 0;
91 }
92}

This did enough to create all of the posts in a format that Statamic would be happy with.

I then needed to go through and do a few chunks of manual cleanup (some of which I could have made a part of this command, but 🤷🏻‍♂️) - this was essentially a bunch of 'find and replace' in my IDE.

I've added a few styles and adjusted things for better reading and that's it. I haven't moved any images anywhere yet.

My cheap and cheerful, self-hosted blog, backed by a fully-fledged CMS and hosted for free.

The best part? I can completely craft the editor experience I want. I write content and save it locally, so I don't need an internet connection just to write. When I'm ready to publish, I just commit and push via Git.

What's more, I can do all of that from the CMS itself thanks to my Statamic Git add-on!

Even better: everyone can read my content without hitting some signup process or banners all over the place.

Beautiful

#notadesigner • #sometimesitworks

All content licensed CC BY-SA 4.0  •  Code highlighting by Torchlight