2022/05/21

AnotherCustomFieldsプラグインの内容をMT7に移行した話

MTOSにカスタムフィールド的なものを組み込めるAnotherCustomFieldsプラグインは、その後上位版MovableTypeへの対応がなされていない。
MT6なら一部機能を除いてギリギリ使えるそうだが、MT7だと記事編集画面の入力欄が壊れてしまって、開いて保存するだけで値が空になってしまう。
記事のエクスポートにも含まれない。救済予定もないそうで、MTのバージョンアップをする際に非常に困ってしまった。

何とかならんのかと調べてここへたどり着いたかた、そういうことです。

かといって放っておくわけにもいかなかったのだけど、手入力でちまちまとコピ&ペを繰り返すのはあまりにしんどい。
ということで以下、解決までの道のりを書き残してみる。

方針

エクスポート/インポートの道が絶たれているならば、おおもとのデータベースをあたるしかない。
普通のカスタムフィールドは、PHPMyAdminを覗いてみても値を直接操作することができないらしい。
しかしAnotherCustomFieldsの場合はPHPMyAdminの「mt_entry」から値を確認/編集することができる。
ついでにデフォルトのフィールド(本文、キーワード etc.)も同じくPHPMyAdminから編集できる。

今回のケースでは、たまたま「本文」欄を使わない運用をしていたので、下のような方針をとることができた。

  1. 移行元のPHPMyAdminの画面上で移行対象記事の部分をコピーし、それをローカルでちょっと加工し、AnotherCustomFieldsで作られたフィールドの値を置換用に整形する
  2. 移行先のPHPMyAdminの画面上で、上記1を各記事の本文欄(entry_text)にちまちま貼り付ける
  3. 記事テンプレート上で、本文を正規表現で置換処理し、目的の値を取り出して変数に格納
  4. 別途、普通のカスタムフィールドも作成。今後は「あればカスタムフィールドの値→なければ上記3の変数値」という分岐を設けて併存させる

以下、それぞれについて解説していきたい。

1. 移行元のPHPMyAdminの画面上で移行対象記事の部分をコピーし、それをローカルでちょっと加工し、AnotherCustomFieldsで作られたフィールドの値を置換用に整形する

PHPMyAdminの画面上で直接見ることができるフィールドの値は、一定の文字数を超えると最後に「...」がついて省略されてしまう。その場合、そうなってしまっている欄をひとつひとつ編集状態にして全文をコピーするほかない。
今回のケースでは幸いにも字数が多くないものばかりで、ブラウザ上で豪快にバーッとドラッグ選択すれば、ほぼ完全に値をコピーすることができた。
Tableタグで表示されているので、そのままExcelに貼り付け。不要な行や列を削除する。

これらの値をあとから正規表現で取り出せるよう、各記事ごとに、「画像1=〼〼&画像2=〼〼&画像3=〼〼&金額=〼〼&種別=〼〼」のように区切り記号を決めてひとつづきのテキストとして整形しておく。

2. 移行先のPHPMyAdminの画面上で、上記1を各記事の本文欄(entry_text)にちまちま貼り付ける

移行元の環境から、AnotherCustomFieldの値が抜け落ちた状態で記事をエクスポートし、移行先にインポートする。
PHPMyAdmin上でセルをクリックすると編集状態になるから、それで移行先の各記事の本文フィールドを片っ端から編集状態にして、上記1で作った置換処理用の文字列をペーストしていく。
かなり手を動かすことになるけど、普通に管理画面の記事一覧から1ページ1ページ開いて入力して再構築待ちをして...とやるよりは多少なりとも効率がよい。160件くらいひたすらポチポチした。

3. 記事テンプレート上で、本文を正規表現で置換処理し、目的の値を取り出して変数に格納

PHPMyAdminでの作業は終了。移行先環境の管理画面に普通にログインして、記事テンプレートに手を入れる。
上記2でペーストしたEntryBodyをいったん変数に格納し(複数回使い回すため)、regex_replaceで慎重に必要な部分だけを残して「画像1」「画像2」「画像3」「金額」「種別」の値を得て、またそれぞれを変数に入れる。

ここでひとつハマッたことがあった。本文欄の編集モードのデフォルトがリッチテキストになっていると、PHPMyAdmin上で貼り付けをおこなっても、半角「&」がご丁寧に「&」に置き換えられた状態で保存されてしまう。まあ置換条件に&じゃなく&を使うだけで解決したのだけど、絵ヅラが自然すぎてしばらく気が付かなかった。区切り記号にそういう文字は避けることをお勧めする。あるいは空いていれば概要やキーワード欄を使うか。

4. 別途、普通のカスタムフィールドも作成。今後は「あればカスタムフィールドの値→なければ上記3の変数値」という分岐を設けて併存させる

ここまで来ればクリアしたも同然。だが甘い!
MTのデータベースにおいて、画像フィールドの値は、URLではなくアセットのIDが保存されるようだ。PHPMyAdminでコピペした画像1~4欄の中身も当然そうなっている。
そしてMTPagesやMTEntriesとは違い、MTAssetsにidモディファイアをつけても何も起こらない(試した)。えー。
つまり、せっかく仕込んだ本文から画像URLがすんなり取得できない。けっこうな大問題である。

とはいってもやるしかない。
記事一覧ページでは、再構築が重くなるのを覚悟でいったんMTAssetsを回し(このときtype="image"をつける)、ブログ内のぜーんぶの画像アセットについて、MTSetVarsの中でIDを変数名、URLをその変数の値として、画像の数だけ変数を定義していく。
次に別の箇所で、本文から取り出した画像IDを使って、それらの変数の中の該当するものを呼び出せば、値であるURLが書き出される。よし。

同じことを記事個別ページでもやると、再構築のたびに、何百と画像が登録されているMTAssetsが記事の数だけ回ることになってしまい、何10分待たされるかわからない。
絶対避けたいので、全アセットのIDとURLが書き出されたJSONファイルをひとつ作る。
各記事ページではそのJSONファイル+JavaScriptを利用し、画像ID→URLの置き換えを動的におこなう。
読み込みは若干遅くなるが、まあよし。(記事一覧ページも読み込みが遅くて問題ない内容ならばこれでよい)

これでどうにか上手くいった。MT7の管理画面のテンプレートでMTVarが機能するようにさえできれば、欄が壊れて表示されることもないっぽいのだけど。分かる人ならすぐできそう。ワタシはわからない。
さしあたり、PHPMyAdminが使えない環境の人は、鬼コピペをがんばってください...