Movable Typeで使ったテーマをMovable Type.netへ移行して色々ハマったこと

この記事はMovable Type Advent Calendar 2019の5日目の記事です。
結婚記念日ということで今年もこの日を選びました。

いつも案件で使っているMTのDocker環境をアップデートしてポストする予定だったのですが完成できず。。別の機会にポストしたいと思います。

今回のAdvent Calendarは、「Movable Typeで使ったテーマをMovable Type.netへ移行して色々ハマったこと」を書きます。
今年も開催されたMTDDC Meetup TOKYO 2019のデザイン・コーディング・MTの実装を担当しました。
MTDDC Meetup TOKYO 2016にも担当し、当時は普通のMovable Typeで実装をしました。
2019ではMovable Type.netで実装することになり2016(手元に持ってるテーマ)→2018のテーマをベースにMovable Type.netへ移植をしました。
未対応のタグやカスタムフィールドの書き方が異なるくらいでそこまで時間もかからないだろうと高を括っていたら意外と時間がかかってしまったので、今後Movable Type.netで実装担当になったときに思い出せるようにまとめておきます。(笑)

ハマりポイント1:シングルクォーテーションでは認識しなかった 🤦‍♂

シングルクォーテーション書く必要?と思っちゃうかもしれませんが。。私の実装的にHTMLタグの中にMTMLをいれて書くときにダブルクォーテーションだとエディタでエラーみたい感じのがすごく気になってしまうのでタグの中にMTML書くときはシングルクォーテーションで書くようにしていました。
Movable Typeの構築では、シングルクォーテーションを使い実装してました。
<mt:CustomFieldValue identifier='speaker_name' /> で行けると思ったのですが <mt:CustomFieldValue identifier="speaker_name" /> ではないと表示されなかったです。

// Movable Type の場合
<mt:entry_photoAsset>
  <img src="<mt:AssetURL regex_replace='$regex_replace','/' />" height="540" width="540" alt="<mt:EntryTitle />" />
</mt:entry_photoAsset>
// Movable Type.net の場合
<mt:CustomFieldAsset identifier="speaker_img"><img src="<mt:AssetURL />" height="540" width="540" alt="<mt:CustomFieldValue identifier="speaker_name" />"></mt:CustomFieldAsset>

テンプレ実装者目線では、シングルクォーテーションで括っても値が取れるようになってくれるとうれしいなと感じました。

シングルクォーテーションは使えるとのこと

シックスアパートの早瀬さんから個別でご連絡をいただき使えるとのことでした。
間違った情報失礼いたしました。m(_ _)m
MTソフトウェア版でテンプレをごそっとインポートしたとき(色々エラーに苦戦したため)にシングルクォーテーションで括った箇所だけ反映しなかったので、もしかすると思った内容だったのできちんと調査できてなかったです。
製作者ライセンスでテンプレに書いて確認するときちんとシングルクォーテーションは読み込めました。

案件で使用したコードが変数にいれてさらにInclude先の変数にセットしたコードだったので、自分が書いたコードの問題だったかもしれません。
間違った情報のためこちら斜線とさせていただきます。

  • シングルクォーテーションでも使えます。(結果)

ハマりポイント2:SetVarTemplateが使えなかった 🤦‍♂

SetVarTemplateは、私の実装では頻度多めに使うタグになります。
最近追加して頂けましたが実装当時は使えなかったので、SetVarTemplate書いた部分をすべてIncludeに書き直して実装しました。
SetVarTemplateが使えれば1つのIncludeファイルにまとめることもできますが、用途を考えつつIncludeファイルで管理しました。
mt:If でやるのもいいかなと思いましたが、さすがに冗長すぎるなと思い用途別に分けることにしました。
mt:SetVarTemplateであれば mt:If で定義した判定部分なしで実装ができます。

// Movable Type の場合
// component.mtml
<mt:SetVarTemplate name="_page_visual" key="_page_visual">
  <div class="page-visual">
    <div class="page-visual__inner">
      <h2 class="page-visual__text"><span><mt:Var name="_name" /></span></h2>
    </div>
  </div>
</mt:SetVarTemplate>

// 出力
<mt:Var name="_page_visual" key="_page_visual" _name="タイトルが入ります" />
// Movable Type.net の場合
// mt:Include 設定
<mt:If name="_page" eq="true">
  <div class="page-visual">
    <div class="page-visual__inner">
      <h2 class="page-visual__text"><span><mt:Var name="_name" /></span></h2>
    </div>
  </div>
</mt:If>

// 出力
<mt:Include module="visual" _page="true" _name="タイトルが入ります" />

SetVarTemplateは使えるようにはなったが。。。 😰

SetVarTemplate使えるようにはなりましたが、一部実装のみなので name のみしか提供されていません。
このタグの最大の魅力はfunctionが使えるという点ですので、実装されるまではInclude方式でやっていく方法が良さそうです。(悲)

この部分が出来ないとわかったタイミングでなんとか代替案で実装しましたが、SetVarTemplateは強力なタグだと改めて実感しました。(笑)

ハマりポイント3:setvarが使えなかった 🤦‍♂

SetVarタグは使えるのですが、よく使うモディファイア定義書く(私だけ?) setvar が出来ません。
Movable Type.net では SetVarBlock で囲う必要があります。
最初から実装であればこのあたりは SetVarBlock で定義するで良いですが移行となるとモディファイアで書いたものはすべて囲うという作業が発生します。
SetVarタグ使えると思って疑いもせずに値取れないとなって、きちんと調べてデバッグしたら「なるほど!」となりました。

// Movable type の場合
<mt:EntryTitle setvar="_title" />
// Movable Type.net の場合
<mt:SetVarBlock name="_title"><mt:EntryTitle /></mt:SetVarBlock>

setvar使用可能です。

こちらも合わせて間違った情報失礼いたしました。
setvarは使用できるようです。製作者ライセンスで試しに使ってみたところ確認取れました。

こちらもインポート時で値が空だったためsetvar使えないと勘違いでした。
インポート時にエラーなしで空だった原因は調査しきれていませんが、タグにsetvarモディファイアは使用できますので、こちらも斜線とさせていただきます。

ハマリポイント4:テーマインポートどこで失敗したのか不明 🤦‍♂

Movable TypeMovable Type.net の大きな違いは静的か動的かですが、テーマのインポートする際に Movable Type で登録して再構築させることでエラーの内容(タグが使えない等)がわかります。
Movable Type.net 場合は、テーマをアップロードして保存したタイミングでエラーアラートが出ます。

このとき、エラー内容がどの部分の何行目のタグが対応してないなど記載がないため手探りでエラー箇所を探す作業が発生しました。
今回一番時間がかかった部分でした。

機能要望としてエラーアラートの詳細は出してもらえると開発側としてはありがたいです。

ハマリポイント5:mt:Loop及びHashが使えなかった 🤦‍♂

mt:Loop が使えないことは存じていましたが、Hashが使えないの辛いと感じました。
単純なサイトだとHashを実装で使うこともない( 普通にサイトでもロジック書いてちゃってますが。。😎 )と思いますが、今回のイベントページでは登壇者とタイムテーブルはリレーションしたい場合があります。

MTDDC Meetup TOKYO 2016 でも登壇者情報をタイムテーブルでも同様のデータを取り出すように実装しました。
このとき登壇者情報でハッシュ化し任意の値をSetVarTemplateに格納しておけば、タイムテーブルで呼び出せるようになります。
今回はハッシュが使えないなかったので、 <mt:Entries include_blogs="speakers" id="XXXXX"></mt:Entries> IDごとにEntries を回して <mt:SetVarBlock name="_id_XXXXX"><mt:EntryID /></mt:SetVarBlock> に格納してタイムテーブルで呼び出すようにしました。 <mt:SetVarBlock name="_id_XXXXX"><mt:EntryID /></mt:SetVarBlock> この部分を全登壇者分を入れたため登壇者情報のロジックが冗長すぎる感じになってしまいました。
ハッシュがあると mt:Entries 一回ですべての情報をハッシュにまとめれるのでハッシュはどうしても使いたいと感じました。

// Movable type の場合
// タイムテーブルのフォーマット
<mt:SetVarTemplate name="timetable_layout" key="_timetable_layout">
  <div class="speaker__list -timetable">
    <div class="speaker__timetable">
      <mt:Var name="_speaker_profile" />
    </div>
    <h3 class="speaker__name">
      <span class="name"><mt:Var name="_speaker_name" /></span><br>
    </h3>
  </div>
</mt:SetVarTemplate>

// データを格納
<mt:Entries lastn="0" sort_order="ascend">
<mt:EntryID setvar="this_entryID" />
<mt:EntryTitle setvar="title" />
<mt:entry_profile setvar="this_profile" />
<mt:entry_company setvar="this_company" />
<mt:SetVar name="entry_title" function="push" value="$title">
<mt:SetVar name="entry_id" function="push" value="$this_entryID">
<mt:SetVar name="entry_profile" function="push" value="$this_profile">
</mt:Entries>

// 出力(インデックスの添字)
<mt:Var name="this_entryID[XXXX]" setvar="_this_entryID" />
<mt:Var name="title[XXXX]" setvar="_title" />
<mt:Var name="this_profile[XXXX]" setvar="_this_profile" />
<mt:Var
  name="timetable_layout"
  key="_timetable_layout"
  _speaker_id="_this_entryID"
  _speaker_name="_title"
  _speaker_profile="_this_profile"
/>
// Movable Type.net の場合
// タイムテーブルのフォーマットテンプレート mt:Include
<h3 class="timetable__session-title">
  <a href="<mt:Var name="_speaker_id" />"><mt:Var name="_speaker_title" /></a>
</h3>
<div class="speaker__list -timetable">
  <div class="speaker__timetable">
    <mt:Var name="_speaker_profile" />
  </div>
  <h3 class="speaker__name">
    <span class="name"><mt:Var name="_speaker_name" /></span><br>
  </h3>
</div>

// データの格納
<mt:Entries include_blogs="speakers" id="XXXXX">
  <mt:SetVarBlock name="_id_XXXXX"><mt:EntryID /></mt:SetVarBlock>
  <mt:SetVarBlock name="_title_XXXXX"><mt:CustomFieldValue identifier="speaker_session_title" /></mt:SetVarBlock>
  <mt:SetVarBlock name="_name_XXXXX"><mt:CustomFieldValue identifier="speaker_name" /></mt:SetVarBlock>
  <mt:SetVarBlock name="_profile_XXXXX"><mt:CustomFieldValue identifier="speaker_profile" /></mt:SetVarBlock>
</mt:Entries>

<mt:Entries include_blogs="speakers" id="XXXXX">
  <mt:SetVarBlock name="_id_XXXXX"><mt:EntryID /></mt:SetVarBlock>
  <mt:SetVarBlock name="_title_XXXXX"><mt:CustomFieldValue identifier="speaker_session_title" /></mt:SetVarBlock>
  <mt:SetVarBlock name="_name_XXXXX"><mt:CustomFieldValue identifier="speaker_name" /></mt:SetVarBlock>
  <mt:SetVarBlock name="_profile_XXXXX"><mt:CustomFieldValue identifier="speaker_profile" /></mt:SetVarBlock>
</mt:Entries>

// 出力
<mt:Include
  module="timetable_speaker"
  _speaker_id="$_id_XXXXX"
  _speaker_title="$_title_XXXXX"
  _speaker_profile="$_profile_XXXXX"
  _speaker_name="$_name_XXXXX"
/>

ハッシュが使えると // データの格納 部分で mt:Entries を何度も定義する必要がなくなると思います。
個人的にはハッシュは使いたいですが、こういうイベントページでのリレーションは独自の入力フィールドがあったほうが用途的に良いのかなと感じました。
ブラックボックス感がでてしまいますが、タイムテーブルフィールドみたいなものが作れて且つ登壇者情報をドラッグアンドドロップで入れたりセルを結合(時間等)が管理画面で行えるのが良いなーと思っています。表示するコンテンツはタグ1つでタイムテーブル用のtableが出力されるような機能があればスマートな感じがしました。

ハマりポイント6:mt:Entriesの件数制限 🤦‍♂

インストール版では mt:Entries を使用するときに lastn="0" で全件出すような感じで書くことが多いです。
Movable Type.net では制限があり100件までしか取得することが出来ません。

出力するブログ記事の件数を制限します。lastn モディファイアは、つねに降順 (新しいものから古いものに並ぶ) で処理します。指定可能な値は 1-100 、all(最大100迄)です。

ASPになるため制限があることは仕方ないですが、例えば商品情報など100件以上データがあって出すときはMTMLでどう実装するのが良いのか代替案が浮かびませんでした。 🤔
イベントページで100件以上出すことはありませんが、商品情報を取り出すときはDataAPIを使ってフロントはJavaScriptで実装するみたいな感じがよいのでしょうか。
Data APIは、使用可能エンドポイント一覧 から参照できますが、インストール版やMTクラウドは異なるので、実装要件確認時には一度目を通しておいたほうがいいですね。

良かったこと1:再構築不要 🎉 💯

ハマったポイントはありましたが、実装してて再構築がないというは動的の恩恵は受けれたので良かったです。
何年も再構築押して更新することがなかったので共通パーツ(例えばスポンサーバナーの更新)などを即更新できるのは良かったです。

良かったこと2:フォーム機能は良かった 🎉 💯

Movable Type.netには標準でフォーム機能がついています。
Movable Type.netのウェブサイトのみになるので外部で使いたいやJSでカスタマイズが必要な場合は、別途でMovable Type.net フォームの申し込みが必要になります。
設置も簡単でiframeのみ設定しスタイル調整するだけだったので実装工数も30分くらいで実装できました。
Movable Typeでフォームはプラグインで実装や別立てのフォーム実装することが一般的になるので、インストール版・MTクラウドとMovable Type.net フォームを抱合せして使うのも良いかと思いました。

良かったこと3:小規模サイトなら良い 🎉 💯

要件次第で採用になるのがCMS選定だと思いますが、単純なWebサイトなど細かい要件がなければMTクラウドやインストール版よりは低コストだと感じました。
私は提案する立場というより実装する立場なので、できるできないという部分で見てしまいますが単純にサイトほしい方にはおすすめですね。

今回は使ってないですが、ステージング機能やアクセシビリティチェック・ワークフロー機能がが低コストで導入できますのでユーザ目線なCMSだと感じました。

初めてMovable Type.netで実装してみて

MTからのテーマからMovable Type.netでも動くようにしたので、テーマ化してイベント用テーマとして配布できるくらいまでには実装はしておきました。
タイムテーブルとか登壇者とかそういうイベントに必要な項目網羅できてるので意外と需要ありそうと思いました。

実装してみて思ったことは、MTのテーマ使って〜実装でも普通に実装するよりコスト高いのでは?と思いました。
意外と自分の書き方はマニアック過ぎたかもしれませんね。 シックスアパートさんの引っ越しサービス使うのもありかと思います。

いつもMTクラウドやインストール版の実装が多いので一つ勉強になりました。
これからMTテーマをMovable Type.netへ移行する方の参考になればと思います。 💁‍♂

  • Facebook
  • Twitter
  • はてなブックマーク

Author

札幌でフロントエンドエンジニアとして働いています。好きな音楽はSIAM SHADE!
SIAM SHADEの六人目のメンバーとして日々ロックを愛し続けている。
HTML,CSS,JavaScriptをベースにCMS構築が得意です。
HAMWORKS社員 https://ham.works