📃

【Movable Type】とりあえず覚えておくといいグローバルモディファイア

2024/10/17に公開

概要

MTやPowerCMSにおいて利用できるグローバルモディファイアのうち、筆者の経験でとくに使用頻度の高いもの(便利なもの)を実例とともに紹介しています。

グローバルモディファイアは、共通のモディファイアとしてほぼすべてのファンクションタグで利用できます(一部のモディファイアはブロックタグでも利用可能です)

とりあえず覚えておくといいグローバルモディファイア

encode_html

1を指定すると、このモディファイアを付与したファンクションタグで出力される値に含まれるHTMLタグをエスケープ処理をする。
なお、ファンクションタグは何も指定しなければHTMLタグを適用した状態で出力されます。

<$mt:xxx encode_html="1"$>

以下の例では、記事タイトルにHTMLタグが含まれている場合、エスケープ処理をして出力します。

<$mt:EntryTitle encode_html="1"$>

<!-- 記事タイトルに入力した内容 -->
これは<strong>HTML</strong>の記述を含むタイトルです

<!-- 出力結果 -->
これは&lt;strong&gt;HTML&lt;/strong&gt;の記述を含むタイトルです

このモディファイアを指定することで、本来テキスト入力のみを想定しているフィールドに意図せず書かれてしまうHTMLを無害化できます(XSS対策の一環として有効)
encode_htmlはHTMLタグの記述がエスケープ処理された状態で出力されるので、HTMLタグそのものを除去したい場合は、後述するremove_htmlを使用します。

補足

反対に、HTMLエンティティをデコードするdecode_htmlというモディファイアもあります。このモディファイアを値1で指定すると、HTMLタグを適用した状態で出力します。

<$mt:EntryTitle decode_html="1"$>

<!-- 記事タイトルに入力した内容 -->
これは&lt;strong&gt;HTML&lt;/strong&gt;の記述を含むタイトルです

<!-- 出力結果 -->
これは<strong>HTML</strong>の記述を含むタイトルです

<!-- モディファイアの付与がなければ、HTMLエンティティを含む内容をそのまま出力する -->
これは&lt;strong&gt;HTML&lt;/strong&gt;の記述を含むタイトルです

encode_json

1を指定すると、このモディファイアを付与したファンクションタグの値を、JSONデータとして扱えるようエスケープ処理をする。

<$mt:xxx encode_json="1"$>

以下の例では、記事本文の内容をJSONデータとして扱えるようにエスケープ処理をして出力します。

<$mt:EntryBody encode_json="1"$>

<!-- 記事本文に入力した内容 -->
<h2>encode_jsonについて</h2>
<p>この内容はencode_jsonモディファイアについての説明です。<br>MTの公式リファレンスは<a href="https://www.movabletype.jp/documentation/appendices/modifiers/encode_json.html">こちら</a>から。</p>
<p>JSONデータとして扱えるよう適切にエスケープ処理します。</p>

<!-- 出力結果 -->
<h2>encode_jsonについて</h2>\n<p>この内容はencode_jsonモディファイアについての説明です。<br>MTの公式リファレンスは<a href=\"https://www.movabletype.jp/documentation/appendices/modifiers/encode_json.html\">こちら</a>から。</p>\n<p>JSONデータとして扱えるよう適切にエスケープ処理します。</p>

lower_case

1を指定すると、このモディファイアを付与したファンクションタグで出力される値のうち、英文字を小文字に変換する。

<$mt:xxx lower_case="1"$>

以下の例では、記事投稿画面に用意されたカスタムフィールドに入力された値(英文字)を小文字に変換して出力します。

<$mt:custom_field lower_case="1"$>

<!-- カスタムフィールドに入力した内容 -->
Movable Typeのグローバルモディファイアについての説明です。

<!-- 出力結果 -->
movable typeのグローバルモディファイアについての説明です。

なお、全角英字も同様に変換されます。

<!-- カスタムフィールドに入力した内容 -->
ABCD

<!-- 出力結果 -->
abcd

補足

反対に、英文字を大文字に変換するupper_caseというモディファイアもあります。このモディファイアを値1で指定すると、このモディファイアを付与したファンクションタグで出力される値のうち、英文字を大文字に変換します。全角英字も同様に変換します。

<$mt:custom_field upper_case="1"$>

<!-- カスタムフィールドに入力した内容 -->
abcdefg

<!-- 出力結果 -->
ABCDEFG

また、単語の最初の文字を大文字に、残りの文字を小文字に変換するcapitalizeというモディファイア(値として1を指定する)もあります。以下はその出力例です。

<$mt:PageTitle capitalize="1"$>

<!-- ウェブページタイトルに入力した内容 -->
aBOUT tHiS pAGe

<!-- 出力結果 -->
About This Page

なお、「単語の最初の文字」判定について、日本語(に限らず中国語・韓国語など、ちゃんと検証できていませんが、おそらく他の言語全般)とつながっているものは「ひとつの単語」として認識されるようで、大文字変換がうまくいきません。
以下の例は単語として不自然ですが、検証として入力しています。

<!-- ウェブページタイトルに入力した内容 -->
あaBOUT いtHiS pAGe

<!-- 出力結果 -->
あabout いthis Page

全角英字も同様に変換できます。

<!-- ウェブページタイトルに入力した内容 -->
aBOUT tHiS pAGe

<!-- 出力結果 -->
About This Page

全角英字の場合も「単語の最初の文字」判定は上記同様です。

<!-- ウェブページタイトルに入力した内容 -->
あaBOUT いtHiS pAGe

<!-- 出力結果 -->
あabout いthis Page

mteval

1を指定すると、このモディファイアを付与したファンクションタグの値に含まれるテンプレートタグを実行する。

<$mt:xxx mteval="1"$>

以下の例では、記事本文の中でMTEntryTitleを記述し、実行および出力しています。

<$mt:EntryBody mteval="1"$>

<!-- 記事タイトル -->
グローバルモディファイア「mteval」について

<!-- 記事本文に入力した内容 -->
<p>以下の内容は、<$mt:EntryTitle$>を説明したものです。</p>

<!-- 出力結果 -->
<p>以下の内容は、グローバルモディファイア「mteval」についてを説明したものです。</p>

注意点として、本文エディタが「リッチテキストエディタ」の場合は、mtevalは実行されず、テンプレートタグがエスケープ処理されてそのまま出力されます。

なおこのモディファイアを使うと、たとえばウェブページ本文中にMTEntriesで記事一覧を出力することも可能ですが、記事が追加編集されても記事一覧を出力しているウェブページは再構築されないので、注意が必要です(反映するにはウェブページの更新(保存)をしてページを再構築する必要がある)

nl2br

1を指定すると、モディファイアを付与したファンクションタグの値に含まれる改行を<br>に変換する。
カスタムフィールドの「テキスト(複数行)」やコンテンツタイプの「埋め込みテキスト」のようなtextareaが用意されるフィールドにおいて便利です。

<$mt:xxx nl2br="1"$>

以下の例では、カスタムフィールドの「テキスト(複数行)」に入力した内容を改行付きで出力しています。

<$mt:custom_field nl2br="1"$>

<!-- カスタムフィールドに入力した内容 -->
nl2brモディファイアを付与すると、
改行(brタグ)が出力されます

<!-- 出力結果 -->
nl2brモディファイアを付与すると、<br>改行(brタグ)が出力されます

remove_html

1を指定すると、このモディファイアを付与したファンクションタグで出力される値に含まれるHTMLタグをすべて除去する。
先述のencode_html同様、このモディファイアを指定することで、本来テキスト入力のみを想定しているフィールドに意図せず書かれてしまうHTMLを無害化できます(XSS対策の一環として有効)

<$mt:xxx remove_html="1"$>

以下の例では、記事本文にHTMLタグが含まれている場合、すべて除去して出力します。

<$mt:EntryBody remove_html="1"$>

<!-- 記事本文に入力した内容 -->
<h2>remove_htmlについて</h2>
<p>remove_htmlは<strong>HTMLタグをすべて</strong>除去します。<br>
<a href="リンクURL">リンク</a>も見出しも改行タグも除去します。</p>
<p>画像も除去するので、概要文として本文から何文字か抽出する際に使用するのに向いています。</p>
<p><img alt="画像ALT" src="画像URL" width="xxx" height="xxx" class="mt-image-none"></p>

<!-- 出力結果 -->
remove_htmlについて
remove_htmlはHTMLタグをすべて除去します。リンクも見出しも改行タグも除去します。
画像も除去するので、概要文として本文から何文字か抽出する際に使用するのに向いています。

上記はさらにstrip_linefeedsモディファイアも付与することで、改行コードも除去できます。

<$mt:EntryBody remove_html="1" strip_linefeeds="1"$>

<!-- 出力結果 -->
remove_htmlについてremove_htmlはHTMLタグをすべて除去します。リンクも見出しも改行タグも除去します。画像も除去するので、概要文として本文から何文字か抽出する際に使用するのに向いています。

補足

同じくHTMLタグを除去するモディファイアとして、sanitize(値に1あるいは出力時に許可するHTMLタグを,(カンマ)区切りで指定)があります。
remove_htmlが問答無用ですべてのHTMLタグを除去するのに対し、sanitizeは許可されたHTML以外を除去します。

詳細は公式のリファレンスをご参照ください。

https://www.movabletype.jp/documentation/appendices/modifiers/sanitize.html

replace / regex_replace

モディファイアを付与したファンクションタグの値に対して、文字列を検索置換する。
regex_replaceは検索置換に正規表現が利用できます。

<$mt:xxx replace="検索文字列","置換文字列"$>

<$mt:xxx regex_replace="/検索文字列/","置換文字列"$>

以下はreplaceを使用した例です。記事本文中の「鶴」を「亀」に検索置換して出力しています。

<$mt:EntryBody replace="鶴","亀"$>

<!-- 記事本文に入力した内容 -->
<p>千羽鶴と折り鶴</p>

<!-- 出力結果 -->
<p>千羽亀と折り亀</p>

以下はregex_replaceを使用した例です。正規表現を使い、記事本文中のURLを取り出して出力しています。

<$mt:EntryBody regex_replace="/(.*)(https?:\/\/)([-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#]+)に.*/","$2$3"$>

<!-- 記事本文に入力した内容 -->
<p>mt-devを利用してローカル環境を構築すると、ログインURLはhttp://localhost/cgi-bin/mt/mt.cgiになります。</p>

<!-- 出力結果 -->
http://localhost/cgi-bin/mt/mt.cgi

以下はブロックタグでの利用の一例としてMTForでテンプレート全体を囲い、このブロックタグにreplaceファンクションを付与した例です。regex_replaceモディファイアも同様です。
ブロックタグにこれらのモディファイアを付与することにより、テンプレート全体に対して処理をかけることが可能です。

<mt:For replace="検索文字列","置換文字列">
  <!-- テンプレートの中身(この部分に対して検索置換の処理がはしる -->
</mt:For>

なお、公式リファレンスの該当ページに注意書きがありますが、regex_replaceモディファイアの置換対象文字列にダブルクォーテーションが含まれる場合、文字列の置換がうまくいかないとのことです。

setvar

このモディファイアを付与したブロックタグまたはファンクションタグの値は出力されず、代わりにsetvarで指定された値の変数に格納される。
ブロックタグで利用する場合は、このモディファイアではなくMTSetVarBlockタグを利用する方が、メンテナンスの観点からはわかりやすいです。

以下ではファンクションタグでの利用を前提に解説しています。

<$mt:xxx setvar="変数名"$>

<!-- 出力はmt:Varを使う -->
<$mt:Var name="変数名"$>

以下の例では、MTCategoryLabelの値(「カテゴリA」とする)を変数に格納し、別途出力しています。

<$mt:CategoryLabel setvar="category_label"$>
<$mt:Var name="category_label"$>

<!-- 出力結果 -->
カテゴリA

慣れるまでは要点や使い所が掴みにくいと思いますが、変数に格納することで、たとえばテンプレートの再構築日時と投稿記事の日付を比較し、特定の公開日の記事のみを出力させるということが可能になります。

以下はその一例で、「今月(2024年10月)公開された記事のみ」を出力しています。

<!-- 投稿記事のタイトル一覧 -->
2024年8月の記事
2024年9月の記事
2024年10月の記事①
2024年10月の記事②
2024年11月の記事

<!-- MTML -->
<$mt:Date format="%Y%m" setvar="rebuildDate"$>
<mt:Entries>
  <$mt:EntryDate format="%Y%m" setvar="publishDate"$>
  <mt:EntriesHeader>
    <ul>
  </mt:EntriesHeader>
  <mt:If name="rebuildDate" eq="$publishDate">
    <li><$mt:EntryTitle$></li>
  </mt:If>
  <mt:EntriesFooter>
    </ul>
  </mt:EntriesFooter>
</mt:Entries>

<!-- 出力結果 -->
<ul>
  <li>2024年10月の記事②</li>
  <li>2024年10月の記事①</li>
</ul>

再構築日時を出力するファンクションタグMTDateに年月フォーマットを指定し、setvarモディファイアを変数名「rebuildDate」として付与します。また、MTEntriesタグ内でMTEntryDateも同じようにsetvarを変数名「publishDate」として付与します。
ループの処理内でMTIfを使用してテンプレート再構築日時と記事公開日時を比較し、条件に一致するもの(再構築日時=記事公開日時の記事)を出力しています。

trim_to

このモディファイアを指定したファンクションタグの値を、先頭から指定した文字数分取り出す。
数値に数値+文字列とすると、取り出した文字の後に指定した文字列を追加します。

<$mt:xxx trim_to="数値"$>

<$mt:xxx trim_to="数値+文字列"$>

以下の例では、記事タイトルに入力された内容を各条件で出力しています。それぞれ上段がモディファイアを付与したファンクションタグ、下段が出力結果です。

<!-- 記事タイトルに入力した内容 -->
吾輩は猫である。名前はまだ無い。

<!-- trim_to="4"を指定 -->
<$mt:EntryTitle trim_to="4"$>
吾輩は猫

<!-- trim_to="4+..."を指定 -->
<$mt:EntryTitle trim_to="4+..."$>
吾輩は猫...

<!-- trim_to="-4"を指定 -->
<$mt:EntryTitle trim_to="-4"$>
吾輩は猫である。名前はま

<!-- trim_to="-4+..."を指定 -->
<$mt:EntryTitle trim_to="-4+..."$>
吾輩は猫である。名前はま...

値に負の数を指定すると、末尾から指定数を除去した残りを取り出して出力します。末尾から指定数を取り出すではないので、注意が必要です。

_default

モディファイアを付与したファンクションタグの値が空の場合に、代わりに指定した値をファンクションタグの値とする。

<$mt:xxx _default="未入力の場合に出力する文字列"$>

以下の例では、記事タイトルが未入力の場合、代わりに「無題」という記事タイトルで出力します。

<$mt:EntryTitle _default="無題"$>

<!-- 記事タイトルが未入力の場合の出力結果 -->
無題

公式リファレンス

MT

PowerCMS

Discussion