こんにちは。STです。
MovableType7(MT7)で、自動再構築をする方法について紹介します。
公式のバッチがあるのですが、バージョン7の場合完全には動きません。
色々試してみて、結論は”ほとんどのページで再構築が可能”という状態になりました。
例外はありますが、ある程度のケースまで対応できると思います。
初の投稿記事にしてはニッチな内容ですね。
※Perlを読めない人間なので、実践ベースでやっています。ご利用は自己責任でお願い致します。
そもそも自動の再構築機能は必要なのか
実際のところ、多くの場合は自動化ツールを必要としません。
更新が終わった後に、再構築ボタンを押して待機するだけです。
記事更新の時にはログインしているので、本当にそれだけの手間で済みます。
多少の更新漏れがあっても問題ないのであれば、わざわざ作る必要はありません。
コンテンツタイプに若干癖があるものの、多くの場合は連動して更新されます。
対象サイトの特徴
今回対象とするサイトは、以下の二つを含むものになります。
- コンテンツタイプアーカイブ
- カテゴリアーカイブ
インデックスやウェブページのみの場合は、自作の必要はなくバッチで実現できます。
MovableTypeの自動再構築で検索するとすぐ見つかります。
ぜひ探してみましょう。
「rebuild-pages」という名称のバッチで、インストール時にも封入されています。
もしバッチが使える状況なら、サーバー負荷も少ないのでおすすめです。
バッチが使えない理由と代替案
理由は非常に単純で、公式がバッチの動作保証と更新を止めてしまいました。
恐らくは、MovableType6→7で大きく仕様が変わったせいです。
具体的には、コンテンツタイプ系のデータ構造を追加したことですね。
そこで、今回はコンテンツタイプに対応している「DataAPI」を採用しました。
個人的にドキュメントが少々心もとないように思うので、補足しつつご紹介します。
※後日DataAPIはv5が発表されましたが、この記事ではv4を取り扱います。
サイト構成
サイト一本構成で、子サイトやマルチサイトはありません。
コンテンツタイプが少々複雑で、コンテンツタイプアーカイブの中で別のコンテンツタイプを呼んでいます。
本来コンテンツタイプを更新すると関連するアーカイブが更新されますが、この構造が自動再構築を必要とする理由でもあります。
[本題]DataAPIを使った再構築の実装
クライアント側は何でも構いませんが、私はJavascript(node.js)で構成しています。
流れとしては下記のようになります。
- 認証
- インデックステンプレートおよびウェブページ
- テンプレートの一覧データを取得
- テンプレートモジュールの再構築
- 個別のコンテンツタイプとコンテンツタイプアーカイブ
- 各コンテンツデータの一覧を取得
- 各コンテンツデータを再構築
- インデックステンプレートおよびウェブページ
APIサンプル
認証処理について
素直にユーザー情報とパスワード情報、そして任意のクライアントIDを送ればOKです。
DataAPIのパスワードとログインのパスワードは別なので、管理画面のユーザー画面から事前に確認しておきましょう。
DataAPIの有効化もお忘れなく。
ドキュメントはコチラ
※APIから取得した情報については、便宜上、認証は「auth」、そのほかは「response」で示します。
※ループについても上記と同様に、「loop」で記載します。
// 認証リクエストのサンプル
{
"url": "{{ サイトURL }}/{{ DataAPIのcgiパス }}/v4/authentication",
"method": "POST",
"body": {
"username": "{{ ユーザー名 }}",
"password": "{{ DataAPIパスワード }}",
"clientId": "{{ 任意のID }}"
}
}
注意点としては、認証で受け取れるトークンには有効期限があります。
件数が多いとそれなりに時間がかかるので、有効時間を超える場合は再取得を行いましょう。
※また設定ファイルから有効時間の変更が可能です。
インデックステンプレートとウェブページの更新について
まずテンプレートの一覧を取得します。
limitがデフォルトで設定されているので、大きい数字にでも設定しておきましょう。
ドキュメントはコチラ
// テンプレートの一覧取得サンプル
{
"url": "{{ サイトURL }}/{{ DataAPIのcgiパス }}/v4/sites/{{ サイトID }}/templates",
"method": "GET",
"query": "limit=9999"
}
一覧を取得したら、bodyレスポンスをループさせて情報を取り出します。
ドキュメントのresponseにありますが、{{ response.items }}に配列で返ってくるので、ループなりなんなりで取り出しましょう。
ID情報のみで更新のPOSTが作成できるので、順次更新のAPIを投げます。
下書き情報が混ざっている場合は注意が必要です。
ドキュメントはコチラ
// テンプレートの再構築サンプル
{
"url": "{{ サイトURL }}/{{ DataAPIのcgiパス }}/v4/sites/{{ サイトID }}/templates/{{ loop.id }}/publish",
"method": "POST",
"headers": {
"X-MT-Authorization": "MTAuth accessToken={{ auth.accessToken }}"
}
}
個別のコンテンツタイプとコンテンツタイプアーカイブ
「2」の場合と流れは大体同じで、まずは一覧情報を取得します。
ドキュメントはコチラ
※コンテンツタイプが増減する場合や数が多い場合は、コンテンツタイプの取得APIも呼ぶ必要があります。
// コンテンツデータの取得サンプル
{
"url": "{{ サイトURL }}/{{ DataAPIのcgiパス }}/v4/sites/{{ サイトID }}/contentTypes/{{ コンテンツタイプID }}/data",
"method": "GET",
"headers": {
"X-MT-Authorization": "MTAuth accessToken={{ auth.accessToken }}"
},
"query": "limit=9999"
}
itemsまでのデータ構造は「2」と同じなので、ループは同じ要領で回せます。
「2」の例では再構築のAPIでしたが、こちらは更新のAPIになり、メソッドや構造が異なります。
JSONのラベルは決まっているので、間違えないようにしましょう。
環境によってはパンクする可能性があるので、インターバルがあった方が良いです。
ドキュメントはコチラ
// コンテンツデータの更新サンプル
// bodyのラベルはドキュメントで仕様が定義されています
{
"url": "{{ サイトURL }}/{{ DataAPIのcgiパス }}/v4/sites/{{ サイトID }}/contentTypes/{{ コンテンツタイプID }}/data/{{ loop.id }}",
"method": "PUT",
"headers": {
"X-MT-Authorization": "MTAuth accessToken={{ auth.accessToken }}"
},
"body": {
"content_data": {
"data": " {{ loop.data }}"
}
}
}
失敗例
失敗例なので、さくさく紹介していきます。
- コンテンツデータの公開
対象API
実質は再構築かと思ったのですが、そうではないようでした。
下書き→公開の方っぽいです。
- テンプレートの更新
インデックスとウェブページの更新ではお世話になりましたが、コンテンツタイプではダメでした。
APIの方で補足している通り、コンテンツタイプ系のページは駄目の様です。
API自体は通っているようで、なぜかアーカイブから書き出しているうちの1件だけは更新されていました。
未対応箇所について
ご紹介した方法では、管理画面で設定可能な、記事がなくてもアーカイブを出力するページに対応していません。
個別のコンテンツタイプを更新した場合は関連テンプレート全体ではなく、それに紐づいているテンプレートのみが更新されます。
つまり、どこにも紐づけられていないアーカイブは更新されないということになりますね。
私の管理しているサイトでは問題ありませんが、「テンプレートモジュール」が頻繁に更新されるようなサイトでは要注意です。
最後に
トライアルアンドエラーというか泥臭いというか、全体的になんとかした感のある作りになってしまいました。
それっぽいAPIを呼んで動きを見ていただけなので、もっといい方法があると思います。
ちなみに、管理画面にボタンがありますよね。
ご存じの通り、インデックスやウェブページなど、再構築対象の選択が可能です。
実は開発者ツールで見ると、対象毎に別々のURLが生成されています。
そのURLにアクセスすると(要ログイン)、直接再構築することも可能です。
API経由でも、同じようなことができるようになってほしいですね。でも需要が限定的過ぎて望みは薄そうです。