Signal drop!
Relay (operand.online) is unreachable.
Usually, a dropped signal means an upgrade is happening. Hold on!
Sorry, no connección.
Hang in there while we get back on track
Dump your WordPress.
Phase one in ending a long and arduous relationship.
So, you're managing WordPress?
That's a popular thing to be doing!
How long have you had this running?
Oh, how rude of me to ask; probably much longer than you'd like to admit.
Here is how you can quickly back up a WordPress domain - focusing on the content of the pages, rather than the themes & style.
Throughout this guide we'll be making use of the WordPress REST API. Our code samples are prepared using Nushell.
Discover the API.
WordPress relies on a discovery mechanism to communicate each site's public API to one another.
In this example, we use wordpress.org - the same code applies, in theory, to any wordpress domain.
def "wp base" [domain: string] {
http get --full $domain |
get headers.response |
where name == link |
get value.0 |
parse '<{link}>; rel="https://api.w.org/"' |
get link.0
}
let base = wp base https://wordpress.org | tee { print }
Solid! We have a base URL.
Using the reference, we see that /wp/v2/posts
is the path we need to use.
Depending on how your WordPress has been managed, other nice places to look are:
/wp/v2/pages
/wp/v2/tags
/wp/v2/categories
/wp/v2/comments
/wp/v2/media
/wp/v2/users
Again, see the reference for a more thorough appraisal.
To help us progress here, let's make a couple quick helper functions:
def "wp dump" [base: string, path: string, --form (-f): string = yml] {
let node = [. ($base | url parse | get host) $"($path).($form)" ] |
path join | path expand
mkdir ($node | path dirname)
try { http get ([ $base wp v2 $path ] | path join) | save -f $node }
}
Ready? Here goes.
let base = wp base 'https://wordpress.org'
timeit { [
posts pages comments media users
categories tags taxonomies types statuses
settings themes search plugins
block-types blocks block-renderer block-directory/search
] | each {|label| wp dump $base $label } }
# for a colleague's domain:
# 21sec 895ms 964µs 817ns
Of course, if you prefer a non-yml dump,
pass in one of these extensions under -f
:
➜ scope commands
| where name starts-with "to "
| insert extension { get name | str replace -r "^to " "" | $"*.($in)" }
| select extension name
| rename extension command
╭────┬────────────┬─────────────╮
│ # │ extension │ command │
├────┼────────────┼─────────────┤
│ 0 │ *.csv │ to csv │
│ 1 │ *.html │ to html │
│ 2 │ *.json │ to json │
│ 3 │ *.md │ to md │
│ 4 │ *.msgpack │ to msgpack │
│ 5 │ *.msgpackz │ to msgpackz │
│ 6 │ *.nuon │ to nuon │
│ 7 │ *.text │ to text │
│ 8 │ *.toml │ to toml │
│ 9 │ *.tsv │ to tsv │
│ 10 │ *.xml │ to xml │
│ 11 │ *.yaml │ to yaml │
│ 12 │ *.yml │ to yml │
╰────┴────────────┴─────────────╯
For completeness, here is a multi-format dump:
let base = wp base 'https://wordpress.org'
let labels = [
posts pages comments media users
categories tags taxonomies types statuses
settings themes search plugins
block-types blocks block-renderer block-directory/search
]
let forms = [ csv json yml ]
timeit { $labels | each {|l| $forms | each {|f|
wp dump -f $f $base $l
} } }
Yeah! Such a nice backup already.
➜ tree wordpress.org
wordpress.org
├── block-directory
├── blocks.csv
├── blocks.json
├── blocks.yaml
├── blocks.yml
├── categories.json
├── categories.yaml
├── categories.yml
├── comments.json
├── comments.yaml
├── comments.yml
├── media.json
├── media.yaml
├── media.yml
├── pages.json
├── pages.yaml
├── pages.yml
├── posts.json
├── posts.yaml
├── posts.yml
├── search.json
├── search.yaml
├── search.yml
├── statuses.json
├── statuses.yaml
├── statuses.yml
├── tags.json
├── tags.yaml
├── tags.yml
├── taxonomies.json
├── taxonomies.yaml
├── taxonomies.yml
├── types.json
├── types.yaml
├── types.yml
├── users.json
├── users.yaml
└── users.yml
If you have a local copy of zip
, yay!
zip -r wordpress.zip wordpress.org/*
Since I'm on NixOS I'm going to use a small prefix here:
nix-shell -p zip --run 'zip -r wordpress.zip wordpress.org/*'
Now, I'm going through this process to help a colleague, so this is a good place to email off the ZIP file, to see if she has any issues with how the records came back.
I'm eager to press ahead and look at a few newer CMS options for her! A couple ones I already have my eye on:
Plus, the Awesome SelfHosted page has 40 more options for a CMS upgrade - of course, including WordPress.