MODXの独自タグ(エレメント)の使い方

|[../](https://qiita.com/taconana/items/3f5424f9abfc755772c2) |
|---|

MODXがどのような仕組みでPHPのコードを呼び出せるのか調べてみた。そもそもMODXの使い方が分からないので、チュートリアルから試してみた。そして、PHPのコードを呼び出す方法は、WordPressでのショートコードに相当する独自タグ(エレメント)のスニペット`[[xxx]]`や`[!xxx!]`を使うということが分かった。

参照したドキュメントは、以下のもの。
- [MODXを30分で理解する！簡易チュートリアル](https://modx.jp/docs/tutorial/quick.html)
- [サイト用テンプレートの作り方](https://modx.jp/docs/tutorial/howto_make_template.html)
- [MODXのドキュメント](https://modx.jp/docs/) ※まだ読めていない

## MODXの独自タグ(エレメント)のバリエーション

MODXでは「独自タグ」とか「エレメント」と呼んでいる。WordPressのショートコードと同様に`[ ]`などで挟んで表現するが、表記法にバリエーションがあり過ぎて、なかなか難しい。WordPressでのショートコードに相当するのは、スニペット`[[xxx]]`や`[!xxx!]`である。WordPressでは、静的なものも動的なものもすべてショートコードで扱ってきたが、MODXでは、静的なものはスニペット以外の簡易なアクセス方法が提供されている。
```
コンフィグ変数			[(xxx)]
リソース変数				[*xxx*]
リソースID				[~xxx~]
チャンク					{{xxx}}
スニペット(キャッシュあり)	[[xxx]]
スニペット(キャッシュなし)	[!xxx!]
プレースホルダ			[+xxx+]
```
チャンクのみ、なぜか`{ }`だ。プレースホルダと聞くと、HTMLでの入力テキストエリアに初期表示する文字列かと思えるが、そうではない。以下の例では、Dittoというプラグインをスニペット(キャッシュあり)として`[[Ditto]]`を利用し、その引数の文字列の中にプレースホルダとして`[+createdon:date+]`などを差し込んでいる。
```html
<dl class="dl-horizontal">
[[Ditto?
&parents=2
&orderBy=publishedon
&tpl='@CODE:
<dt>[+createdon:date=`%Y年%-m月%-d日`+]</dt>
<dd><a href="[+url+]">[+pagetitle+]</a></dd>
'
]]
</dl>
```
## コンフィグ変数`[(xxx)]`、リソース変数`[*xxx*]`

理解しやすいのは、コンフィグ変数とリソース変数である。コンフィグ変数としては「ツール -> グローバル設定」で設定される値を参照できる。`[(xxx)]`の形式で利用する。主に以下の4つを使う。
```
[(site_name)]		サイト名
[(site_slogan)]		サイトのスローガン
[(site_url)] 		サイトのURL	(例：http://localhost/modx/)
[(base_url)] 		ベースURL (例：/modx/)
```
リソース変数としては、各ページで設定される値を参照できる。よく使うものは以下のものである。`[*xxx*]`の形式で利用する。
```
[*pagetitle*]		ページのタイトル（短めの名前）
[*content*]			ページの本文
[*createdon*]		作成日時
[*editedon*]		更新日時 
[*publishedon*]		公開日時
```
その他にも、リソース変数として以下の属性を参照できる。
```
[*id*]				リソースID（内部的な整数値のID）
[*alias*]			エイリアス（alphabetで）
[*template*]		使用するテンプレートの名前	
[*longtitle*]		長いタイトル
[*description*]		説明（metaタグなどで使う）
[*introtext*]		要約	
[*type*]			タイプ＝リソース

[*published*]		公開中か？	
[*pub_date:date*]	公開開始日時
[*unpub_date:date*]	公開終了日時

[*cacheable*]		キャッシュされているか？
[*searchable*]		検索対象に含めるか？	
[*menuindex*]		メニューオーダー(整数)
[*hidemenu*]		メニューに表示するか？
[*privateweb*]		Webからのアクセス制限ありか？
[*privatemgr*]		管理画面からのアクセス制限ありか？	
[*richtext*]		リッチテキストエディタを使用するか？	
[*isfolder*]		フォルダ(ディレクトリ)か？
```
コンフィグ変数やリソース変数は、以下の感じで使う。テンプレートの例である。`[(base_url)]`はCSSファイルへのリンクなどで使えるが、/modx/ のようにスラッシュで終わっているので注意のこと。
```html
<html>
<head>
  <title>[*pagetitle*] | [(site_name)]</title>
  <link rel="stylesheet" type="text/css" href="[(base_url)]resources/css/my-style.css" />
</head>
<body>
  <div><!-- header部 --></div>
  
  <h2>[*pagetitle*]</h2>
  <p align="right">[*publishedon:date*]</p>
  
  <div>[*content*]</div>
  
  <div><!-- footer部 --></div>
</body>
</html>
```
本文`[*content*]`は必ずテンプレートから呼び出すこと。リソース本文の記述の中で`[*content*]`を呼び出すと無限ループに陥るらしい。MODXでは各ページにダイレクトに本文を書くことができ、その場合は、`[*content*]`で取り込む。またテンプレートのHTMLを指定して挟むこともできる。その場合は、テンプレートのHTML内から`[*content*]`を読み込むようにできる。
一般には、`<head>`と、`<body>`内のheader部分とfooter部分をテンプレートにしておき、header部分とfooter部分の間の本文を`[*content*]`にする感じなのかな。上記のテンプレートの例の感じ。header部分とfooter部分は、静的であればチャンクを使い、動的であればスニペットを使って書く。

## リソースID`[~xxx~]`

チルダを使った`[~xxx~]`の形式では、リソースID(整数)を指定する。すると、そのリソースに遷移するURLが差し込まれる。例えば、会社概要のページがリソースID=2で作成されているとき、他のページからその会社概要のページに飛ばすときには、以下の感じで書ける。
```html
<a href="[~2~]">会社概要</a>
↓
<a href="mysite/company-overview.html">会社概要</a>
```
## チャンク`{{xxx}}`

チャンク(chunk)は、バターやチョコレートのかたまりといったイメージだが、HTMLの断片といった意味だろう。HTMLに差し込む静的な共通部品を扱うようだ。MODXのチュートリアルでは、{{header要素}}、{{バナー広告}}、{{キャッチコピー}}、{{イメージカラー}}、{{担当者名}}、{{最新バージョン}} などの例が挙げられている。
「エレメント管理 -> チャンク」から設定できる。

## スニペット`[[xxx]]`

最も重要なのはスニペットである。スニペット(snippet)も断片だが「切り抜き」といった意味合いのようだ。WordPressのショートコードに該当する。スニペット内ではPHPのコードが書ける。WordPressではショートコードとPHPで書いたハンドラ関数をマッピング定義して間接的に利用していたが、MODXではスニペット名に対してダイレクトにPHPのコードが書ける。

コンフィグ変数`[(xxx)]`、リソース変数`[*xxx*]`、リソースID`[~xxx~]`、チャンク`{{xxx}}`の4つは、静的な値しか取り込めない。原則、いつ呼び出しても同じ値になる。一方、スニペット`[[xxx]]`は動的に変化する値を呼び出した瞬間でスナップショットとして取得できる。呼び出したタイミングで異なる値が返ってくる。

前述の`[[Ditto]]`のスニペットは、以下のように1行で定義されている。PHPをだらだらと書くのではなく、.phpファイルにしておいて、それをinclude(require)する書き方が一般的なのかな。WordPressでハンドラ関数を書くのと同等である。この1行だけでは、引数が分からないのが欠点かな。
```php
return @require MODX_BASE_PATH . 'assets/snippets/ditto/snippet.ditto.php';
```
snippet.ditto.phpをロードして実行し、その値を返す。実行時には様々な引数を渡せるようだ。引数は.phpファイル内で変数名から取得する。.phpファイル内には、使用する引数の説明がされている。例えば、以下の例では`$parents`,`$orderBy`,`$tpl`の3つが仮引数になる。if (isset($parents)) のようにチェックしてから使用する。
```html
[[Ditto?
&parents=2
&orderBy=publishedon
&tpl='@CODE:
<dt>[+createdon:date=`%Y年%-m月%-d日`+]</dt>
<dd><a href="[+url+]">[+pagetitle+]</a></dd>
'
]]
```
上記の例は、DBのmodx_site_contentテーブルからニュースを検索し、publishedonでソートし、createdon、url、pagetitleをプレースホルダとして取得できるようにしている。
- parents=2は、modx_site_contentテーブルのparentのカラムの値が 2 のレコード（つまり、ニュース）を示している。実は、parents=2,8 のように複数を並べることも可能である。だから、parentsのように複数形になっているのだ。
- tplは、おそらくtemplateの略だろう。`@CODE`でHTMLのテンプレートを指定して、そこに値を差し込んで返してくれる。コード量が多い場合にはファイル化して、`@FILE`で読み込むこともできる。
- date=`%Y年%-m月%-d日`の書式指定は、私の環境では機能しない。何か問題があるようだ。2022/06/12の書式では出力できる。

今日はここまで。
|[../](https://qiita.com/taconana/items/3f5424f9abfc755772c2) |
|---|