MovabletypeでIncludeの裏技みつけたった。

この記事は[Digital Identity Creative Div. Advent Calendar 2021 14日目](https://adventar.org/calendars/6258)の記事です。

フルリモートワーク初めて1年以上が経過してますが、出勤時間が無くなって私生活サポートができるようになったのを引き換えに運動不足が加速してちょっと外出したときのスタミナ切れがやばいです。


さて、クソ久方ぶりにMovableType利用したんですけど、モジュールテンプレートの変則的な使い方することで一部のソースを共通化、一部のソースをサイト事で個別管理することができました。

## 一般的なモジュールテンプレートを使ってソース共通化

特定のHTMLソースを全テンプレートで共通化利用する場合はテンプレートモジュールに設定してインクルードするのはいわずもがななんですが、複数サイトでおなじモジュール利用する際はたいてい親サイトにモジュールテンプレート設置しますよね。
例えば今回jsonld周りのソースを管理するモジュールテンプレートを「json_ld」として下記のように用意。（json ldってなんぞやってのは割愛）
※事前にMTSetVarで下記を設定
・website_url：親サイトのURL
・common_path：親サイトURLに「common/」を結合
・common_title：共通タイトルとして設定する文言

```
<script type="application/ld+json">
[
	{
	"@context": "http://schema.org",
	"@type": "Organization",
	"url": "<$MTGetVar name='website_url'$>",
	"logo": "<MTGetVar name='common_path'>img/logo_header.svg"
	},
	{
		"@context": "http://schema.org",
		"@type": "BreadcrumbList",
		"itemListElement":
		[
			{
				"@type": "ListItem",
				"position": 1,
				"item":
				{
					"@id": "<$MTGetVar name='website_url'$>",
					"name": "<$MTGetVar name="common_title"$>TOP"
				}
			}
		]
	}
]
</script>

```

で、読み込みする際は全ページで下記。

```
<$MTInclude module="json_ld" parent="1"$>
```

## 子サイト側の個別モジュールテンプレート指定

さて、トップページと他ページの最親ページ設定はこれでおｋ、問題はセカンドページ以降の各種階層表記。
例えばニュースページ（/news/）とかだと下記みたいに出力させなくちゃいけない。

```
<script type="application/ld+json">
[
	{
	"@context": "http://schema.org",
	"@type": "Organization",
	"url": "<$MTGetVar name='website_url'$>",
	"logo": "<MTGetVar name='common_path'>img/logo_header.svg"
	},
	{
		"@context": "http://schema.org",
		"@type": "BreadcrumbList",
		"itemListElement":
		[
			{
				"@type": "ListItem",
				"position": 1,
				"item":
				{
					"@id": "<$MTGetVar name='website_url'$>",
					"name": "<$MTGetVar name="common_title"$>TOP"
				}
			},
			{
				"@type": "ListItem",
				"position": 2,
				"item":
				{
					"@id": "https://hoge.com/news/",
					"name": "ニュースページタイトル"
				}
			}
～～以下ページ毎にposition3以降として記述～～
		]
	}
]
</script>

```

上記のようにposition2以降として階層付けしていくわけだが、さすがにこれを親サイトで記載するわけにはいかない。
サイトによっては個別の構成や階層になってるから記述方法も子サイト事で管理ってことはモジュールテンプレートも子サイトで管理させることになる。

例として子サイトで/news/としてニューストップページ、カテゴリページ、記事詳細ページっていうシンプルなサイトを設定した場合のモジュールテンプレートを「json_ld_article」として下記を作成。

```
,
            {
                "@type": "ListItem",
                "position": 2,
                "item":
                {
                    "@id": "<$MTBlogURL$>",
                    "name": "<$MTBlogName$>"
                }
            }<MTIf tag="EntryID" ne="">,
            {
                "@type": "ListItem",
                "position": 3,
                "item":
                {
                    "@id": "<$MTGetVar name='category_link'$>",
                    "name": "<$MTGetVar name='now_cate'$>"
                }
            },
            {
                "@type": "ListItem",
                "position": 4,
                "item":
                {
                    "@id": "<$MTEntryPermalink$>",
                    "name": "<$MTEntryTitle$>"
                }
            }<MTelseIf tag="CategoryID" ne="">,
            {
                "@type": "ListItem",
                "position": 3,
                "item":
                {
                    "@id": "<$MTCategoryArchiveLink$>",
                    "name": "<$MTGetVar name='now_cate'$>"
                }
            }</MTIf>

```

position2はニュースサイト全ページで共通でニューストップページの情報が付与されるため直記述。
MTIfにて記事IDが空じゃなかった場合＝記事詳細という判定でpostion3に属するカテゴリページ情報と、postion4に記事詳細情報。
ElseIfにてカテゴリIDが空じゃなかった場合＝カテゴリページという判定でposition3にカテゴリページ情報のみ記載する形で作成。

これをニュースページ各種でインクルードすればページに応じたソースが出力される。

単純に考えれば子サイト内のモジュールテンプレートを読み込むなら単純に

```
<$MTInclude module="json_ld_artice"$>
```

で読み込めるわけだが、、前段で作成した親サイトのjson_ldモジュールを読み込みつつ再度中で子サイトのjson_ld_articleを読み込ませないといけないわけだが。。
親サイトで記述したモジュールテンプレートの中で子サイトのモジュールテンプレートをインクルードさせようとしたら、階層的に親サイトにそのモジュールテンプレートを参照しようとしてエラーになるんじゃないか。。
そんなもやもやを持ちつつ下記のように親サイトのjson_ldモジュールを改修して再構築を実行。

```
<script type="application/ld+json">
[
	{
	"@context": "http://schema.org",
	"@type": "Organization",
	"url": "<$MTGetVar name='website_url'$>",
	"logo": "<MTGetVar name='common_path'>img/logo_header.svg"
	},
	{
		"@context": "http://schema.org",
		"@type": "BreadcrumbList",
		"itemListElement":
		[
			{
				"@type": "ListItem",
				"position": 1,
				"item":
				{
					"@id": "<$MTGetVar name='website_url'$>",
					"name": "<$MTGetVar name="common_title"$>TOP"
				}
			}<MTIf name="top_flg" eq=""><MTInclude module="json_ld_article"></MTIf>
		]
	}
]
</script>
```
json_ld_articleは親サイトにはなく、子サイトのみに存在する。
top_flgはトップページのインデックステンプレートに<$MTSetVar name="top_flg" value="1"$>を付与してトップページ判定に利用。

うーん・・・動くの？これｗ

## 保存と再構築した結果

結論としてはできました。

親サイトのテンプレートも子サイトのテンプレートも下記で完全共通化完了。

```
<$MTInclude module="json_ld" parent="1"$>
```

どうやら子サイトで上記を実行すると親サイトのモジュールテンプレートを読み込む中、json_ld_articleの参照先は親サイトではなく、子サイト自信のモジュールテンプレートの中を参照してくれたようです。
参照先のモジュールが親でも、その中の記述が特定タグやblod_idsなどで明示的に指定してない限りは参照元を基準とするようで。。

以前はposition1の途中までを親サイト、以降を子サイトでモジュールテンプレート分けしてinclude記述を二つ記述したりもしてましたけど、これであればソース的にもすっきりするし可読性も確保できるのでよいかなと。

### 注意点

ただし一つデメリットがあります。
MovableTypeではインデックステンプレートやアーカイブテンプレートの管理画面にインクルードしてるモジュールテンプレートへのリンクが右ナビの「インクルードテンプレート」の箇所に一覧として表示されるんですがモジュールテンプレート内でインクルードしてるテンプレートへのリンクまでは表示されません。
今回で言うと、json_ldへのリンクは表示されるが、json_ld_articleへのリンクは表示されません。

![スクリーンショット 2021-12-17 124515.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54125/2ca50017-cf76-a0db-2f20-4622c2ca0141.png)

これはさすがにしゃーないね。。