下位互換性のない変更点


2.0.x と 2.1.x の環境から現在のバージョンでは、細かい変更も色々ありますが大きく以下の変更が必要になります。

  • acms-admin.css の追加

  • index.js から acms.js に変更

  • acms.js の前に jQuery の読み込み

  • ioncubeエンコーダーのバージョンアップ

Ver. 2.0.x または Ver. 2.1.x からアップデートする場合

【必須】acms-admin.css の追加

acms.css で使用しているメディアクエリーがモバイルファーストな書き方に変更された為、システムで利用している CSS を acms- admin.css に変更しました。acms.css についてはそのまま残して、ご利用のテーマに以下のコードを追記してください。

<link href="/css/acms-admin.min.css" rel="stylesheet" type="text/css" media="all">

acms- からはじまる今までのクラス名を変更しない場合は、使用していた旧バージョンの acms.cssはそのままご利用く ださい。また旧バージョンのacms.cssをご利用する場合は旧バージョンの/system/fonts/ディレクトリをご利用の テーマに移動をお願いします。

【必須】index.js から acms.js にファイル名変更

Ver. 2.5.0 以前では、組み込みJS を読み込む為に index.js を読み込んでいましたが、Ver2.5.0 より acms.js にファイル名が変更になりました。以下のようにリンクを修正をしてください。

<!-- BEGIN_MODULE Js -->
<script src="/acms.js{arguments}" charset="UTF-8" id="acms-js"></script><!-- END_MODULE Js -->

【必須】 jQuery の読み込み

組み込み JS が非同期で読み込まれるようになった事により、jQuery が読み込まれる前に、jQuery プラグインや組み込み JS のカスタマイズが動いてしまいエラーが出てしまいます。 そこで、jQuery が同期的に読まれるように以下の対策をお願いします。

対策1

jQuery を acms.js から読み込む事をやめ、テンプレートから直接 jQuery をロードします。

以前のバージョンでは組み込み JS の jQuery とバッティングしてエラーを出していましたが、Ver2.5.0 からテンプレー トから読み込んでいる jQuery を優先して読み込むようになりました。こうする事により、同期的にjQueryが読み込ま れますので、エラーを回避する事が出来ます。かならず、acms.js の前で読み込むようにしてください。

<script src="%{JS_LIB_JQUERY_DIR}jquery-%{JS_LIB_JQUERY_DIR_VERSION}.min.js" charset="UTF-8"></script>
<!-- BEGIN_MODULE Js -->
<script src="/acms.js{arguments}" charset="UTF-8" id="acms-js"></script><!-- END_MODULE Js -->

対策2

またテンプレートで config.js の値を書き換えている場合は、以下のように対応をお願いします。

ACMS.Ready(function() {
    ACMS.Config.toggleMark = ‘toggleMark2’; // 例
});

【任意】カスタムユニットを利用されている場合

インクルード先が変更になっております。

  • /include/unit.html に設置してある /include/custom-unit.html が /include/unit/custom.html に変更。

  • /admin/entry/unit.html に設置してある /admin/entry/custom-unit.html が /admin/entry/unit/custom.html に変更

【任意】Entry_Summary で tag を出力している場合

Ver2.5.0よりEntry_Summaryモジュールのタグループ内のglueブロック名が glue から tagGlue に変更されました。ご利用の場合は変更して下さい。

Feed_Rss2モジュールでフィールドによる絞り込みを行っている場合

ver2.5.0 以前は Feed_Rss2 モジュールで「モジュールIDの条件設定」でフィールドが設定できるようになっており、エントリーのカスタムフィールドで絞り込めるようになっていたが、 ver2.5.0以降では、ここの設定がなくなり、「モジュールの表示設定」にこの設定が移動しました。

モジュールの条件設定にあった絞り込み条件をモジュールの表示設定のエントリフィルタに設定してください。

【任意】システムテーマのオフキャンバスを利用している場合

Ver. 2.5.0 以前は、システムテーマにあるオフキャンバスのJSとCSSをテーマでも利用していましたが、Ver. 2.5.0 でなくなり、組み込みJSへと変更されました。 デフォルトテーマ(site2014など)ベースでカスタマイズしている場合は、このオフキャンバスを利用している可能性が高いので以下対応をお願いします。

アップデート時にいらなくなったscriptタグをHTML上から削除する

以下の記述が不要になります。

<!-- offcanvasに利用されていたmodernizr.jsの記述  -->
<!-- site2014テーマでは js.htmlに記述されている -->
<script src="/js/off-canvas/modernizr.js"></script>

<!-- offcanvasに利用されていたoff-canvas.cssの記述 -->
<!-- site2014テーマでは link.htmlに記述されている -->
<link rel="stylesheet" href="/css/off-canvas/off-canvas.css">

<!-- offcanvasに利用されていたmain.jsの記述 -->
<!-- site2014テーマでは footer.htmlに記述されている -->
<script src="/js/off-canvas/main.js"></script>

組み込みJSを適応させるために該当部分にクラスを付与する

オフキャンバスメニューに収めたいエリアを「js-offcanvas」でくくるだけなので、特にHTMLの構造を気にする必要はありません。ただ、画面幅がbreakpointで指定した値よりも数値が小さい場合はoffcanvasMarkでくくられたHTMLが画面上に表示されなくなるので注意してください。 オフキャンバスメニューを使用したHTMLの構造は例えば以下のようになります。

<ul class="js-offcanvas" id="offcanvas">
    <li><a href="#">メニュー</a></li>
    <li><a href="#">メニュー</a></li>
    <li><a href="#">メニュー</a></li>
    <li><a href="#">メニュー</a></li>
</ul>
<a class="js-offcanvas-btn js-offcanvas-btn-r" href="#offcanvas">メニューを表示</a>

site2014テーマの場合は、id="nav"と振られた要素があるのでその要素に対して「js-offcanvas」というクラスを付与します。

<div id="nav" class="js-offcanvas">
...

また、header.htmlにオフキャンバスを開閉するためのボタンが記述されているのでそのボタンに対して「js-offcanvas-btn」というクラスを付与します。 さらにオフキャンバスを右から開閉させたい場合は「js-offcanvas-btn-r」左から開閉させたい場合は「js-offcanvas-btn-l」というクラスを追加します。

<a class="nav-btn acms-btn js-offcanvas-btn js-offcanvas-btn-l" id="nav-open-btn" href="#nav"><i class="acms-icon-sort"></i>メニュー</a>

オフキャンバスメニューを開閉させた時にヘッダーも追随させたい場合はさらにheaderに対して「js-offcanvas-header」というクラスを付与します。

<header id="headWrapper" class="js-offcanvas-header">
...

Ver. 2.0.x からアップデートする場合

ionCube Loader のバージョンアップが必要

Ver. 2.0.x では ioncube エンコーダー Ver. 6.5 を利用していましたが、現在は新しい PHP のバージョンに対応するため ioncube エンコーダー Ver. 9.0 を利用しています。古いバージョンの ioncube Loader では動作させることができませんので新バージョンの ionCube Loader をご利用ください。

ionCube Loader のバージョンアップについては ioncube Loader のインストール をご覧ください。

下位互換性のない変更点


【重要】テーマの変更点とアップデート時の注意事項

バージョンアップで変更となったテーマの変更点と注意事項です。アップデートされる場合は必ずお読みください。

バージョン共通でアップデートする時の注意事項

config.system.yaml に変更を加えていない場合

private/config.system.yaml を上書きしてください。

config.system.yaml に変更を加えている場合

private/config.system.yaml は、コンフィグの初期設定をしているファイルです。 Ver. 2.0.0.xではこれらの設定内容はconfig.system.default.yaml にすべて引き継がれていますが、 config.system.yaml の設定内容が優先されます。 以下の部分を変更してください。


Ver. 1.xまで

Ver. 2.0.0以降

file_icon_dir: images/fileicon/

file_icon_dir: themes/system/images/fileicon/

スクロールできます

Ver. 1.7.0からアップデートする場合の変更点

/themes/system/include/column.html をカスタマイズして利用している場合

Ver. 2.0.0.xでファイル名称が column.html から unit.htmlに変更されています。 このファイルをカスタマイズしている場合には、 column.html のカスタマイズ内容をunit.htmlに反映してください。 column.htmlは今後使用されません。

EntryBodyモジュール を利用しているテンプレート

Ver. 2.0.0.xで動的フォーム、バージョン管理の機能を追加しています。これらの機能を使用する場合には以下の記述が必要になります。記述位置などは /themes/system/acms-code/snippets/entry_body.html のスニペットファイルをブラウザでご覧ください。

インクルードファイルを変更

<!--#include file="/include/column.html"-->  <!-- 廃止 -->
<!--#include file="/include/unit.html"--> <!-- このコードに変更 -->

以下コードを追加

<!-- BEGIN formBody -->
   <!--#include file="/include/form/unit.html"-->
<!-- END formBody -->

<!-- BEGIN adminFormEdit -->
   <!--#include file="/admin/form2/edit.html"-->
<!-- END adminFormEdit -->

<!--#include file="/admin/entry/revision-info.html"-->

Column_Listモジュール を利用しているテンプレート

Ver. 2.0.0.xでモジュール名称が Column_List から Unit_Listに変更されています。テンプレートファイル側で名称変更をしてください。

/admin/entry/action.html および /admin/action.html をカスタマイズしているテンプレート

Ver. 2.0.0.xで各ファイルの内容が変更されています。これらのファイルにカスタマイズをおこなっている場合、カスタマイズ内容を新しいaction.html に反映してください。

/a-blogcms設置ディレクトリ/images/ を削除

Ver. 2.0.0.xで /themes/system/ に移動されています。/a-blogcms設置ディレクトリ/images/ 内のファイルにカスタマイズを行っている場合には /themes/system/images/ に変更分を反映して、 /a-blogcms設置ディレクトリ/images/ を削除してください。

ブログやカテゴリーの編集画面の変更

ブログやカテゴリーの編集画面へのリンクがindexからeditに変わった為、 1系で管理画面へのリンクを用意している場合に2系にアップデートするとリンクが切れる問題が発生します。リンクを用意している場合はリンクの修正をお願いいたします。

静的HTMLサイトのフォームを動くようにする


9. お問い合わせフォームを実装する

a-blog cms では、フォーム機能が標準で備わっており、必要なファイルや処理の流れがあらかじめ用意されています。そのため、カスタマイズ済みのテンプレートを利用するだけで、「入力 → 確認 → 完了 → メール送信」までを実装できます。

お問い合わせフォームは、静的 HTML サイトにゼロから実装しようとすると、
入力画面・確認画面・完了画面の切り替え処理 や メール送信機能 をすべて自作する必要があり、難易度が高い部分です。

このチュートリアルでは「静的 HTML サイトのフォームを動かす」ことを目標としています。ただし、フォーム実装は初心者にはややハードルが高いため、基本的には beginner テーマに含まれるお問い合わせフォームのコードを流用 しながら、その仕組みを解説し、理解を深めていきます。


9-1. 基本のファイル構造を確認する

現在のファイル構成は次のとおりです。
_top.html にもフォームのマークアップがありますが、まずは contact ディレクトリ内で動作するフォーム を確認してから、最終的にトップページに移設していきます。

/themes/sample/
  ├── _top.html 
  ├── news/
  ├── service/
  ├── contact/
  │   ├── index.html   (お問い合わせフォーム:入力画面)
  │   ├── confirm.html (お問い合わせフォーム:確認画面)
  │   └── thanks.html  (お問い合わせフォーム:完了画面)
  ├── css/
  ├── images/
  └── admin/

ここに、beginner テーマの contact ディレクトリ を移設して利用します。
まずは beginner 側のファイル構成を見てみましょう。

/themes/beginner/
  └── contact/
      ├── index.html   (入力画面)
      ├── thanks.html  (完了画面)
      └── form/
          ├── main.html
          ├── confirm.html
          ├── input.html
          ├── step.html
          ├── adminbody.txt
          ├── adminsubject.txt
          ├── body.html
          ├── adminbody.html
          ├── body.txt
          └── subject.txt

この中で重要なのは contact/form ディレクトリ内のファイル群です。これらをまとめてコピーすることで、フォーム機能に必要なテンプレートが揃います。

index.html 内の @include("/contact/form/main.html") という記述です。ここで form/main.html を読み込むことで、入力 → 確認 → 完了画面の一連の流れとメール送信処理が動作します。

9-2. Form モジュールの基本構造

main.html には Form モジュール が書かれています。いくつかの step ブロックに分かれ表示内容が分岐するようになっています。

この仕組みによって、入力画面 → 確認画面 → 完了画面と画面を切り替えながら、ひとつのフォームを動作させることができます。

<!-- BEGIN_MODULE Form -->

  <!-- BEGIN step-->
  <!-- 初期画面 -->
  <h2>入力画面</h2>
  @include("/contact/form/input.html")
  <!-- END step -->

  <!-- BEGIN step#reapply -->
  <!-- 修正・エラー -->
  <h2>入力画面</h2>
  @include("/contact/form/input.html")
  <!-- END step#reapply -->

  <!-- BEGIN step#confirm -->
  <!-- 確認 -->
  <h2>確認画面</h2>
  @include("/contact/form/confirm.html")
  <!-- END step#confirm -->

  <!-- BEGIN step#result -->
  <!-- 完了 -->
  <h2>送信完了</h2>
  @include("/contact/form/confirm.html")
  <!-- END step#result -->

<!-- END_MODULE Form -->

各ステップの役割

  • step : フォームの初期表示(入力画面)

  • step#reapply : 入力内容にエラーがあった場合に戻る画面(再入力用)

  • step#confirm : 入力した内容を表示する確認画面

  • step#result : 送信完了画面(ここでメール送信処理が行われる)

各ファイルの役割

  • input.html : 入力用のフォーム部分の HTML(<input><textarea> などを配置)

  • confirm.html : 確認画面で入力内容を表示するための HTML

  • main.html : これらをまとめて呼び出し step ごとに分岐させる「制御役」

このように、main.html は「全体のまとめ役」、
input.htmlconfirm.html は「実際に画面に表示される部分を担当するファイル」 と考えると分かりやすいでしょう。

なお、ここで紹介したのはあくまでざっくりとした構造です。実際には <form> タグや送信処理に必要な隠しフィールド(hidden input など)が書かれています。詳しくは実際のファイルを開いて確認してください。

9-3. フォームID の設定を行う

これまで、各モジュールをテンプレートに貼り付けた際には、モジュールID を管理画面で設定していました。

Form モジュールも同じように使いますが、メール送信やバリデーションといった特別な仕組みを持つため、専用の「フォーム管理」画面で ID を設定 する必要があります。

この ID を設定しないと、フォームは動作しません。

Beginner テーマの場合

今回のチュートリアルは Beginner テーマがインストールされている状態からスタートしています。そのため、すでに「contactForm」というフォームIDがフォーム管理に登録されています。

つまり 新規作成は不要 で、そのまま利用することができます。ただし、メールの送信先アドレスや自動返信メールの内容は、環境に合わせて修正してください。

入力チェックの初期設定を削除する

a-blog cms では「管理画面側」と「テンプレート側」の両方にエラーチェック機能があります。ただし、今回のチュートリアルではテンプレートをカスタマイズしてフォーム項目を減らしていくため、初期状態の「入力チェック」設定が残っているとエラーで先に進めなくなる可能性があります。

そのため、管理画面の「入力チェック・変換」タブにあるすべての項目を一旦削除してください。これで、フォームのカスタマイズを自由に進められるようになります。

SCR-20250917-kecm

(↑ 入力チェック・変換の設定をすべて削除してください)

他のテーマから始めた場合

もし Beginner テーマをインストールしていない環境でフォームを実装する場合は、フォーム管理に何も登録されていない状態 から始まります。その場合は、新規作成を行い、以下のように設定してください。

  • フォームID : contactForm (テンプレートの hidden フィールドと一致させる必要があります)

  • フォーム名 : 管理画面でわかりやすい名前(例:「お問い合わせフォーム」)

  • 送信先メールアドレス(To) : 管理者が受け取るメールアドレス

  • 通知メールの設定 : 管理者通知メール・自動返信メールの件名や本文

  • 入力チェックの設定 : 必須項目や形式チェックのルール

設定後に保存し、フォームから実際に送信テストを行って動作を確認してください。

9-4. フォームの実装

ここまでフォームの仕組みを解説してきましたので、ここからは beginner テーマのフォームを sample テーマに移植して動かす 実作業を行います。

ファイルをコピーする

まずは beginner テーマにあるフォーム関連のファイル一式を、sample テーマに移植します。

/themes/beginner/contact/form ディレクトリを、/themes/sample/contact/ 配下にそのままコピーしてください。

最終的に sample テーマの構成は以下のようになります。

/themes/sample/contact/
  ├── index.html
  ├── confirm.html
  ├── thanks.html
  └── form/
      ├── main.html
      ├── confirm.html
      ├── input.html
      ├── step.html
      ├── adminbody.txt
      ├── adminsubject.txt
      ├── body.html
      ├── adminbody.html
      ├── body.txt
      └── subject.txt

補足

  • main.html がフォームの本体で、入力 → 確認 → 完了までの制御を行います。

  • .txt ファイルはメール送信用のテンプレートです。

  • body.html で HTMLメールも送信可能です。

index.html を編集する

次に sample テーマの contact/index.html を開き、Contact の見出しを含む <div> の下に以下を追記します。

@include("/contact/form/main.html")

修正後のイメージは以下の通りです。

<div class="border-b border-gray-200 pb-8 mb-12">
    <h1 class="text-3xl font-bold tracking-tight text-gray-900 sm:text-4xl">Contact</h1>
    <p class="mt-4 text-lg text-gray-600">サービスに関するご質問や、ケータリングのご相談など、お気軽にお問い合わせください。</p>
</div>

@include("/contact/form/main.html")

この時点で表示されるフォームは、当初の静的 HTML サイトにあったフォーム項目ではなく、Beginner テーマのサンプルフォーム です。
ただし、sample テーマの CSS とは統合されていないため、スタイルが適用されずレイアウトが崩れた状態になっています。

SCR-20250917-iyop

一方で、必須入力チェック などの処理はすでに動作しており、全ての項目を入力することで確認画面を表示することもできます。つまり、フォームの機能そのものは動いている状態 になっています。

9-5. ステップ部分を調整

Beginner テーマでは、フォームの進行状況を表す step.html がシンプルなリスト形式で実装されています。

<ol class="form-step">
  <li class="form-step-item is-current">内容の入力</li>
  <li class="form-step-item">内容の確認</li>
  <li class="form-step-item">送信完了</li>
</ol>

一方、sample テーマにはよりビジュアル的なステップ表示があり、番号付きの丸アイコンと線で区切るデザインが使われています。今回はこれを step.html に移植し、フォームの状態に応じて切り替わるように修正 します。

実装の考え方

  • 外側の構造は sample テーマのデザインをそのまま流用

  • 中の各ステップは Form モジュールの step, step#confirm, step#result などを利用して切り替える

修正後の例

<!-- BEGIN_MODULE Form -->
<div class="mt-12 mb-8">
    <div class="flex items-center justify-between px-8">
    
<!-- BEGIN step -->
( index.html を参考に )
<!-- END step -->

<!-- BEGIN step#reapply -->
( index.html を参考に )
<!-- END step#reapply -->

<!-- BEGIN step#confirm -->
( confirm.html を参考に )
<!-- END step#confirm -->

<!-- BEGIN step#result -->
( thanks.html を参考に )
<!-- END step#result -->

    </div>
</div>
<!-- END_MODULE Form -->

このようにすることで、sample テーマのデザインを維持しながら、フォームの進行状況が正しく反映されるステップ表示が完成します。

9-6. 入力フォーム input.html の調整

ここでは、input.html を実際のサイトの要件に合わせてシンプルな構成に修正していきます。項目は「お名前」「メールアドレス」「お問い合わせ内容」の 3 つに絞ります。

修正後の例

<div>
    <label for="name" class="block text-sm font-medium text-gray-700">お名前</label>
    <div class="mt-1">
        <input type="text" name="name" id="name" value="{name}" autocomplete="name" class="block w-full rounded-md border-gray-300 shadow-sm focus:border-sky-500 focus:ring-sky-500 sm:text-sm">
    </div>
</div>
<div>
    <label for="email" class="block text-sm font-medium text-gray-700">メールアドレス</label>
    <div class="mt-1">
        <input id="email" name="email" type="email" value="{email}" autocomplete="email" class="block w-full rounded-md border-gray-300 shadow-sm focus:border-sky-500 focus:ring-sky-500 sm:text-sm">
    </div>
</div>
<div>
    <label for="message" class="block text-sm font-medium text-gray-700">お問い合わせ内容</label>
    <div class="mt-1">
        <textarea id="message" name="message" rows="10" class="block w-full rounded-md border-gray-300 shadow-sm focus:border-sky-500 focus:ring-sky-500 sm:text-sm">
        {message}
        </textarea>
    </div>
</div>

ポイント

  • 入力値の保持:value="{name}"{message} のようにプレースホルダーを入れることで、確認画面やエラー時にも入力内容を保持できます。

  • name 属性と value の対応:フォームの項目は「カスタムフィールド」と同じ仕組みで、name 属性にフィールド名を指定し、その内容が value に反映されます。

  • シンプルに始める:必須チェックやエラー表示などの拡張は後から追加できるため、まずは基本の「入力 → 確認 → 完了」の流れを作ることを優先します。

これで、input.html は「お名前」「メールアドレス」「お問い合わせ内容」という最小限の入力項目を持った実用的なフォームになりました。

9-7. 確認画面 confirm.html の調整

次に、confirm.html を修正していきます。
ここでは、入力画面 (input.html) で受け取った値を確認画面に表示し、ユーザーが送信前に内容をチェックできるようにします。

修正後の例

<div>
    <label class="block text-sm font-medium text-gray-700">お名前</label>
    <div class="mt-1 p-3 bg-gray-100 rounded-md">
        <p>{name}</p>
    </div>
</div>
<div>
    <label class="block text-sm font-medium text-gray-700">メールアドレス</label>
    <div class="mt-1 p-3 bg-gray-100 rounded-md">
        <p>{email}</p>
    </div>
</div>
<div>
    <label class="block text-sm font-medium text-gray-700">お問い合わせ内容</label>
    <div class="mt-1 p-3 bg-gray-100 rounded-md">
        <p class="whitespace-pre-wrap">{message}</p>
    </div>
</div>

ポイント

  • 入力画面で入力された値を {name}, {email}, {message} で出力。

  • 今回 Tailwind CSS の class="whitespace-pre-wrap"<br> でなくても改行が有効になっているが、一般的には {message}[nl2br] として改行コードを <br> に置き換える事が一般的です。

9-8. フォーム全体の制御 main.html の調整

ここまでで入力 (input.html)、確認 (confirm.html)、のそれぞれのファイルを修正しました。 最後に、これらを切り替えて表示する フォーム全体の制御 を main.html に実装します。

入力画面の構造と hidden フィールドの役割

main.htmlstepstep#reapply のブロックの詳細を確認していきます。

<!-- BEGIN step -->
<!-- フォームステップ:初期 -->

@include("/contact/form/step.html")

<div class="mt-16 px-5">
  <form action="?step=reapply" method="post" class="space-y-6" enctype="multipart/form-data">
  
  @include("/contact/form/input.html")

  <div>
    <input type="hidden" name="step" value="confirm" />
    <input type="hidden" name="error" value="reapply" />
    <input type="hidden" name="id" value="contactForm" />
    <input type="submit" name="ACMS_POST_Form_Confirm" value="内容の確認へ" id="btnConfirm" class="w-full flex justify-center py-3 px-4 border border-transparent rounded-md shadow-sm text-base font-medium text-white bg-sky-600 hover:bg-sky-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-sky-500" />
  </div>

  </form>
</div>

<!-- END step -->

type="hidden" で設定されている 3つを確認していきます。

<input type="hidden" name="step" value="confirm" />

入力内容が正しく、エラーがなかった場合に step#confirm ブロックを表示させる。

<input type="hidden" name="error" value="reapply" />

入力チェックでエラーがあった場合に step#reapply ブロックを表示させる。

<input type="hidden" name="id" value="contactForm" />

フォームを識別するための フォームID の設定。同じページに複数のフォームを置く場合、この ID によってどのフォームの処理かを判別します。

確認画面の「戻る」と「送信」フォーム分岐

main.htmlconfirm のブロックの詳細を確認していきます。

<!-- BEGIN step#confirm -->
<!-- フォームステップ:確認画面 -->

@include("/contact/form/step.html")

<div class="mt-16 px-5">
  <div class="space-y-6">      
    
    @include("/contact/form/confirm.html")

    <div class="flex gap-x-4">

        <form action="" method="post" class="w-full" enctype="multipart/form-data">
          <input type="hidden" name="step" value="reapply" />
          <input type="hidden" name="takeover" value="{takeover}" />
          <input type="submit" name="ACMS_POST_Form_Chain" value="戻って修正する" class="w-full flex justify-center py-3 px-4 border border-gray-300 rounded-md shadow-sm text-base font-medium text-gray-700 bg-white hover:bg-gray-50" />
        </form>

        <form action="thanks.html" method="post" class="w-full" enctype="multipart/form-data">
          <input type="hidden" name="To[]" value="{email}" />
          <input type="hidden" name="AdminReply-To[]" value="{email}" />
          <input type="hidden" name="AdminFrom[]" value="{email}" />
          <input type="hidden" name="step" value="result" />
          <input type="hidden" name="takeover" value="{takeover}" />
          <input type="hidden" name="id" value="contactForm" />
          <input type="submit" name="ACMS_POST_Form_Submit" value="この内容で送信する" class="w-full flex justify-center py-3 px-4 border border-transparent rounded-md shadow-sm text-base font-medium text-white bg-sky-600 hover:bg-sky-700" />
        </form>
    </div>

  </div>
</div>

<!-- END step#confirm -->

ここでは、戻って入力画面を表示させる form と、実際に送信する画面の2つの form が用意されています。

戻るボタン側

この画面では、エラーチェックが済んでいる状態なので type="hidden" name="error" は必要なく、name="step" で step#reapply に戻るような記述になっています。

<input type="hidden" name="takeover" value="{takeover}" />

新しい name="takeover" というものが出てきましたが、これはこれまでに入力した情報を引き継ぐための設定です。これによって、戻った画面で再度入力し直す必要がなく、ユーザーが入力した情報を保持したまま表示できます。

送信ボタン側

送信完了後に thanks.html へ遷移しつつ、入力内容をメールで送信するための設定です。

メール送信関連

  • To[] : 送信先アドレス

  • AdminReply-To[] : 管理者が返信する際の返信先

  • AdminFrom[] : 管理者からの送信元

フォーム制御関連

  • step="result" : 完了画面(step#result)を表示

  • takeover="{takeover}" : 入力内容を引き継ぎ再入力を省略

  • id="contactForm" : 複数フォームを識別する ID

最後の submit ボタンを押すことで、a-blog cms のフォーム処理が実行され、入力内容がメール送信されます。

type="submit" に設定される POST モジュールの役割

a-blog cms では、フォームの送信ボタンには ACMS_POST_〜 という特別な属性が使われています。これによって、送信内容の処理や画面遷移が制御されます。

  • ACMS_POST_Form_Confirm : 入力内容をバリデーション(必須チェックなど)して、次のステップ(確認画面)へ遷移させる。

  • ACMS_POST_Form_Submit : 実際に送信処理を実行し、入力内容をメールで送信や、必要に応じてデータベースに保存する。

  • ACMS_POST_Form_Chain : バリデーションを行わずに次のステップへ遷移させる。主に「戻る」ボタンで利用され、入力内容を保持したまま入力画面に戻す処理に使われる。

confirm.html を削除

contact/confirm.html については index.html の Form モジュールで表示されるようになり、使われない事になりましたので削除します。

9-9. 送信完了画面 thanks.html の調整

最後に、送信完了画面を整えます。

この画面はフォームの送信処理が完了したあとに表示されるページで、ユーザーに「送信が成功したこと」を伝える重要な役割を持っています。

contact/thanks.html の必要な部分を step#result に移設します。

<!-- BEGIN step#result -->
<!-- フォームステップ:完了画面 -->

@include("/contact/form/step.html")

<div class="mt-16 text-center">
    <div class="mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-green-100">
        <svg class="h-6 w-6 text-green-600" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
            <path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5" />
        </svg>
    </div>
    <h2 class="mt-4 text-2xl font-bold tracking-tight text-gray-900">お問い合わせありがとうございます</h2>
    <p class="mt-4 text-lg leading-8 text-gray-600">
        ご入力いただいた内容でメッセージを送信しました。<br>
        内容を確認の上、担当者より3営業日以内にご連絡いたします。
    </p>
    <div class="mt-10">
        <a href="/" class="rounded-md bg-sky-600 px-5 py-3 text-base font-semibold text-white shadow-sm hover:bg-sky-700">
            トップページへ戻る
        </a>
    </div>
</div>
<!-- END step#result -->

また、contact/thanks.html のファイルの中身を全て削除し、以下のようにします。

@include("/contact/index.html")

9-10. トップページにフォームを設置する

http://localhost/contact/ でフォームが動作するようになったら、最後にトップページ下部にあるフォームも同様に調整します。

_top.html のフォームを差し替える

/themes/sample/_top.html を開き、既存の <form>...</form> のマークアップを削除し、次のように書き換えます

<!-- BEGIN_MODULE Form -->
<!-- BEGIN step -->
  <form action="/contact/" method="post" class="space-y-6" enctype="multipart/form-data">
  
  @include("/contact/form/input.html")

  <div>
    <input type="hidden" name="step" value="confirm" />
    <input type="hidden" name="error" value="reapply" />
    <input type="hidden" name="id" value="contactForm" />
    <input type="submit" name="ACMS_POST_Form_Confirm" value="内容の確認へ" id="btnConfirm" class="w-full flex justify-center py-3 px-4 border border-transparent rounded-md shadow-sm text-base font-medium text-white bg-sky-600 hover:bg-sky-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-sky-500" />
  </div>

  </form>
<!-- END step -->
<!-- END_MODULE Form -->

ポイント

  • お問い合わせページと同じフォームをトップページにも設置できるようにする。

  • @include("/contact/form/input.html") を使うことで、入力欄の定義を共通化。

  • action="/contact/" とすることで、実際の処理は /contact/ 側のフォームに委譲。

  • こうすることで「トップからも入力 → 確認 → 完了」の流れが同じ仕組みで動作する。

9-11. メールのテンプレート

a-blog cms のフォームでは、送信完了時にメールを自動で送信する仕組みが標準で備わっています。

これらのテンプレートは /contact/form/ ディレクトリ内に含まれており、必要に応じて編集することで、送信内容を自由にカスタマイズできます。

テンプレートファイルの種類

/themes/sample/contact/form/
  ├── adminbody.txt     (管理者宛メールの本文)
  ├── adminsubject.txt  (管理者宛メールの件名)
  ├── body.txt          (ユーザー宛メールの本文)
  ├── subject.txt       (ユーザー宛メールの件名)
  ├── adminbody.html    (管理者宛メールの HTML 版)
  └── body.html         (ユーザー宛メールの HTML 版)

使い分け

  • 管理者宛メール

    • adminsubject.txt : 管理者宛メールの件名

    • adminbody.txt : 管理者宛メールの本文

    • adminbody.html : HTML メール版(必要に応じて利用)

  • ユーザー宛(自動返信メール)

    • subject.txt : ユーザー宛メールの件名

    • body.txt : ユーザー宛メールの本文

    • body.html : HTML メール版

テンプレート内で利用できる変数

入力フォームの項目はそのまま変数として利用できます。
例えば input.html で name="email" と定義した場合は {email} で参照できます。

{ name } 様

この度はお問い合わせいただき、誠にありがとうございます。
以下の内容で承りました。

--------------------
お名前: {name}
メールアドレス: {email}
お問い合わせ内容:
{message}
--------------------

担当者より折り返しご連絡いたしますので、今しばらくお待ちください。

ポイント

  • 管理者宛メールとユーザー宛メールはテンプレートを分けて管理できる。

  • HTML メールを使う場合は .html 側を編集、テキストメールで良ければ .txt のみで十分。

  • フォーム項目名を変更した場合は、このテンプレート内の変数も合わせて修正する必要がある。

ここまでで、a-blog cms 標準のフォーム機能を利用し、入力 → 確認 → 完了 → メール送信 までを実装しました。静的 HTML サイトでは難しかった仕組みも、テンプレートと管理画面を組み合わせることで短時間で構築できることが体験できたと思います。今回の内容で、実務に必要な「お問い合わせフォーム」の基本が一通り揃いました。

静的HTMLサイトのトップページを CMS 化する

「お知らせ」が CMS で管理できるようになったことで、サイト担当者が自分で更新できる基本的な仕組みが整いました。さらに、静的 HTML サイトにあったフォームについても CMS 側に実装し、一旦はここで納品を済ませたことにします。

その後、サイトのオーナーは日々のお知らせの更新が自分でできるようになると、「トップページの他の部分も自分で編集できるようにしたい」と要望するようになりました。

そこで次のステップとして、トップページの「お知らせ」以外の要素も CMS 化していく ことになります。

10. ヘッダー & フッターの情報を CMS 化する

トップページには「お知らせ」以外にも、サイト全体で共通して表示されるヘッダー部分(サイト名・キャッチコピー)とフッター部分(SNS アイコン・コピーライト) があります。これらを CMS 化することで、管理画面から一元的に更新できるようになります。

SCR-20250919-scmy

10-1. サイトタイトルの CMS 化(グローバル変数)

サイトタイトルについては、CMS 側で設定している ブログ名 をそのまま利用できるようにします。

a-blog cms には「グローバル変数」と呼ばれる仕組みがあり、サイト全体で共通して利用できる値を %{...} の形で呼び出すことができます。ブログ名は %{BLOG_NAME} で出力可能です。

これにより、管理画面からブログ名を変更すれば、ヘッダー部分にも自動的に反映されるようになります。

スマホの時のヘッダー部分(修正前 → 修正後)

<!-- 修正前 -->
<h1 class="text-lg font-bold text-gray-800 tracking-wider">
    <a href="#home">SAMPLEPLE</a>
</h1>

<!-- 修正後 -->
<h1 class="text-lg font-bold text-gray-800 tracking-wider">
    <a href="#home">%{BLOG_NAME}</a>
</h1>

PC の時のサブカラム ヘッダー部分(修正前 → 修正後)

<!-- 修正前 -->
<div class="mb-16">
    <div class="text-2xl font-bold text-white tracking-wider">
        <a href="#home">SAMPLEPLE</a>
    </div>
    <p class="text-sm text-gray-400 mt-2">
        静的HTMLからCMS化するための<br>サンプルHTML
    </p>
</div>

<!-- 修正後 -->
<div class="mb-16">
    <div class="text-2xl font-bold text-white tracking-wider">
        <a href="#home">%{BLOG_NAME}</a>
    </div>
    <p class="text-sm text-gray-400 mt-2">
        静的HTMLからCMS化するための<br>サンプルHTML
    </p>
</div>

ブログ名は管理画面の ブログ管理 で変更できます。

SCR-20250919-sjxe

↑ 「名前」の入力欄に設定されている内容が %{BLOG_NAME} として反映されます。

これにより、クライアントが管理画面でブログ名を変更するだけで、ヘッダー部分のサイトタイトルにも自動的に反映 されるようになります。

10-2. キャッチコピーの CMS 化(ブログフィールド)

サイトタイトルに続いて、キャッチコピーも管理画面から更新できるようにします。

ブログフィールドとは?

a-blog cms では、ブログ(サイト全体の単位)に紐づいたカスタムフィールドを「ブログフィールド」と呼びます。

記事やカテゴリにカスタムフィールドを持たせられるのと同じように、ブログ自体にも任意のフィールドを追加できる仕組み です。これにより、キャッチコピーのように サイト全体で共通する情報 を柔軟に管理することができます。

カスタムフィールド用ファイル field.html の作成

ブログのカスタムフィールドの作成するには、themes/sample/admin/blog というディレクトリ(フォルダ?)を作ります。そして、themes/sample/admin/blog/field.html というファイルを作りましょう。

カスタムフィールドメーカー

次に field.html の中に記述するフォームの HTML を作っていきます。この時に利用するのが「カスタムフィールドメーカー」というカスタムフィールド作成のための補助ツールになります。

  • http://localhost/bid/1/admin/customfield_maker/

SCR-20250919-solq

管理画面 の 一番左の黒いアイコンが並ぶメニューの一番下にあるスパナのアイコンをクリックすると管理者用の情報リンクが用意されています。

その一番上にある カスタムフィールドメーカー を選択してください。

SCR-20250919-spce

フィールドの設定

次のように入力します。

タイプタイトルフィールド
テキストエリアサイト説明文site_description

入力後、(生成)ボタンをクリックすると、下部に コードプレビューエリア が表示されます。 自動生成された HTML が表示されるので、(生成コードをコピー)ボタンをクリックし、その内容を /themes/sample/admin/blog/field.html に貼り付けます。

管理画面での確認

では、管理画面に項目が追加されたかを確認してみましょう。

管理画面 > ブログ管理 > カスタム設定 タブ にアクセスすると、新しく「サイト説明文」という入力欄が追加されています。

ここで入力した内容は、テンプレート内で {site_description} と書くことで呼び出せます。

テンプレートの修正例

<!-- 修正前 -->
<div class="mb-16">
    <div class="text-2xl font-bold text-white tracking-wider">
        <a href="#home">SAMPLEPLE</a>
    </div>
    <p class="text-sm text-gray-400 mt-2">
        静的HTMLからCMS化するための<br>サンプルHTML
    </p>
</div>

<!-- 修正後 -->
<div class="mb-16">
    <div class="text-2xl font-bold text-white tracking-wider">
        <a href="#home">%{BLOG_NAME}</a>
    </div>
    <!-- BEGIN_MODULE Blog_Field -->
    <p class="text-sm text-gray-400 mt-2">
        {site_description}[nl2br]
    </p>
    <!-- END_MODULE Blog_Field -->
</div>
ポイント
  • ブログフィールドで管理されているキャッチコピーは {site_description} 変数で表示
  • 変数はモジュールで囲まないと動作せず、今回は Blog_Field モジュールを利用
  • テキストエリアのデータには改行コードが含まれる可能性があり、改行コードは、校正オプションの [nl2br] を利用する

これで、ヘッダー部分の「サイト名」と「キャッチコピー」がブラウザの管理画面から更新可能になりました。

10-3. フッター部分の CMS 化(ブログフィールド)

ヘッダーと同様に、カスタムフィールドを追加します。

フィールドの設定

次のように入力します。

タイプタイトルフィールド
テキストXsns_x
テキストFacebooksns_facebook
テキストInstagramsns_instagram
テキストエリアフッターテキストsite_footer
<!-- BEGIN_MODULE Blog_Field -->
<ul class="flex space-x-4 mb-4">
    <!-- BEGIN x:veil -->
    <li>
        <a href="https://x.com/{sns_x}" class="text-gray-400 hover:text-white transition-colors">
            <span class="sr-only">X</span>
            <svg class="h-6 w-6" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true"><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/></svg>
        </a>
    </li><!-- END x:veil -->
    <!-- BEGIN facebook:veil -->
    <li>
        <a href="https://www.facebook.com/{sns_facebook}" class="text-gray-400 hover:text-white transition-colors">
            <span class="sr-only">Facebook</span>
            <svg class="h-6 w-6" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true"><path fill-rule="evenodd" d="M22 12c0-5.523-4.477-10-10-10S2 6.477 2 12c0 4.991 3.657 9.128 8.438 9.878v-6.987h-2.54V12h2.54V9.797c0-2.506 1.492-3.89 3.777-3.89 1.094 0 2.238.195 2.238.195v2.46h-1.26c-1.243 0-1.63.771-1.63 1.562V12h2.773l-.443 2.89h-2.33v6.988C18.343 21.128 22 16.991 22 12z" clip-rule="evenodd"/></svg>
        </a>
    </li><!-- END facebook:veil -->
    <!-- BEGIN instagram:veil -->
    <li>
        <a href="https://www.instagram.com/{sns_instagram}" class="text-gray-400 hover:text-white transition-colors">
            <span class="sr-only">Instagram</span>
            <svg class="h-6 w-6" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true"><path fill-rule="evenodd" d="M12 2c2.717 0 3.056.01 4.122.06 1.065.05 1.79.217 2.428.465.66.254 1.216.598 1.772 1.153a4.902 4.902 0 0 1 1.153 1.772c.247.637.415 1.363.465 2.428.047 1.066.06 1.405.06 4.122s-.013 3.056-.06 4.122c-.05 1.065-.218 1.79-.465 2.428a4.902 4.902 0 0 1-1.153 1.772 4.902 4.902 0 0 1-1.772 1.153c-.637.247-1.363.415-2.428.465-1.066.047-1.405.06-4.122.06s-3.056-.013-4.122-.06c-1.065-.05-1.79-.218-2.428-.465a4.902 4.902 0 0 1-1.772-1.153 4.902 4.902 0 0 1-1.153-1.772c-.247-.637-.415-1.363-.465-2.428C2.013 15.056 2 14.717 2 12s.013-3.056.06-4.122c.05-1.065.218-1.79.465-2.428a4.902 4.902 0 0 1 1.153-1.772A4.902 4.902 0 0 1 5.45 2.525c.637-.247 1.363-.415 2.428-.465C8.944 2.013 9.283 2 12 2Zm0 5a5 5 0 1 0 0 10 5 5 0 0 0 0-10Zm-7 5a7 7 0 1 1 14 0 7 7 0 0 1-14 0Z" clip-rule="evenodd"/></svg>
        </a>
    </li><!-- END instagram:veil -->
</ul>
<p class="text-xs text-gray-500">{site_footer}[nl2br]</p>
<!-- END_MODULE Blog_Field -->
</div>

ポイント

  • 今回も Blog_Field を利用
  • SNS の <li>..</li> は、<!-- BEGIN sns:veil --><!-- END sns:veil --> で囲む事で入力が無い時に <li>..</li> を削除することが可能
  • フッターテキストは、キャッチコピーと同様

コレで、ブログ管理 > カスタム設定 を確認すると、サイト全体の共通要素を一元管理できるようになりました。

SCR-20251012-pqhh

11. メインビジュアルを CMS 化する

トップページのメインビジュアル部分も CMS 化して、管理画面から画像とテキストを更新できるようにします。

前章 10. では ブログフィールド を使ってヘッダー情報を CMS 化しましたが、ここでは別のカスタムフィールドの仕組みである モジュールフィールド を使ってみます。

a-blog cms には、以下のように複数のカスタムフィールドが用意されています。それぞれ保存される場所が異なり、用途に応じて使い分けが可能です。

種類保存対象管理画面パス
ブログフィールドサイト全体admin/blog/field.html
カテゴリーフィールド各カテゴリーadmin/category/field.html
エントリーフィールド各記事admin/entry/field.html
ユーザーフィールド各ユーザーadmin/user/field.html
モジュールフィールド各モジュールIDadmin/module/field.html

この中の モジュールフィールド は、モジュール(例:Entry_Body や Entry_Summary など)ごとに独自のカスタムフィールドを設定できる仕組みです。今回はこの機能を使って、トップページのメインビジュアルを管理画面から更新できるようにします。

11-1. モジュールID を作成

まずはモジュールフィールドの設定単位となる モジュールID を作成します。

  1. 管理画面 > モジュールID にアクセスします。
  2. (モジュール作成)をクリックし、以下の内容を入力します。
項目設定内容
モジュールモジュールフィールド (Module_Field)
モジュールIDmain_visual
名前メインビジュアル

設定後、(作成)ボタンをクリックしてください。

11-2. ファイル を作成

ブログやエントリーのカスタムフィールドと同様に、モジュールフィールドもテンプレートファイルとして admin/module/ ディレクトリを配置します。

/themes/sample/
  └── admin/
      ├── blog/
      ├── entry/
      └── module/
         └── field.html (作成)

field.html に以下のように記述します。

@include("/admin/module/%{MODULE_ID}.html")

これにより、モジュールIDごとに異なるファイルを読み込むことができるようになります。 たとえば今回の main_visual モジュールIDの場合、次のような構成になります。

/themes/sample/
  └── admin/
      ├── blog/
      ├── entry/
      └── module/
         ├── field.html
         └── main_visual.html (作成)

こう設定することで、今回用意した「メインビジュアル」のモジュールIDの管理画面では、グローバル変数 %{MODULE_ID}main_visual に変換され最終的には main_visual.html が読み込まれることになります。

11-3. カスタムフィールドメーカー で項目を定義

次に、main_visual.html の中身を作ります。その際に便利なのが カスタムフィールドメーカー です。

タイプタイトルフィールド
テキストメインコピーmain_copy
テキストサブコピーsub_copy
メディア背景画像main_image

生成ボタンをクリックするとコードプレビューが表示されるので、 出力されたフォームHTMLをコピーし、main_visual.html に貼り付けてください。

SCR-20251011-keui

モジュールフィールドは、モジュールIDの管理画面の「条件設定タブ」の隣にある「カスタム設定タブ」に表示されます。

11-4. 表示用テンプレートの修正

モジュールID と管理画面の設定が完了したら、最後に表示用テンプレート _top.html のメインビジュアル部分を修正します。

修正前のコード

<section id="home" class="relative h-[46rem]">
    <img src="/images/main_visual.jpg" alt="美味しそうな料理のメインビジュアル" class="w-full h-full object-cover">

    <div class="absolute inset-0 bg-black/50"></div>

    <div class="absolute inset-0 flex flex-col px-4">
        <div class="flex-grow-[2]"></div>

        <div class="flex-shrink-0 text-center">
            <p class="text-4xl sm:text-5xl lg:text-6xl font-extrabold tracking-tight text-white" style="text-shadow: 2px 2px 8px rgba(0, 0, 0, 0.6);">
                感動を、一皿に込めて。
            </p>
            <p class="mt-6 max-w-2xl mx-auto text-lg sm:text-xl text-white/90" style="text-shadow: 1px 1px 4px rgba(0, 0, 0, 0.6);">
                あなたの特別な瞬間を、最高の食体験で彩ります。
            </p>
        </div>

        <div class="flex-grow"></div>
    </div>
</section>

テキストのカスタムフィールドの場合には {main_copy}{sub_copy} 定義したフィールド名を { } で囲むだけでしたが、メディアのカスタムフィールドは main_image というフィールド名でカスタムフィールドメーカーで設定しますが、表示の際には {main_image@path}{main_image@alt} のように @ で追加属性がありますので注意ください。

こちらも カスタムフィールドメーカーの出力用コード を参考にしてください。

修正後のコード

<!-- 修正後 -->
<!-- BEGIN_MODULE Module_Field id="main_visual" -->
<section id="home" class="relative h-[46rem]">
    <img src="%{MEDIA_ARCHIVES_DIR}{main_image@path}" alt="{main_image@alt}" class="w-full h-full object-cover">

    <div class="absolute inset-0 bg-black/50"></div>

    <div class="absolute inset-0 flex flex-col px-4">
        <div class="flex-grow-[2]"></div>

        <div class="flex-shrink-0 text-center">
            <p class="text-4xl sm:text-5xl lg:text-6xl font-extrabold tracking-tight text-white" style="text-shadow: 2px 2px 8px rgba(0, 0, 0, 0.6);">
                {main_copy}
            </p>
            <p class="mt-6 max-w-2xl mx-auto text-lg sm:text-xl text-white/90" style="text-shadow: 1px 1px 4px rgba(0, 0, 0, 0.6);">
                {sub_copy}
            </p>
        </div>

        <div class="flex-grow"></div>
    </div>
</section>
<!-- END_MODULE Module_Field -->

11-5. モジュールフィールドの入力画面をモーダル表示

モジュールID のカスタムフィールドは、 管理画面 > モジュールID 一覧ページ > 該当モジュールID 詳細ページ > カスタム設定 タブ と、通常は 4 回クリックして開く必要があります。

毎回この手順を踏むのは少し手間がかかるため、トップページの該当エリアから直接モーダルで編集画面を開けるように してみましょう。

編集リンクを追加する

先ほど作成した Module_Field の <section id="home" ... の直下に、以下のインクルード文を追加してください。

@include("/include/edit/module-custom.html",{"hash":"#acms_box3"})

SCR-20251011-kjmw

このコードを追加すると、メインビジュアルコンテンツの右上に「編集する」というリンクが表示されます。

SCR-20251011-kkwg

ポイント

@include("/include/edit/module-custom.html") は、a-blog cms に標準で用意されている管理画面ショートカット機能 を呼び出す仕組みです。

a-blog cms は、カスタムフィールドをはじめ、管理画面の UI についてもカスタマイズでき、運用者のことを考えた UI を追加実装できる点も特徴にあげられます。

12. About コンテンツを CMS 化する

前章の 11. メインビジュアルを CMS 化する と同様の手順で、About セクションも モジュールフィールド を利用して CMS 化していきます。

これにより、運用者が管理画面から自由にテキストや画像を変更できるようになります。

変更前

<section id="about" class="py-14 sm:py-20 bg-white">
    <div class="max-w-3xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
        <h2 class="text-3xl font-bold tracking-tight text-gray-900 sm:text-4xl mt-2">About</h2>
        <p class="mt-4 text-2xl font-semibold text-sky-600">最高の食体験を、すべての人へ。</p>
        <p class="mt-6 text-lg leading-8 text-gray-600">
            私たちは、厳選された食材と革新的なアイデアを融合させ、心に残るダイニング体験を創造します。お客様一人ひとりの特別な日を、最高の料理とサービスで彩ることが私たちの使命です。
        </p>
    </div>
</section>

前章の手順を応用して、以下の項目をモジュールフィールドとして管理できるようにしてください。

タイプタイトルフィールド
テキストセクションタイトルabout_title
テキストサブタイトルabout_subtitle
テキストエリア説明文about_text

作業内容は 第11章と同じ手順 になりますので、ここではあえて詳細な説明は省略します。

ぜひ自分の手で設定を進めてみて、モジュールフィールドの仕組みをもう一度確認してみましょう。

13. ヘッダー・フッターを共通化してテンプレートを整理する

これまで、トップページのヘッダーやフッターを CMS 化してきました。 しかし、News や Contact ページでは、まだ静的 HTML のまま同じ構造が残っています。

このままでは、デザイン変更や CMS 情報の修正を行うたびに複数ページを更新する必要があり、保守性が低下します。

ここでは、ヘッダーとフッターをインクルードファイルとして共通化 し、全ページから同じテンプレートを読み込むようにします。

13-1. include ディレクトリの作成

テーマディレクトリ内に共通パーツをまとめるための include ディレクトリを作成します。

/themes/sample/
  ├── _top.html 
  ├── admin/
  ├── contact/
  ├── css/
  ├── images/
  ├── include (追加)
  ├── news/
  └── service/

include ディレクトリには、ヘッダーやサイドカラムなどの共通パーツを配置します。

今回のサイト構成では、一般的な「フッター」よりも 右カラム(aside) がグローバルな情報をまとめる役割を果たしているため、footer.html の代わりに aside.html を用意することにします。

13-2. 共通パーツのファイルを作成

include ディレクトリに以下のファイルを作成します。

/themes/sample/include/
  ├── header.html
  └── aside.html

まずは、_top.html の <header> 部分を include/header.html に、<aside> 部分を include/aside.html にコピーします。

header.html

<header class="fixed top-0 left-0 right-0 z-30 flex items-center justify-between h-16 px-4 bg-white shadow-md lg:hidden">
    <button
        @click="sidebarOpen = !sidebarOpen"
        class="p-2 -ml-2"
        aria-controls="sidebar"
        :aria-expanded="sidebarOpen">
        <span class="sr-only">サイトバーを開く</span>
        <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
        </svg>
    </button>

    <h1 class="text-lg font-bold text-gray-800 tracking-wider">
        <a href="#home">%{BLOG_NAME}</a>
    </h1>

    <a href="#contact" class="px-3 py-1.5 text-sm font-semibold text-white bg-sky-500 rounded-md hover:bg-sky-600 transition-colors">
        Contact
    </a>
</header>

aside.html(抜粋)

<aside
    id="sidebar"
    class="fixed top-0 left-0 h-screen w-72 bg-gray-900 flex flex-col justify-between p-8 transform -translate-x-full transition-transform duration-300 ease-in-out z-50 lg:translate-x-0 lg:shadow-none"
    :class="{ 'translate-x-0 shadow-2xl': sidebarOpen }">

    <div>
        <div class="mb-16">
            <div class="text-2xl font-bold text-white tracking-wider">
                <a href="#home">%{BLOG_NAME}</a>

... (略) ...

    <p class="text-xs text-gray-500">{site_footer}[nl2br]</p>
    <!-- END_MODULE Blog_Field -->
    </div>
</aside>

また、<header> 部分は、インクルード文に置き換え、<aside> も同様に書き換えてください。

@include("/include/header.html")

13-3. 各テンプレートでインクルード

_top.html 以外に、これまでテンプレート化したファイルは、以下の3つになります。

  • news/index.html
  • news/_entry.html
  • contact/index.html

これらも修正していく必要があります。news/index.html<header> が同じであれば、@include("/include/header.html") に置き換えてください。

今回のサイトは、しっかり SEO対策を考え見出し構成を考えているサイト作りを考えて実装されており、トップページと中ページで見出しが変わっていることが比較してみると分かります。

_top.html

<h1 class="text-lg font-bold text-gray-800 tracking-wider">
    <a href="#home">%{BLOG_NAME}</a>
</h1>

news/index.html

<p class="text-lg font-bold text-gray-800 tracking-wider">
    <a href="/#home">SAMPLEPLE</a>
</p>

修正前 include/header.html

<h1 class="text-lg font-bold text-gray-800 tracking-wider">
    <a href="#home">%{BLOG_NAME}</a>
</h1>

修正後 include/header.html

この場合の時に表示する、それ以外の時には BEGIN 〜 END の部分を消すことができる タッチモジュール というモジュールが色々用意されています。

今回は、トップページの時 Touch_Top と、それ以外の時の Touch_NotTop で分岐する設定を

<!-- BEGIN_MODULE Touch_Top -->
<h1 class="text-lg font-bold text-gray-800 tracking-wider">
    <a href="#home">%{BLOG_NAME}</a>
</h1>
<!-- END_MODULE Touch_Top -->
<!-- BEGIN_MODULE Touch_NotTop -->
<p class="text-lg font-bold text-gray-800 tracking-wider">
    <a href="/#home">%{BLOG_NAME}</a>
</p>
<!-- END_MODULE Touch_NotTop -->

aside.html のナビゲーションを調整

include/aside.html に記述されている <nav role="navigation"> の設定は、トップページではページ遷移を行わずにスムーズスクロールで移動し、その他のページではトップページへ遷移して対象セクションにスクロールする という動作になっています。

また、現在表示中のページを示すための アクティブクラス の指定もトップページとそれ以外で異なるため、分岐処理を追加して調整します。

<!-- BEGIN_MODULE Touch_Top -->
<nav role="navigation">
    <ul class="space-y-5 text-lg">
        <li><a href="/#home" @click="sidebarOpen = false"
                :class="activeLink === '#home' ? 'text-white font-semibold border-l-2 border-sky-400 pl-4' : 'text-gray-400 hover:text-white transition-colors'"
                :aria-current="activeLink === '#home' ? 'page' : false">Home</a></li>
        <li><a href="/#about" @click="sidebarOpen = false"
                :class="activeLink === '#about' ? 'text-white font-semibold border-l-2 border-sky-400 pl-4' : 'text-gray-400 hover:text-white transition-colors'"
                :aria-current="activeLink === '#about' ? 'page' : false">About</a></li>
        <li><a href="/#service" @click="sidebarOpen = false"
                :class="activeLink === '#service' ? 'text-white font-semibold border-l-2 border-sky-400 pl-4' : 'text-gray-400 hover:text-white transition-colors'"
                :aria-current="activeLink === '#service' ? 'page' : false">Service</a></li>
        <li><a href="/#news" @click="sidebarOpen = false"
                :class="activeLink === '#news' ? 'text-white font-semibold border-l-2 border-sky-400 pl-4' : 'text-gray-400 hover:text-white transition-colors'"
                :aria-current="activeLink === '#news' ? 'page' : false">News</a></li>
        <li><a href="/#contact" @click="sidebarOpen = false"
                :class="activeLink === '#contact' ? 'text-white font-semibold border-l-2 border-sky-400 pl-4' : 'text-gray-400 hover:text-white transition-colors'"
                :aria-current="activeLink === '#contact' ? 'page' : false">Contact</a></li>
    </ul>
</nav>
<!-- END_MODULE Touch_Top -->
<!-- BEGIN_MODULE Touch_NotTop -->
<nav role="navigation">
    <ul class="space-y-5 text-lg">
        <li><a href="/#home" @click="sidebarOpen = false" class="text-gray-400 hover:text-white transition-colors">Home</a></li>
        <li><a href="/#about" @click="sidebarOpen = false" <!-- BEGIN_IF [%{CCD}/eq/about] -->class="text-white font-semibold border-l-2 border-sky-400 pl-4" aria-current="page"<!-- ELSE -->class="text-gray-400 hover:text-white transition-colors"<!-- END_IF-->>About</a></li>
        <li><a href="/#service" @click="sidebarOpen = false" <!-- BEGIN_IF [%{CCD}/eq/service] -->class="text-white font-semibold border-l-2 border-sky-400 pl-4" aria-current="page"<!-- ELSE -->class="text-gray-400 hover:text-white transition-colors"<!-- END_IF-->>Service</a></li>
        <li><a href="/#news" @click="sidebarOpen = false" <!-- BEGIN_IF [%{CCD}/eq/news] -->class="text-white font-semibold border-l-2 border-sky-400 pl-4" aria-current="page"<!-- ELSE -->class="text-gray-400 hover:text-white transition-colors"<!-- END_IF-->>News</a></li>
        <li><a href="/#contact" @click="sidebarOpen = false" <!-- BEGIN_IF [%{CCD}/eq/contact] -->class="text-white font-semibold border-l-2 border-sky-400 pl-4" aria-current="page"<!-- ELSE -->class="text-gray-400 hover:text-white transition-colors"<!-- END_IF-->>Contact</a></li>
    </ul>
</nav>
<!-- END_MODULE Touch_NotTop -->

Touch_Top / Touch_NotTop は、トップページとそれ以外のページで出力内容を切り替えるための a-blog cms の条件分岐をするためのタッチモジュールです。トップページでは Alpine.js の activeLink を利用して現在位置に応じて動的にクラスを切り替えます。中ページでは CMS 側の変数 %{CCD}(現在のカテゴリーコード)を利用し、表示中のカテゴリに応じて aria-current="page" とスタイルを付与します。これにより、トップページではスムーズスクロール、それ以外のページでは通常遷移+アクティブ強調を実現します。