My personal blog/writing platform has lived in a lot of places over the years. My dedication to contributing to it tends to come in spurts. It’s lived on a lot of platforms over the years. Most recently it’s been hosted on Medium. I decided to migrate from Medium for a hosts of reasons this post isn’t going into and back to my own blog. I landed on using Hugo and hosting it on Netlify.
My primary goal was to take some of my favorite posts from Medium and re-publish them on my new Hugo-powered blog.
My design skills are “curious amateur” level at best. I didn’t create this site from scratch, or anything near it. I actually paid a few dollars for a Hugo theme I liked and have done a little customization on it.
In fact, this admonition box is one of my customizations. My next blog post will likely be about the Hugo shortcodes I’ve added to my site’s codebase so far.
Medium has an export function, but it outputs your content as HTML. Luckily, mediumexporter
has already been created to do this job for us. I found an article, oddly enough on Medium, that outlines its usage. As I began to think about it I decided I needed to build on this very useful one-liner just a little bit more.
If you aren’t used to using Hugo, creating content is handled by the hugo
command line tool. My site uses a blog
category to handle my normal posts, so creating a new blog post would look like this. Notice that I included the file extension to tell Hugo that this was going to be written using markdown.
hugo new blog/new_topic.md
/Users/djamie/Code/jduncan_io/content/blog/new_topic.md created
All content is created inside the content
folder in Hugo. Here’s how I decided to build out my site’s directory structure (the them I used dictated a lot of this structure). You can see content/blog/new_topic.md
was created.
content
├── about
│ └── about.md
├── blog
│ ├── _index.md
│ ├── container_image.md
│ ├── dockercon_2017.md
│ ├── domain_specific_dns_on_macbook.md
│ ├── kube-on-pi.md
│ ├── linux_capabilities.md
│ ├── migrating_to_hugo.md
│ ├── new_topic.md
│ ├── ocp_on_azuregov.md
│ ├── practical_kubernetes_operator.md
│ └── technical_debt.md
├── contact
│ └── _index.md
└── search
└── _index.md
4 directories, 14 files
Hugo adds frontmatter to each newly created markdown file. You can customize how this works using archetypes. When I created my new blog post this frontmatter was automatically generated.
---
title: "New_topic"
date: 2019-12-28T11:56:24-05:00
draft: true
image: "/images/some/path/"
categories:
-
tags:
-
# post type
type: post
---
This is metadata used by Hugo and the templates you create to create logic and stateful information in your site. For example, the image
parameter is used by my theme to set the preview image at the top of each blog post. Additionally, the type
parameter is used to decide if a post ’normal’, or if it’s featured
at the top of my home page. Hugo builds in variable scoping, so the parameters in a post’s frontmatter are valid only for that page, while parameters in your config.toml
or config.yaml
files are scoped to be site-wide. It’s a simple, powerful system.
Now that I have my frontmatter set, I can use mediumexporter
to populate the content.
By default, mediumexporter
takes a URL from a medium post and outputs the content as markdown to STDOUT
. Using a simple redirect I can append this content to my new, empty post from the base directory for my Hugo site.
mediumexporter https://medium.com/@macropus/export-your-medium-posts-to-markdown-b5ccc8cb0050 >> content/blog/new_topic.md
Your new post now looks more like this.
---
title: "New_topic"
date: 2019-12-28T11:56:24-05:00
draft: true
image: "/images/some/path/"
categories:
-
tags:
-
# post type
type: post
---
# Export your Medium posts to Markdown
There’s a simple solution to avoid copy/pasting and re-editing your Medium articles.
![](https://cdn-images-1.medium.com/max/2000/1*i-S80mDrkJQO2tJ_lhYwfA.png)
First of all, you need to install node on your computer.
There is an installer for node for all platforms, just download it and install it like you would any other program:
* [***https://nodejs.org/en/download/](https://nodejs.org/en/download/)***
Once you have this installed, you fire up the **Command Prompt** on **Windows** or **Terminal** on **MacOS** or **Linux** and run this command.
...
You’re close! But you should make a few tweaks to make your content more inline with Hugo best practices.
mediumexporter
tool doesn’t make any changes to it, so you should at least alter the date
parameter to reflect the data you published the content on Medium. At least I think you should.title
parameter to set the title for a post, while mediumexporter
sets the title as a top level markdown heading. So take the top-level (single #
) heading and set it to your Medium post’s title.mediumexporter
tool takes those Medium plugins and converts them to raw HTML.static/images
directory. For each post I create a new sub-directory there to hold the post’s images and graphics.figure
shortcode and created a bootstrap media
shortcode (post upcoming) to format the pictures in my post to look very similar to their appearance on Medium. The figure
shortcode creates HTML5 <figure>
content. The media
shortcode creates bootstrap media objects to quickly format grahpics and text.Making those changes, I was able to take my favorite 6 or 8 Medium posts and pull them into Hugo cleanly in about 45 minutes. I have since added a small script to automate creating a new post and its corresponding images subdirectory.
#! /usr/bin/env bash
ARTICLE=$1
echo "Creating new blog post $1."
hugo new blog/$1.md
echo "Creating directory for images."
mkdir -p static/images/$1
echo "Done. Happy writing."
This is simplistic now, but I’ll keep updating it with things like regex to set the images directory and other fun things. I do love a good helper script.
After working with Hugo on and off for a weekend, I’m quite impressed. It’s easier to extend than most of the other static site generators I’ve worked with in the past. Hugo also is fast and consistent with a vibrant user community to help you work through challenges while you’re getting started.