Show HN: I made a service to convert WordPress blogs to Hugo
wp2hugo.blogdb.orgHi Hacker News!
I made this project to read a WordPress export and create the markdown files for Hugo. It'll speed up the process of moving your blog over to Hugo and let you avoid a bunch of manual work.
It came about when I was talking to somebody who was trying to move their site over and didn't want to manually copy and reformat all their posts. They had trouble finding a tool to do it, so I wrote one.
I want to make sure it's useful to people before charging them, so it'll give you a download with 3 pages and 5 blog posts converted for free and without asking for any information. If you like what you see, there is a one-time charge through Stripe to convert everything.
I hope you find it useful, and I welcome any and all feedback on it!
Thanks for reading!
That's pretty cool! I ported my own WP blog to a static site generator (my own but with a format inspired by Hugo) a while back and hacked together a script with wpparser and some custom code to spit out markdown (it was a while back but I think just regexes). It got me the bulk of the way there but I still had to go through every page and tweak it to get everything just right. Would happily have paid $150 to avoid that.
Are you keeping URLs stable? That was tricky for me IIRC, along with RSS.
(The very trickiest bit was probably specific to me. I still have inbound links with the page in a "/?p=3" kind of query param, which I think was the WordPress default 20-odd years ago. I didn't want to make the root URL for the site non-static to handle that, so I wound up putting some JS in my index page template that checks for that kind of thing. If it spots it, it changes window.location to a specific URL that is delegated a Flask site that knows where to redirect people. Link in bio if anyone wants to see how it works. I should probably blog about it sometime!)
I actually did write this up if it helps anyone... I did something similar, my WordPress site only had ~100 pages, so I just put the page map in a table in the js: https://www.hotelexistence.ca/something-mildly-different/ (my ?p=### script is near the bottom)
> so I wound up putting some JS in my index page template that checks for that kind of thing.
If we are going to use JS, then you might as well put the redirects themselves in JS. Have a tiny stub of JS that detects the "/?p=xxx" case, which can then load the (presumably very large) list of redirects from a separate file and do the redirecting. That'll save you maintaining the extra service.
As for me, I moved from a Django app I made to a Hugo site, but it's pretty much the same deal. Because my Hugo site is on a "real" server (rather than e.g. GitHub Pages) I just have a giant pile of 500+ redirects in the nginx config file for the site (which is checked into the same repo as my Hugo site). It works for me.
That's a nifty idea! I need the extra Flask for some other unrelated stuff, so it's OK as it is, but if it was on GH pages (like you say) that would be super useful.
Thank you for saying so!
That's super awesome too, this is not so different under the hood, I used libxml for getting the content and pandoc for converting -- pandoc turned out to be by far the best of the tools I tried for that aspect.
It won't necessarily keep the URLs stable, they'll be made based on the title of the post.
That's a cool solution for the ?p=<id> issues, this doesn't handle it but when I've done it for for sites I host I usually use nginx's rewrite rules. I think for query rewriting you need to additionally use the map directive, but I was only handling directory vs .html and things like that.
Thank you again for commenting, I like your site!
I may be wrong here, but I understood Hugo sites to be static sites, therefore not supporting comments, for example. How does your tool handle migrating a WordPress side with comments to a Hugo site?
You're right, Hugo is for static sites! Hugo does support comments through things like Disqus (https://gohugo.io/content-management/comments/).
My service only converts the blog posts and pages themself and helps you get started on a conversion.
The vast majority of WordPress sites are static sites with no use for comments.
The vast majority use plugins not available outside of wordpress.
The vast majority use no plugins at all.
They probably use plugins but they dont need them. Like Yoast for SEO etc
Thanks for sharing @symkat, love seeing developer side projects.
Was curious why you picked Hugo over something like Astro. I'm migrating a site off of Jekyll and have found Astro has a lot of interesting features if I want to use them but is at its heart a static site generator and seems to be a pretty easy lift to migrate to. Haven't done much evaluation of Hugo yet.
Thank you for commenting!
Really the reason I picked Hugo is because that's what the person I was talking to wanted. He'd only found contractors who would charge more than he wanted to pay to do a manual conversion, and said even something that just got his pages and posts over would be worthwhile to him.
I have more experience with Jekyll. In fact, I had tried to start a hosted platform with a CMS for it that I opened sourced a while back (https://github.com/symkat/MyJekyllBlog) but it never really got traction.
At this point I'm actively looking for a new job and figured getting this on Hacker News might be helpful for that.
I hadn't heard of Astro before, it looks neat!
I was all about Jekyll 4 or 5 years ago and wouldn't have considered spending time switching but now on modern hardware it is ridiculously difficult to get the jekyll runtime to install and run properly, we've had multiple team members myself included spend hours dealing with hunting down random forum posts or github pull requests outlining the need to downgrade ruby in one way or another to support apple silicon or some other such thing that hasn't been patched in more recent versions. And the Jekyll docker images have been abandoned for a few years and no longer work on arm architectures.
Hopefully moving to a more actively supported static site generator will benefit us but its also a lesson to us that we need to keep track of continued support of apps we rely on. It's easy to just build and forget something and then there's a fire drill when you have to go back and change something that hasn't been re-deployed in a while.
Why did your person want to migrate? Out of curiosity.
I’m not sure about the OP, but I’d choose Hugo over Astro because of the simplicity of the single binary, and the lack of necessity for a JavaScript package manager just to run the thing.
The real money is in converting sites with plugins and retaining the functionality which in many cases isn’t static. The copying of data to another tool is the easy part.
I totally agree. This came about because of a pretty expensive quote the person I was talking to got.
And how do I upload an image of my cat to my all new Hugo site?
WP lets me drag/drop or upload media very very easily. Has done for years.
Hugo? or indeed most SSG's?
You copy it into the same directory as the post you want to put it in, and reference it as a resource from your post. I made a shortcode for this for my own Hugo site, adding auto thumbnailing & WebP support:
https://gist.github.com/lewiscollard/c6651648d1c20144ed89e16...
Copy that into your "layouts/shortcodes/image.html" and use it as
If you just want to upload it to _not_ reference it in a post/page, copy it into your `static` directory and it'll be passed through when the site is built.Hope that helps!
Plain old markdown image syntax also works, although there is no way to preprocess the file or add any additional HTML attributes beyond what you see here:
Yep, that works too. I wrote the shortcode because I didn't want to have to manually resize pictures. That's effort and it means if I change my layout to require wider pictures I have to go find the originals.
I think you could do this with a render hook if you want to get fancy (with the benefit that the Markdown for your posts stays as plain Markdown): https://werat.dev/blog/automatic-image-size-attributes-in-hu...
That’s my main issue with SSG, it’s always a pain.
Isn't this a bit deceiving to call this "WordPress 2 Hugo"?
Because isn't this just "WordPress 2 Markdown".
Unless I'm mistaken, this does not recreate your WordPress theme/template to be used in Hugo (nor nothing specific to Hugo).
It's just exporting your blog posts from WordPress database into a Markdown file format.
Note: still very useful, I just find the name confusing.
Thank you for commenting!
It does put your files into a Hugo directory structure and includes the smol theme. It doesn't recreate your theme, plugins, or process your images, but I also have tried to be very explicit that it just converts your pages and posts and is the starting point for a conversion.
When you put an export file through it, you'll end up on this page: https://imgur.com/a/UUMB6ve where you can download a zip or tgz of the site and you'll clearly understand what you're getting before you can choose if you want to have the remaining pages/posts converted.
WordPress is not just content - it's plugins such as WooCommerce, GiveWP, email marketing, BuddyPress, membership plugins, etc.
not anymore! with this tool, we can get rid of all of that fluff and go straight back to pure content only.
They did specify "WordPress blogs" in the title. Not all WordPress powered sites are blogs.
then this tool is not for them. pretty simple
Part of me was really hoping this was going to be for the Hugo interactive fiction game engine [0]
0: https://www.ifwiki.org/Hugo
That's a great tool! When I migrated from WordPress to Astro before, I used my own custom script for the migration. I think having tools like this is very convenient and useful.
Does it handle themes, plugins, etc., as well? Thx.
It does not, it converts just the blog posts and pages to help you get started on a conversion. It gives you the smol theme by default and the page that gives you access to the downloads gives additional information for finding themes at https://themes.gohugo.io/
$150 haha. Wtf.
This is ~1 hour of software engineer, ~2 hours of technology generalist time. Time is non renewable, and humans have a cost. If you're an agency, business, whatever, and have the need to make something WP static via Hugo, this is a reasonable cost to solve the problem quick.
Makes sense, you're right. I'm glad this single-use static file converter is $150. Thank you.
Pricing and product market fit discovery is a process. Solve the problem, make it maintainable, make it perform. You are on a VC startup accelerator funded forum where a component is encouraging makers and builders to solve problems (sometimes, for money), after all. Encouragement and constructive feedback is both cheap and kind.
[flagged]
Good. But I do wonder why we're flooded with "services" like that when a simple open-source Python script could do this. $150 FFS. I hope you have clients but the open-source dev inside me is dying a bit.
Edit: 413 Request Entity Too Large.
People pay to have their problems solved, not code (although code is one of the ways to solve some problems!). If you made such a service for free, that's great! It's helpful, it scratches an itch to build you have, it is a net positive to put it into the world. Importantly, non technical people want their hand held and usually, are willing to pay for it. Something to consider. There is room for both solutions and code, based on bucketing of use cases and personas.
> non technical people want their hand held
I know but I'm still not happy about it. Also Hugo is not what I would call a WYSIWYG application like Wordpress, so...
https://github.com/ashishb/wp2hugo is pretty good. That said I think there's probably room for a good solution that doesn't require command line proficiency.
In my case, at least a big part of it is I'm looking for a job again and doing something like this to get myself out there, I already had one person who was interested in this specific type of conversion so maybe there are others.
Thanks for the 413 note! I've just upped the client_max_body_size if you want to give it a try again.