!slug node-red_wordpredd_hexo_migration

!date 2017/05/06

!draft false

!tags Heroku, Node-RED, Wordpress, Hexo, Markdown, Github pages, wpxml2md, hexo-migrator-wordpress, node-red-contrib-markdown, Flow-Based Programming

!! WordpressからHexoへ移行 このブログもとうとう昨年1年間放置してしまっていました。しれっとフェードアウトしようかと思ってたんですがGoogle Analyticsとか見てみると案外過去のエントリが世の役に立っているようなので、もうしばらくメンテナンスしてみます。 ずっとWordpressでやってきましたが随分前から静的ジェネレータ系に移行したいと思ってましたので今回Hexoに移行...

WordpressからHexoへ移行

このブログもとうとう昨年1年間放置してしまっていました。しれっとフェードアウトしようかと思ってたんですがGoogle Analyticsとか見てみると案外過去のエントリが世の役に立っているようなので、もうしばらくメンテナンスしてみます。

ずっとWordpressでやってきましたが随分前から静的ジェネレータ系に移行したいと思ってましたので今回Hexoに移行しました。Markdownでエントリ書いてGithub pagesへDeployすればOKという手軽さは“自分1人のブログ”で使うツールとして最適です。

ちなみにWordpressはHeroku+PostgreSqlでやってきましたがHexoはGithub pagesでやっていきます。

hexo-migrator-wordpressが止まる

ブログ移行の何が大変かって過去のエントリの移行ですが今回もハマりました。hexo-migrator-wordpressという移行ツール使ったんですが、何やら JS-YAML: can not read a block mapping entry; a multiline key may not be an implicit key というようなエラーで途中で止まります。

scaffoldspost.md とかのテンプレートの上部にあるYAMLが何かおかしいらしく、言われた通りに変更すると症状は変わるけど結局YAML部分全削除になって、動いたとしても全エントリのタイトルさえ取り込めない状態で意味が無いので諦めました。

Node-REDで移行Flowを作ってみた

要はWordpressからエクスポートしたXMLをParseして、YAMLの部分とMarkdown化した本文をマージすれば良いので、こういう「やればできるけどモチベーションが上がらない作業」こそNode-REDが向いてる(個人的見解)ということで以下のFlowを作ってみました。

[{"id":"e218d167.2e763","type":"file in","z":"387c7d80.f1bbc2","name":"","filename":"/Path/to/wordpress_export_file","format":"utf8","x":356.5,"y":116,"wires":[["18994be6.f85814"]]},{"id":"e70bdfb8.c911f","type":"inject","z":"387c7d80.f1bbc2","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":114.5,"y":32,"wires":[["e218d167.2e763"]]},{"id":"18994be6.f85814","type":"xml","z":"387c7d80.f1bbc2","name":"","attr":"","chr":"","x":132.5,"y":182,"wires":[["5c3ebf52.fcbf"]]},{"id":"5c3ebf52.fcbf","type":"change","z":"387c7d80.f1bbc2","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.rss.channel.0.item","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":291.5,"y":182,"wires":[["a0ccebc1.702dd8"]]},{"id":"e1705f3c.bbb2f","type":"template","z":"387c7d80.f1bbc2","name":"","field":"head","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"---\\ntitle: {{payload.title}}\\nsubtitle:\\ndate: {{payload.wp:post_date.0}}\\ncatalog: true\\nheader-img:\\ntags:\\n---","x":461.5,"y":257,"wires":[["50f760b.254e1a"]]},{"id":"a0ccebc1.702dd8","type":"split","z":"387c7d80.f1bbc2","name":"","splt":"\\\\n","x":468.5,"y":181,"wires":[["f0e69020.e56e"]]},{"id":"50f760b.254e1a","type":"template","z":"387c7d80.f1bbc2","name":"","field":"filename","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"/Path/to/{{yyyy}}/{{mmdd}}.md","x":126.5,"y":315,"wires":[["d53310c7.3e3e2"]]},{"id":"f0e69020.e56e","type":"change","z":"387c7d80.f1bbc2","name":"","rules":[{"t":"set","p":"post_id","pt":"msg","to":"payload.wp:post_id","tot":"msg"},{"t":"set","p":"post_date","pt":"msg","to":"payload.wp:post_date.0","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":151.5,"y":262,"wires":[["13950893.0b2987"]]},{"id":"e7932009.89ebd","type":"file","z":"387c7d80.f1bbc2","name":"","filename":"","appendNewline":true,"createDir":false,"overwriteFile":"false","x":409.5,"y":378,"wires":[]},{"id":"d53310c7.3e3e2","type":"file in","z":"387c7d80.f1bbc2","name":"","filename":"","format":"utf8","x":276,"y":314,"wires":[["1538d793.74b6d8"]]},{"id":"23e71877.4c4258","type":"debug","z":"387c7d80.f1bbc2","name":"","active":true,"console":"true","complete":"post_id","x":351.5,"y":460,"wires":[]},{"id":"13950893.0b2987","type":"function","z":"387c7d80.f1bbc2","name":"","func":"msg.yyyy = msg.post_date.substring(0, 4);\\nmsg.mmdd = msg.post_date.substring(5, 10);\\nreturn msg;","outputs":1,"noerr":0,"x":306.5,"y":261,"wires":[["e1705f3c.bbb2f"]]},{"id":"31337f7c.a4b51","type":"template","z":"387c7d80.f1bbc2","name":"","field":"filename","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"/Path/to/{{post_id}}.md","x":258,"y":379,"wires":[["e7932009.89ebd"]]},{"id":"fd978b3f.1879c8","type":"template","z":"387c7d80.f1bbc2","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{{head}}\\n{{payload}}","x":122,"y":379,"wires":[["31337f7c.a4b51"]]},{"id":"1538d793.74b6d8","type":"function","z":"387c7d80.f1bbc2","name":"","func":"msg.payload = msg.payload.split('\\\\n');\\ndelete msg.payload[0];\\nmsg.payload = msg.payload.join('\\\\n');\\nreturn msg;","outputs":1,"noerr":0,"x":415,"y":311,"wires":[["fd978b3f.1879c8"]]},{"id":"6ecf7921.eb47f8","type":"catch","z":"387c7d80.f1bbc2","name":"","scope":null,"x":134.5,"y":462,"wires":[["23e71877.4c4258"]]}]

これ最初は楽勝だと思ってたんですが以下の想定外により思ったより複雑になってしまいました。

node-red-contrib-markdownの想定外

node-red-contrib-markdownで本文をHTMLからMarkdownへ変換しようと思ってたんですが、このノードはMarkdownをHTMLへ変換することしか対応してないようです。がーん。

wpxml2mdの想定外

node-red-contrib-markdownの代替としてwpxml2mdというWordpressのエクスポートXMLからMarkdown化されたファイルを生成してくれるツールを使ってみました。ただ、このツールの仕様上、生成されるファイルは以下のようなディレクトリ構造でアウトプットされます。