Mac OS X,  Mac OS X Server

Migrating Data From The Apple Wiki Server

“Taking a new step, uttering a new word, is what people fear most.”
― Fyodor Dostoyevsky, Crime and Punishment

The Apple Wiki Server is sadly going away. I always liked this service. It was thoughtfully designed and looked much nicer than most of the other tools available out there. Sure, you couldn’t write articles offline, write in markdown, or do a lot of other things that I’ve learned to both love and hate from other solutions, but honestly it always felt the most Apple of services in macOS Server because it didn’t have every-single-checkbox. So, I’ll pour a little Jaëger on the ground in memory of the wiki server and then… export some stuffs and move on.

Before we get started, let’s talk about where you’re going to be putting this stuff. You can export in three formats (in order of the likelihood you’ll use them): 

  • wxr: the native WordPress format that can also be used by a variety of other solutions as WordPress is their reference competitor of sorts. WordPress also has wiki plugins, which you could experiment once you’ve imported all of your stuff. ExpressionEngine, Drupal, and many other solutions support importing via the wxr format. For importing into confluence check out https://wiki.afm.co/display/PUBL/HOW+to+import+Wordpress+into+Confluence which requires you to run your own server temporarily if your ultimate goal is to move to the Atlassian Cloud (which is pretty much what I ended up doing). 
  • pages: A folder that stores static html, rather than the dynamic html files that the wiki services builds. You might use this if you just want to take a permanent archive of the wiki service and maybe hire an intern to cut/copy/paste pages into a new wiki solution, like Confluence. 
  • json: If you’re going to be scripting a custom import into another solution then json is likely to be your best bet. I blame python. There are more modules than I can count to import that assist with manipulating json. If another wiki or documentation tool has an import option, you can find a way to get it in. You’ll likely encounter broken links, etc. Unless you correct those in the script during import. Which is a lot of logic. 
  • legacy: Uses PostgreSQL. Probably not useful for a lot of people. I’ve done some work reverse engineering that database, but it changes routinely and so that work is put out of date at regular intervals.
  • decoded: A more swifty export. I think I’d just use this if I were building a swift app based on my export. Which I can’t imagine doing.

The export command is now built into wikiadmin (unlike a couple of previous articles I wrote where it was a standalone command back in the 10.5 or 10.6 era). So to export, you’ll run wikiadmin followed by the export verb. The next option you’ll provide in the command is either -all or the -name of the wiki (multiple wikis can be provided with  comma separated values) and then the -format you’re exporting into (listed above), and finally the -path of the destination. To put that all together, would look like the following if we’re exporting into WordPress: 

sudo /Applications/Server.app/Contents/ServerRoot/usr/bin/wikiadmin export -name Legal -format wxr -path /exports

Exports will be owned by _teamserver so to get to the data, you’ll have to chmod the files:

sudo chmod -R /exports

Inside that target directory, you’ll see a number of files as you can see in the following screenshot:

So, for wxr there will be a directory called wiki that doesn’t have much in it. And then there will be an xml file for each user that has a “page” as well as another with all the articles in it. You’ll need to look at them, but typically the biggest and last one exported (so the last one in the directory listing) will have all your articles.

Once you have the correct XML file, you can import it! To do so, go to WordPress, hover over tools in the sidebar and click on Import. At the import screen, select the xml file, and then click on the “Upload file and import” button.

Note: If the import fails, you may have to edit your php.ini to increase post_max_size or upload_max_filesize. But once the import is complete, I’d change those back to the defaults.

Now, let’s say instead I was going to json. In the following iteration of the earlier command, I’m going to do -all and then I’m going to do json as the -format:

sudo /Applications/Server.app/Contents/ServerRoot/usr/bin/wikiadmin export -all -format json -path /exports

This output starts as follows (I left off the subsequent articles:

{

  “LongName” : “Legal”,

  “UpdateTime” : “2018-02-09T08:37:41.691-0600”,

  “Description” : “test”,

  “ExportDate” : “2018-02-09 16:06:51 +0000”,

  “Revision” : 1,

  “UpdatedByLogin” : “charles.edge”,

  “BlogPosts” : [

  ],

  “Theme” : “carbon,,”,

  “WikiUID” : “c7de0acb-baae-baae-e9bd-f78d3e4d43ed”,

  “ShortName” : “legal”,

  “Pages” : [

{

  “LongName” : “test page 1”,

  “UpdateTime” : “2018-02-09T08:38:32.025-0600”,

  “UpdatedByLogin” : “charles.edge”,

  “Revision” : 3,

  “PageTextValue” : “To edit this page, click the Edit (pencil) button. To delete this page, click the Action (gear) button and choose Delete. When you edit this page, you can easily rename the page, and use the editing toolbar to: Apply paragraph or character styles to text. Create bulleted lists, numbered lists, and tables. Insert media, such as images, audio, or QuickTime movies. Attach files. Insert an HTML snippet from another website or email. For more information about editing pages, click the Action (gear) button and choose Help. 1 1”,

  “TinyID” : “x4j836N4C”,

  “Tags” : [

” test”,

“wtf”

  ],

  “CreateTime” : “2018-02-09T08:38:07.039-0600”,

  “RelatedItems” : [

{

  “LongName” : “Legal”,

  “UID” : “c7de0acb-baae-baae-c6c2-aae392690186”

}

  ],

  “CreatedByLogin” : “charles.edge”,

  “RenderedPage” : “<div id=\”text-block-view-24c701f8-0e15-49a7-b331-f8b755cb6a32\” class=\”block wrapchrome text\” data-guid=\”24c701f8-0e15-49a7-b331-f8b755cb6a32\” data-type=\”text\” contenteditable=\”false\”><div id=\”text-block-view-24c701f8-0e15-49a7-b331-f8b755cb6a32-wrapper\” class=\”wrapper wrapchrome\”><div id=\”text-block-view-24c701f8-0e15-49a7-b331-f8b755cb6a32-inner\” class=\”inner wrapchrome\”><div class=\”content selectable wrapchrome\”><div id=\”text-block-view-24c701f8-0e15-49a7-b331-f8b755cb6a32-editable\” class=\”editable wrapchrome\”><p>To edit this page, click the Edit (pencil) button. To delete this page, click the Action (gear) button and choose Delete.<\/p><p>When you edit this page, you can easily rename the page, and use the editing toolbar to:<\/p><ul><li>Apply paragraph or character styles to text.<\/li><li>Create bulleted lists, numbered lists, and tables.<\/li><li>Insert media, such as images, audio, or QuickTime movies.<\/li><li>Attach files.<\/li><li>Insert an HTML snippet from another website or email.<\/li><\/ul><p>For more information about editing pages, click the Action (gear) button and choose Help. 1 1<\/p><\/div><\/div><\/div><\/div><\/div>”,

  “RevisionHistory” : [

{

  “ChangedByLogin” : “charles.edge”,

  “Version” : 1,

  “PageTextValue” : “”,

  “RenderedPage” : “<div class=\”block text\”><div class=\”content\”><div class=\”editable\”><p>To edit this page, click the Edit (pencil) button. To delete this page, click the Action (gear) button and choose Delete.<\/p><p>When you edit this page, you can easily rename the page, and use the editing toolbar to:<\/p><ul><li>Apply paragraph or character styles to text.<\/li><li>Create bulleted lists, numbered lists, and tables.<\/li><li>Insert media, such as images, audio, or QuickTime movies.<\/li><li>Attach files.<\/li><li>Insert an HTML snippet from another website or email.<\/li><\/ul><p>For more information about editing pages, click the Action (gear) button and choose Help.<\/p><\/div><\/div><\/div>”,

  “ChangeType” : “create”,

  “ChangeTime” : “2018-02-09T08:38:07.039-0600”

},

{

  “ChangedByLogin” : “charles.edge”,

  “Version” : 2,

  “PageTextValue” : “To edit this page, click the Edit (pencil) button. To delete this page, click the Action (gear) button and choose Delete. When you edit this page, you can easily rename the page, and use the editing toolbar to: Apply paragraph or character styles to text. Create bulleted lists, numbered lists, and tables. Insert media, such as images, audio, or QuickTime movies. Attach files. Insert an HTML snippet from another website or email. For more information about editing pages, click the Action (gear) button and choose Help. 1”,

  “RenderedPage” : “<div id=\”text-block-view-24c701f8-0e15-49a7-b331-f8b755cb6a32\” class=\”block wrapchrome text\” data-guid=\”24c701f8-0e15-49a7-b331-f8b755cb6a32\” data-type=\”text\” contenteditable=\”false\”><div id=\”text-block-view-24c701f8-0e15-49a7-b331-f8b755cb6a32-wrapper\” class=\”wrapper wrapchrome\”><div id=\”text-block-view-24c701f8-0e15-49a7-b331-f8b755cb6a32-inner\” class=\”inner wrapchrome\”><div class=\”content selectable wrapchrome\”><div id=\”text-block-view-24c701f8-0e15-49a7-b331-f8b755cb6a32-editable\” class=\”editable wrapchrome\”><p>To edit this page, click the Edit (pencil) button. To delete this page, click the Action (gear) button and choose Delete.<\/p><p>When you edit this page, you can easily rename the page, and use the editing toolbar to:<\/p><ul><li>Apply paragraph or character styles to text.<\/li><li>Create bulleted lists, numbered lists, and tables.<\/li><li>Insert media, such as images, audio, or QuickTime movies.<\/li><li>Attach files.<\/li><li>Insert an HTML snippet from another website or email.<\/li><\/ul><p>For more information about editing pages, click the Action (gear) button and choose Help. 1<\/p><\/div><\/div><\/div><\/div><\/div>”,

  “ChangeType” : “edit”,

  “ChangeTime” : “2018-02-09T08:38:26.194-0600”

},

There’s a glaring omission in this article: files. I’ll get to that later in another article. But the gist is that you can do a webdav and move them, but you kinda’ break any links…

Finally, if I came up short in this article (as I often do), the official wikiadmin man page: 

wikiadmin export -name somewiki,anotherwiki -path /var/tmp/two-exported-wikis

wikiadmin import -all -path /var/tmp/two-exported-wikis

wikiadmin import -all -path /var/tmp/two-exported-wikis/Exported.wikis

wikiadmin export -all -format json -path /var/tmp/readable-wikis

wikiadmin export -all -format pages -path /var/tmp/browsable-wikis

wikiadmin export -all -format wxr -path /var/tmp/wxr-wiki-files

wikiadmin migrate -r /Volumes/SnowLeopard/Library/Collaboration

RETURN VALUES

wikiadmin returns a status code of 0 for success. In the event of failure it returns a non-zero status, and writes error messages to stderr.

FILES

/Library/Server/Wiki/Logs/wikiadmin.log

Log file for wikiadmin activity

/Library/Server/Wiki/Logs/collabd.log

Log file for Wiki http server activity

/Library/Server/Wiki/, /tmp/, /var/tmp, /Users/Shared

Folders readable and writable by user _teamsserver where exports can typically be placed

<export-path>/Exported.wikis

The name of the bundle created when exporting wikis for formats other than pages.

<export-path>/FileData/*/*/*

For -format pages – exported files that were uploaded to the wiki as files or embedded in pages

<export-path>/wiki/projects/*/*.html

For -format pages – exported wiki main pages and user profile pages

<export-path>/wiki/pages/*/*.html

For -format pages – exported wiki pages

<export-path>/css/*.css

For -format pages – style sheets for use in browsing the exported content

<export-path>/index.html

For -format pages – a generated landing page with links to all exported wikis and pages

HISTORY

The wikiadmin command first allowed export in macOS Server 3.2. The packaging format for exported wikis was revised with macOS Server 4.1, but the

new wikiadmin still supports importing from the older export formats.

macOS Server March 30, 2017 macOS Server