CMSで記事用のテンプレートを作成する際に要望の多いモジュールと、その仕様について

wordpress用のAdvanced Custom Fieldsやmovabletype用のMTAppjQueryなどのプラグインの登場で、テキストと画像のみのシンプルな記事ではなく、見出しやテーブルや定型文などを使ったリッチなページを作成したい、という要望がここ数年増えています。

ここ数年といっても2015年くらいからかな？
Advanced Custom Fieldsの登場でCMS×モジュールの組み合わせが世にウワーッと広まった気がします。

実案件では、お客さんの要望を聞いた上で必要なモジュールを準備しますが、__案件が終わるたびに細かい仕様を忘れてしまう__ので、そんな僕のためにも要望の多いモジュールについてまとめておこうと思います。

ちなみにこの記事では以下のCMSとプラグインを前提にしています。

- MovableType × MTAppjQueryプラグインのマルチフィールド機能（mtapp.multiField）
- Wordpress × Advanced Custom Fieldsプラグインの柔軟コンテンツ（Flexible Content）
- Craft CMS × フィールド機能
- WebRelease × コンポーネント機能

※そういえばConcrete5ってのもあったな…。


#「見出し」モジュール
![headlines@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225315/71777c3d-581d-2223-2699-77aa716e51e5.png)

必須のモジュールですね。

##フィールドの構成
|フィールド名|タイプ|選択肢／備考|
|:-:|:-:|:-:|
|見出しレベル|ラジオボタン|大見出し／中見出し／小見出し|
|テキスト|１行テキスト、または複数行テキスト|html入力可|
|アンカー|１行テキスト|   |

見出しレベル別に

- 大見出しモジュール
- 中見出しモジュール
- 小見出しモジュール

と分けてもいいですが、__ページを一旦構築した後に見出しレベルを変更したくなるかもしれない__ので、ラジオボタンで選択できるようにしておいたほうが運用上楽です。

【テキスト】は１行テキストが主流ですが__「見出し内で改行したい」__という要望も結構あるので、複数行テキストにしておいて、管理画面ではデフォルトの高さを２〜３行にしておく、のが良いかもしれません。
あと、英語サイトで__「文字の一部を斜体にしたい」__といった要望がたまに出るので、`<i>`などを挿入できるよう、html入力できるようにしておきましょう。

ここで忘れがちなのが【アンカー】ですね。文字種を指定できるCMSなら入力できる文字を半角英数に制限しておくと良いです。

小見出しについては左寄せか中央寄せが選べるようにしておくのもいいかもしれません。
ただそこまで自由を与えるとサイト全体の統一感が失われるので個人的には嫌いです。

##出力コード例
```html:headline.html
<section class="module_headline" id="iwanttobelieve">
  <div class="inner">
    <h1>I want to believe</h1>
  </div>
</section>
```

`<section>`直下に`<h1>`や`<h2>`を置いてもいいですが、__構築後にデザインが変わるかもしれない__（結構遭遇します）ので間に`<div>`を１つ挟んでいます。こうしておくと大抵の変更に対応できます。

#「テキスト」モジュール
![text@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225315/aa7a12c5-fa30-7a83-d657-f380f306fe51.png)

これはシンプルですね。
##フィールドの構成
|フィールド名|タイプ|選択肢／備考|
|:-:|:-:|:-:|
|テキスト|複数行テキスト|wysiwygエディタが使えると良い|

フィールドの構成はシンプルなんですが、wysiwygを使えるようにしておくとそのぶん自由度が上がるので、

- 画像が配置された場合
- tableタグが配置された場合
- 段落が中央寄せになった場合
- テキストにリンクが貼られた場合

など、__様々なシチュエーションを想定しておく__必要があります。
cssの設定がめんどくさいモジュールですね。

##出力コード例
```html:text.html
<section class="module_text">
  <div class="inner">
    <p>“Pilot” is the pilot episode of the science fiction television series The X-Files. The episode aired on September 10, 1993 on the Fox network in the United States and Canada, and subsequently aired in the United Kingdom and Ireland on Sky1...</p>
  </div>
</section>
```

#「テキストと画像」モジュール
![text_image@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225315/6e86855a-c618-f491-8f78-330d8cbd7f43.png)

photo by [Marcin Wichary](https://www.flickr.com/photos/8399025@N07/2290325804/)

画像が絡むと構成がややこしくなります。

##フィールドの構成
|フィールド名|サブフィールド名|タイプ|選択肢／備考|
|:-:|:-:|:-:|:-:|
|テキスト||複数行テキスト|wysiwygエディタが使えると良い|
|画像||繰り返しフィールド||
||ファイル|画像アップロード||
||代替テキスト|一行テキスト||
||キャプション|一行テキスト、または複数行テキスト|html入力可|
||キャプションの位置|ラジオボタン|左寄せ／中央寄せ／右寄せ|
|画像位置||ラジオボタン|右／左|
|回り込み||ラジオボタン|しない／する|
|スクロール時の画像位置固定||ラジオボタン|しない／する|

【画像】フィールドは、Advanced Custom Fieldsの繰り返しフィールドのように自由に増減できると使いやすいです。一方、MTAppjQueryはこのようにフィールドのセット内に繰り返しフィールドを設置することができないので、

- 画像1 - ファイル
- 画像1 - 代替テキスト
- 画像1 - キャプション
- 画像1 - キャプションの位置
- 画像2 - ファイル
- 画像2 - 代替テキスト ...

と、あらかじめ3セットほど用意しておきます。これ不便なんですよね。MTAppjQueryのアップデートに期待です。

【キャプション】については、__「リンク貼りたい」「太字にしたい」__などの要望が意外と多い箇所ですので、cssをあらかじめ整備しておきましょう。

【キャプションの位置】は選択できないほうがいい気もするんですが、特に中央寄せで複数行になった場合、見た目が情けなくなってしまうので、右寄せ、左寄せの選択肢があると安心です。

【画像位置】でテキストと画像の位置関係を選択できるようにしておきます。右寄せの画像がずっと続くページはデザイン的にも退屈ですので、このフィールドはよく使います。
__スマホ・タブレットの場合__は画像とテキストを上下に並ばせるのが主流ですが、その際に画像を上にするか下にするか、のオプションも案件によっては必要になるかもしれませんね。

画像サイズに比べてテキストの量がかなり多くなってしまった場合、画像の下に大きな余白が生じてしまうので、【回り込み】のフィールドも用意しておきましょう。floatの出番です。

![float@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225315/f48ec3b6-01ec-4d81-ddc6-38b7a6dea9bb.png)


「【画像】フィールドが空の場合はテキストモジュールとほぼ同じコードになるからこのモジュールだけで済むんじゃないか？」と思う方もいるかもしれませんが、__その通りです。__
ただ、このモジュールはフィールドが多いため、__ページの編集画面が無駄に長くなってしまう__というデメリットがあります。ですので両方用意しておくことをおすすめします。

##出力コード例
```html:text_image.html
<section class="module_text_image">
  <div class="inner image_right">
    <p>“Pilot” is the pilot episode of the science fiction television series The X-Files. The episode aired on September 10, 1993 on the Fox network in the United States and Canada, and subsequently aired in the United Kingdom and Ireland on Sky1...</p>
    <div class="images">
      <figure>
        <img src="/images/dammy_01.png" alt="Mulder’s office">
        <figcaption class="center">Mulder’s office from “The X files”</figcaption>
      </figure>
      <figure>
        <img src="/images/dammy_02.png" alt="">
      </figure>
    </div>
  </div>
</section>
```

#「画像」モジュール
![image@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225315/9479dca0-834c-d431-f096-25daba30a850.png)
![image_full@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225315/799b1056-f05a-0ee4-6ae4-e2efebe2cff3.png)


デフォルトの横幅は他のモジュールに合わせておいて、そのうえで__個別に最大幅を指定できるように__しておきます。こうすることでレイアウトの幅が広がります。
画像自体の位置は中央寄せのみで構わないと思います（案件にもよりますが）。

##フィールドの構成
|フィールド名|タイプ|選択肢／備考|
|:-:|:-:|:-:|
|ファイル|画像アップロード||
|代替テキスト|一行テキスト||
|キャプション|一行テキスト、または複数行テキスト|html入力可|
|キャプションの位置|ラジオボタン|左寄せ／中央寄せ／右寄せ|
|最大幅|一行テキスト|%またはpxも入力|

##出力コード例
1枚の場合

```html:image.html
<section class="module_image">
  <div class="inner">
    <figure>
      <img src="/images/dammy_01.png" alt="Mulder’s office">
      <figcaption class="center">Mulder’s office from “The X files”</figcaption>
    </figure>
  </div>
</section>
```
最大幅の指定がある場合

```html:image_full.html
<section class="module_image">
  <div class="inner" style="max-width:100%">
    <figure>
      <img src="/images/dammy_01.png" alt="Mulder’s office">
      <figcaption class="center">Mulder’s office from “The X files”</figcaption>
    </figure>
  </div>
</section>
```

#「画像（複数枚）」モジュール
![image_multi@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225315/ac9262f4-e373-0807-c0d8-769e6d9a0089.png)
photo by [Becky Stern](https://flic.kr/p/azAqoX)

##フィールドの構成
|フィールド名|サブフィールド名|タイプ|選択肢／備考|
|:-:|:-:|:-:|:-:|
|画像||繰り返しフィールド||
||ファイル|画像アップロード||
||代替テキスト|一行テキスト||
||キャプション|一行テキスト、または複数行テキスト|html入力可|
||キャプションの位置|ラジオボタン|左寄せ／中央寄せ／右寄せ|

ここも繰り返しフィールドが使えると楽ですね。

##出力コード例
```html:image.html
<section class="module_image">
  <div class="inner">
    <figure>
      <img src="/images/dammy_01.png" alt="Mulder’s office">
      <figcaption class="center">Mulder’s office from “The X files”</figcaption>
    </figure>
    <figure>
      <img src="/images/dammy_02.png" alt="Me and Matt as Scully and Mulder">
      <figcaption class="center">“Me and Matt as Scully and Mulder”<br>by Becky Stern</figcaption>
    </figure>
  </div>
</section>
```

#「動画」モジュール
![movie@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225315/e234ccf8-869c-65f0-ffee-eab27490eb44.png)


##フィールドの構成
|フィールド名|タイプ|選択肢／備考|
|:-:|:-:|:-:|
|ソース|複数行テキスト||
|キャプション|一行テキスト、または複数行テキスト|html入力可|
|キャプションの位置|ラジオボタン|左寄せ／中央寄せ／右寄せ|
|最大幅|一行テキスト|%またはpxも入力|

youtubeなど、`<iframe>`タグを貼り付ける場合がほとんどだと思いますので、【ソース】フィールドは複数行テキストにしておきます。「絶対にyoutubeしか使わない！」という場合は動画IDのみを貼り付けるフィールドにしてもいいですね。

また、こちらも「画像」モジュールと同様、横幅は自由に決められるようにしておきましょう。

##出力コード例
```html:movie.html
<section class="module_movie">
  <div class="inner">
    <div class="movie_wrap">
       <iframe width="560" height="315" src="https://www.youtube.com/embed/BgEN1t4jPRE" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
    </div>
    <p class="center">Uninvited guests</p>
  </div>
</section>
```
`<iframe>`周りはレスポンシブ用に`<div>`が余分に必要になりますね。

#「表組み」モジュール
![table@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225315/776f8ed5-43a9-b6c3-7280-b4fb3c94f13e.png)
表組みはいろんなバリエーションがあるので設計段階で仕様を詰めておきましょう。
上の図は上部にヘッダーがありますが、左端がヘッダーセルというパターンも多いので、とにかく__いろんなパターンを想定しておく__と良いです。

##フィールドの構成
|フィールド名|タイプ|選択肢／備考|
|:-:|:-:|:-:|
|ソース|複数行テキスト|wysiwygエディタが使えると良い|
|キャプション|一行テキスト、または複数行テキスト|html入力可|
|キャプションの位置|ラジオボタン|左寄せ／中央寄せ／右寄せ|
|左セル固定|ラジオボタン|しない／する|
|均等幅|ラジオボタン|しない／する|

クライアントに`<table>`タグを手打ちしてもらうのは難しいのでwysiwyg必須です。
納品の際はセルをヘッダーセル（`<th>`）にする方法は最低限伝えておきましょう。

`<caption>`タグについてはcssの`caption-side`で`top`か`bottom`を指定できますが、データ系の表組み以外で上部にキャプションが付いている場面をあまり見たことがないので、【キャプションの位置】は他のモジュールと同様左／中央／右の選択肢で良いと思います。

スマホでは__表組みがコンテンツ幅からはみ出てしまう__ことがよくあります。それを防ぐために`<table>`タグの親要素に`overflow:auto;`を指定しておき、かつ`<td>`に最小幅を設定する、という手法が一般的だと思いますが、その上で、__左端のセルがヘッダーの場合、その`<th>`の位置を固定する__と幅の狭い画面でも読みやすい表組みになります。【左セル固定】フィールドはそのために用意しています。

また、表組みの__列の幅を均等にしたい__、という要望もよくありますので、【均等幅】フィールドを設置し、「する」が選択された場合は`<table>`タグに`table-layout:fixed;`が適用されるようにしておきます。

##出力コード例
```html:movie.html
<section class="module_table">
  <div class="inner">
    <div class="table_wrap">
      <table>
        <caption>Source : https://en.wikipedia.org/wiki/List_of_The_X-Files_episodes</caption>
        <tr>
          <th>No.</th>
          <th>Title</th>
          <th>Directed by</th>
          <th>Original air date</th>
        </tr>
        <tr>
          <td>1</td>
          <td>Pilot</td>
          <td>Robert Mandel</td>
          <td>September 10, 1993</td>
        </tr>
      </table>
    </div>
  </div>
</section>
```

#まとめ

代表的なのは以上でしょうか。
他にも、

- ボタン
- 横並びパネル
- お問い合わせ
- GoogleMaps

などのモジュールが求められる案件もありますが基本的にこれだけ揃えておけば心配ないと思います。
あと、画像が絡むモジュールについてはスマホ用とPC用でフィールドを分けてpictureタグかjsかcssで出し分けするともっと便利になりますね。

CMSについては、

- 様々な状況を想定する
- 入力画面が冗長にならないようにする

の２つを常に念頭に入れて構築するのがとても重要です。
ですので、

- クライアントの担当者さんへのヒアリング
- デザインの段階でのパターン出し、確認

は徹底的に時間をかけましょう。
何事も最初が肝心です。