承認申請画面でデフォルト承認者を設定できるようにするカスタマイズ
今回のカスタマイズのゴールは、採用情報の投稿者Jが特定の編集者Hに承認依頼を行うことを便利にする、ミスを減らすことができるようにすることを考えてカスタマイズを進めていく事にします。
今回のサイトの構成
システムとしては a-blog cms プロフェッショナル版 を利用します。
ルートブログや子ブログに架空のダミーデータでユーザーを用意しています。実際には、もっと多くの人が登録されている場合もありますが、それぞれ 管理者・編集者・投稿者 の権限のユーザーを用意しました。
ルートブログ / bid=1
お知らせ / news / bid=2
採用情報 / recruit / bid=3
標準的な承認画面
標準的には、全員(編集者, 管理者)が選択された状態になっております。以下に実際の 選択UI を触れるようにしています。
今回の業務フローとして、承認者は 杉本さん(投稿者J)が、上司である村瀬さん(編集者H)に依頼したいところが、5人に対して承認依頼のメールを送ってしまう事になります。
具体的なカスタマイズ目標
ユーザーのカスタムフィールドでデフォルトの承認依頼をしたい人を設定できるようにする をメインの目標とします。加えて部署名も表示できるようにし、もし、上司である村瀬さん(編集者H)が不在の際に、同じ部署の承認可能な方が誰かも分かるようにします。
各ユーザーの情報を設定できるようにする
ユーザー情報にカスタムフィールドの設定することができるようにします。
- 承認したい人を選択できる SELECT UI
- 部署名を設定できるような INPUT UI
themes/*利用しているテーマ名*/admin/user/field.html を編集します。
admin/user/field.html
<table class="acms-admin-table-admin-edit"> <tr> <th>部署名</th> <td> <input type="text" name="division" value="{division}" class="acms-admin-form-width-mini" /> <input type="hidden" name="field[]" value="division" /> </td> </tr> <tr> <th>承認ユーザー</th> <td> <select name="approval_user" class="acms-admin-form-width-mini"> <option value=""></option> <!-- BEGIN_MODULE User_Search id="approval_user_list" --> <!-- BEGIN user:loop --> <option value="{id}" \{approval_user:selected#{id}\}>{name}</option> <!-- END user:loop --> <!-- END_MODULE User_Search --> </select> <input type="hidden" name="field[]" value="approval_user" /> </td> </tr> </table>
承認ユーザーを選択肢を表示させるために bid=1 のモジュールID 設定に User_Search モジュール id="approval_user_list" をグローバル化して設定します。
条件設定については運用次第ではありますが、他のブログのユーザーが表示された方がいい場合には、bid=1 を指定し、階層の設定を「下階層のブログも含める ( descendant-or-self )」を設定ください。
同一ブログのユーザーのみの場合には、bid を指定しないようにすることで子ブログ内のユーザーのみをリスト表示が可能です。
ログインユーザーの情報をどこでも利用できるようにする
a-blog cms の情報をいつでも、どこでも利用できるようにする際には、グローバル変数という変数に値を持たせることで管理できるようにします。例えば、%{NOW_DATE} のようにテンプレート書くと今日の日付を表示ができるようなものになります。
今回はログインしている際に、ユーザーのカスタムフィールド approval_user をグローバル変数化し %{APPROVAL_USER} で、テンプレートのどこでも利用することを可能にします。
extension/acms/hook.php
public function extendsGlobalVars(&$globalVars) { if ( SUID ) { $field = loadUserField(SUID); $globalVars->set('APPROVAL_USER', $field->get('approval_user')); } }
config.server.php
hook.php の記述を有効にするには、config.server.php の HOOK_ENABLE を 1 に設定を変更する必要があります。
define('HOOK_ENABLE', 1);
承認画面のカスタマイズ
標準的な承認画面 のところで表示していた画面の URL は
http://localhost/recruit/entry-52.html/tpl/ajax/revision-preview.html?rvid=4
のようになっていました。
http://localhost/recruit/entry-52.html のページの情報を
/tpl/ajax/revision-preview.html でテンプレートを置き換えて表示させています。
/themes/system/ajax/revision-preview.html が対象のテンプレートになりますが、このテンプレートファイルをご利用中のテーマにコピーしてカスタマイズするようにしてください。
ajax/revision-preview.html
<!-- BEGIN_MODULE Approval_NextUsergroup --> <div class="acms-admin-margin-top-small"> <span class="acms-admin-label acms-admin-clear"><!--T-->次の承認者<!--/T--></span> </div> <select name="receiver" id="input-nextGroup" class="acms-admin-revision-sidebar-select js-select2 acms-admin-margin-top-small"><!-- BEGIN group:loop --> <option value="{nextGroup}:0"><!--T-->全員<!--/T-->({nextGroupName})</option> <!-- END group:loop --><!-- BEGIN user:loop --> <option value="{nextGroup}:{user_id}" <!-- BEGIN_IF [%{APPROVAL_USER}/eq/{user_id}] --> selected="selected" <!-- END_IF --> >{user_name} <!-- BEGIN division:veil -->({division})<!-- END division:veil --></option><!-- END user:loop --> </select> <input type="hidden" name="approval[]" value="receiver" /> <input type="hidden" name="current_group" value="{currentGroup}" /> <!-- END_MODULE Approval_NextUsergroup -->
オマケ : ユーザー管理の一覧にも部署名を表示
ユーザーの管理画面の URL は http://localhost/bid/3/admin/user_index/ のようになっていました。その場合には themes/system/admin/user/index.html に元のテンプレートがありますので、ご自身のテーマの同階層にファイルをコピーしてカスタマイズしてください。
admin/user/index.html
<div class="acms-admin-summary-body"> <strong>{name}</strong> / {code}<br>{mail} </div>
が名前やメールアドレスを表示させているところになりますので、ここに上記で追加したカスタムフィールド division と approval_user を追加します。
approval_user が数字で分かりにくいですが、今回は設定があることだけをお伝えする事とし、id を文字列にする方法については別の機会で紹介させていただきます。
<div class="acms-admin-summary-body"> <strong>{name}</strong> / {code} <!-- BEGIN division:veil -->/ {division}<!-- END division:veil --> <!-- BEGIN approval_user:veil --> ({approval_user})<!-- END approval_user:veil --><br>{mail} </div>
<!-- BEGIN division:veil -->〜<!-- END division:veil --> で囲まれている点を補足しておきます。これは {division} に情報が何も編集されない時には囲まれている部分を表示させないという記述になります。値が無い時に / や () だけ表示されないようにしています。
最後に
今回は、プロフェショナル版での承認機能についてのカスタマイズについて紹介させていただきました。 普段、使えない機能となっておりますが、MYPAGE の開発ライセンス から試しに使ってみたいドメインを設定することで、購入することなく試すことが可能です。
標準的な機能として用意されていないものであっても、今回のようにカスタマイズでしっかり希望の運用ルールに近づけることも出来ます。もし、こうしたいがカスタマイズで難しい場合にはご相談ください。
Custom Search API との連携
JSON形式のデータを表示させることができるビルトインモジュール Json_2Tpl とGoogleの検索結果をJSON形式で取得することができるCustom Search API を連携させて Google の検索結果を使用するサイト内検索を実装することができます。
a-blog cms標準のサイト内検索機能はエントリー単位の検索ですが、 Custom Search API を連携させることで、一覧ページやトップページなどのページも検索対象に含めることができます。また、検索結果自動的に関連度順に表示されるため、普段Googleで検索するときのような検索体験を実現することができます。
Googleのサイト内検索を実装するためには以下の情報が必要になります。
- GoogleのAPIキー
- Googleカスタム検索エンジンの検索エンジンID
準備1: APIキーを用意する
Google Cloud Platform の管理画面からAPIキーを作成してください。 https://console.cloud.google.com/
必要であればIP アドレス(ウェブサーバー、cron ジョブなど)でAPIキーを使用できるウェブサイト、IP アドレス、アプリケーションを制御してください。
※Json_2Tpl ではwebサーバー側でHTTPリクエストを送信するため、HTTPリファラー(URL)による制限はできません。

また、APIの制限も行いましょう。

準備2: 検索エンジンの設定
Google カスタム検索エンジンにログインして、検索エンジンの作成と検索エンジンIDの取得をします。
https://programmablesearchengine.google.com/
1. 検索エンジンの作成
検索対象のドメインと任意の名前を設定して検索エンジンを作成します。
注意点として検索できるサイトでないといけないので、ablogcms.ioなどではなく、ご自身のサイトなどを設定ください。

2. 検索エンジンIDの取得
コントロールパネルの「基本」タブ内、検索エンジン IDをコピーします。

サイト内検索の実装
APIキーと検索エンジンIDがそろったらa-blog cmsのカスタマイズを行い、Googleの検索結果を使用したサイト内検索を実装します。
1. モジュールIDの作成・設定
Json_2Tpl モジュールのモジュールIDを作成し、表示設定のJSONファイルに以下のURLを設定します。
https://www.googleapis.com/customsearch/v1?key=認証キー&cx=検索エンジンID&q=%{KEYWORD}&hl=ja&start=%{start}
&start=%{start}
の部分はページャー機能を実装する場合に必要になります。
2. テンプレートの記述
Json_2Tplのテンプレートを書くためには、jsonの中身を確認する必要がありますが、例えばキーワードを "api" としたとき、検索結果のデータを1件目から取得したい場合は下記のURLをブラウザのアドレスバーに入力して検索すると、jsonの中身を確認することができます。
https://www.googleapis.com/customsearch/v1?key=認証キー&cx=検索エンジンID&q=api&hl=ja&start=1
jsonデータの中身が確認できたら、Json_2Tpl の テンプレートの書き方 を参考に検索結果を表示するテンプレートを記述します。
<!-- BEGIN_MODULE Json_2Tpl id="google_custom_search" -->
<div class="google-search clearfix">
<!-- BEGIN items:loop -->
<div class="search-item clearfix">
<h2>
<a href="{link}">{htmlTitle}[raw]</a>
</h2>
<p class="link">{link}[trim(100, '...')]</p>
<div class="acms-col-md-10">
<p>{snippet}</p>
</div>
<div class="acms-col-md-2 acms-sp-hide">
<!-- BEGIN pagemap -->
<!-- BEGEN metatags:loop -->
<img src="{og:image}[resizeImg(130)]" width="130">
<!-- END metatags:loop -->
<!-- END pagemap -->
</div>
</div>
<!-- END items:loop -->
<ul class="search-pager">
<!-- BEGIN queries -->
<!-- BEGIN previousPage:loop -->
<li class="link-item">
<a href="search.html?keyword=%{KEYWORD}&start={startIndex}" class="btn">前</a>
</li>
<!-- END previousPage:loop -->
<!-- BEGIN nextPage:loop -->
<li class="link-item">
<a href="search.html?keyword=%{KEYWORD}&start={startIndex}" class="btn">次</a>
</li>
<!-- END nextPage:loop -->
<!-- END queries -->
</ul>
</div>
<!-- END_MODULE Json_2Tpl -->
ページャーは、a-blog cms標準機能であるクエリストリングの値をグローバル変数として取得するを利用して実装しています。
具体的には、{startIndex}
の値をクエリストリングに渡すことで、Json_2Tpl モジュールの表示設定、JSONファイルで設定したURLの %{start}
のグローバル変数が {startIndex}
を参照するようになります。
次にキーワード検索をするためのフォームを設置します。
<form action="/search.html" class="search-form" method="post" role="search" aria-label="検索フォーム">
<input type="hidden" name="tpl" value="/search.html">
<input type="hidden" name="query[]" value="keyword">
<input type="hidden" name="query[]" value="start">
<input type="hidden" name="bid" value="%{BID}">
<input type="hidden" name="start" value="1">
<input type="text" name="keyword" class="search-form-text" value="%{KEYWORD}" size="15" placeholder="検索キーワード">
<span class="search-form-btn-wrap">
<button type="submit" name="ACMS_POST_2GET" class="search-form-btn"><span class="acms-icon-search"></span>
</button>
</span>
</form>
完成

検索フォームに適当な検索ワードを入力し、検索ボタンをクリックした時に、画像のような検索画面が表示されていれば完成です。スタイルやHTMLの構造を変えることで、オリジナルのレイアウトにすることも可能です。
追記:複数ワード対応
上記の実装で検索はヒットするようになりましたが、複数ワードをスペースで区切って検索すると検索結果が出てきません。
方法としては、半角スペース&全角スペースを半角カンマに置き換えたグローバル変数 %{API_KEYWORD}
を作成し、利用する事で複数ワードでの検索に対応できるようになります。
config.server.php
define('HOOK_ENABLE', 1);
extension/acms/Hook.php
/**
* グローバル変数の拡張
*
* @param array $globalVars
*/
public function extendsGlobalVars(&$globalVars)
{
// $globalVars->set('key', 'var');
$globalVars->set('API_KEYWORD', str_replace(' ', ',', mb_convert_kana(KEYWORD,'s','utf-8')));
}
- モジュールIDの作成・設定 の Json_2Tpl の設定画面で
%{KEYWORD}
と設定していた部分を%{API_KEYWORD}
と修正ください。
Ver. 3.1.18 リリースのお知らせ
この記事では、2024年6月26日にリリースした Ver. 3.1.18の修正内容について紹介いたします。
現在お困りの問題に該当する項目がありましたら、お早めにバージョンアップのご検討をお願いいたします。
Ver. 3.1.18 リリースノート
修正点
- CMS-6844 ログイン時に、ログインページにアクセスした場合、現在のブログのトップページにリダイレクトするよう修正
- CMS-6846 config.server.phpが存在する場合chmodさせないように修正
- CMS-6848 管理画面ダッシュボードのデバッグモード時のアラートをconfig.server.phpの値のみで判断してアラートを出すように修正(各ユーザーの動作モードは考慮しない)
- CMS-6849 Ver. 3.1.12より、タグ選択用プルダウン、関連エントリー選択用プルダウン、メニュー管理、ナビゲーションモジュールで、<, >, & の文字が2重エスケープスする問題を修正
- CMS-6783 モジュールIDのセルが改行される問題を修正
主なリリースノートの詳細な内容
CMS-6844 ログイン時に、ログインページにアクセスした場合、現在のブログのトップページにリダイレクトするよう修正
今までのバージョンだと、ログイン時にログインページ(/login/)にアクセスした場合、サイトルートのURLにリダイレクトされていましたが、これをログインページを表示したときのブログにリダイレクトするように修正いたしました。
これにより、子ブログのユーザーが間違ってログインURLにアクセスしたとき、ルートブログに移動してしまいログアウトしたと勘違いしてしまう問題が解消されます。
今までの挙動
リダイレクト元: https://example.com/member/login/
リダイレクト先: https://example.com
修正された挙動
リダイレクト元: https://example.com/member/login/
リダイレクト先: https://example.com/lmember/
CMS-6848 管理画面ダッシュボードのデバッグモード時のアラートをconfig.server.phpの値のみで判断してアラートを出すように修正(各ユーザーの動作モードは考慮しない)
管理画面ダッシュボードのデバッグモード時に表示するアラートの表示条件を修正しました。
今までの表示条件
現状の動作モードでのみ判定しているため、ログインユーザーの個々の設定でデバッグモードにしている場合も表示されていました。 これにより、config.server.phpはデバッグモードオフなのにアラートが出ているため、混乱するポイントになっていました。
修正された表示条件
config.server.phpの設定を見て、アラートを表示するようにしているので、各ユーザーのデバッグモード設定は無視するようになりました。
最後に
該当する問題がありましたら、お早めにバージョンアップのご検討をお願いいたします。
また、迅速にご報告いただいたユーザーの皆さま、誠にありがとうございました。
今後もご報告いただいた内容に対して真摯に受け止め修正と改善を行ってまいります。
今後ともどうぞよろしくお願いいたします。