Goodbye WordPress is a customizable library and command line tool for exporting posts from a WordPress MySQL database to static Markdown or HTML files, with YAML front-matter for metadata preservation. It is intended as a starting point for migrating away from a WordPress blog to a static site.
It further supports saving images referenced in the original posts and can generate a single-file archive of all exported posts in JSON format, in case the export process needs to run again after the MySQL database has been taken down.
This tool was developed to export a very legacy WordPress blog to a static site. As such, only a single database revision has been vetted. It is likely that older and newer versions are supported.
Release | Through | Database Version | ||
---|---|---|---|---|
4.7 | 2016-12-06 | 4.9.15 | 2020-06-10 | 38590 |
Pass --ignore-unsupported-db-versions
to the command line tool to ignore the version check.
Please open a pull request to add other vetted versions MysqlPostReader.
dotnet tool install --global goodbye-wordpress
usage: goodbye-wordpress [OPTIONS] [JSON_INPUT_FILE]
Options:
-?, --help Show this help
-v, --verbose Use verbose logging
-q, --quiet Use quiet logging (errors only); synonym for -v-
Post Options:
-o, --output-dir=VALUE Set the output directory for posts and images
--format=FORMAT Output FORMAT: markdown | html | raw
--serialize-json=FILE Serialize the entire post set to FILE
MySQL Options:
-h, --host=VALUE Connect to host
-P, --port=VALUE Connect through port
-u, --user=VALUE User for login
-p, --password=VALUE Password to use
-D, --database=VALUE Database to use
-i, --ignore-unsupported-db-versions
Ignore unsupported WordPress database versions
goodbye-wordpress \
-h localhost \
-u user \
-p *** \
-D wordpressdb \
-o exported-posts \
--serialize-json exported-posts/archive.json
See the contents of the exported-posts/
directory.
dotnet new console
dotnet add package Goodbye.WordPress
Note that with the exception of ConnectionStringBuilder
and WordPressExporterDelegate
, all types are immutable. For example, to transform a Post
object's content, try post = post with { Content = post.Content.Replace("A", "B") }
.
Creating the exporter via API here is equivalent to the command line invocation above, with the exception of providing a custom exporter delegate that will perform additional processing steps.
using Goodbye.WordPress;
var exporter = WordPressExporter.Create(
postReader: new MysqlPostReader(new ConnectionStringBuilder
{
Host = "localhost",
Username = "user",
Password = "***",
Database = "wordpressdb"
}),
contentOutputDirectory: "exported-posts",
archiveOutputFilePath: "exported-posts/archive.json",
// And now the delegate...
@delegate: new CustomExporterDelegate());
await exporter.ExportAsync();
sealed class CustomExporterDelegate : WordPressExporterDelegate
{
/// <summary>Process post contents</summary>
public override Post ProcessPost(
WordPressExporter exporter,
Post post)
// Perform the default post processing first by calling base
=> base.ProcessPost(exporter, post) with
{
// Then replace '--' with Unicode em dash '—'
Content = post.Content.Replace("--", "—")
};
/// <summary>Add 'CustomMetadata' to each post's YAML front matter</summary>
public override void PopulatePostYamlFrontMatter(
WordPressExporter exporter,
Post post,
SharpYaml.Serialization.YamlMappingNode rootNode)
{
base.PopulatePostYamlFrontMatter(exporter, post, rootNode);
rootNode.Add("CustomMetadata", "Some Value");
}
}