開発環境が整ったテーマ「Develop」を触ってみよう

このハンズオン記事ではVer.2.11から追加された、開発環境が整ったテーマ「Develop」を触ってみましょう。

ここでは、ローカル環境に a-blog cms をインストール状態を例に解説していきます(ablogcms.io では行えません)。環境が異なる場合はご自身の環境に合わせて読み替えてください。

このハンズオンでは、npm(Node Package Manager)が必要です。インストールされていない方は、 https://nodejs.org/ja/download から環境にあったインストーラーをダウンロードしてインストールください。

「develop」テーマとは

Ver.2.11より同梱された新しいテーマです。a-blog cms を開発する際によく使うテンプレートをシンプルにしたものを同梱していますが、フロントエンドに関する開発環境も整えられています。

機能


機能 概要
SCSSのコンパイル SCSSをCSSにコンパイルします。
JSファイルの結合 複数のJSファイルを1つのファイルに結合します。
コードのLintチェック ESLintやstylelintを使用して、JSやSCSSおよびCSSのコードをチェックします。
Live Reload ファイルの変更があった場合に、ブラウザを自動的にリロードします。
ソースコードの整形 EditorConfigを使い、ソースコードを整形します。
SVGアイコンの使用 Font Awesome 5 のSVG with JavaScriptを利用して、SVGアイコンを表示します。

はじめてみよう

ローカル環境に a-blog cms をインストールしてください。ターミナルで、developテーマを設置しているディレクトリまで移動します。

$ cd  /themes/develop/

移動できたら、npm をインストールします。

$ npm install

※現在お配りしているdevelopテーマではstylelintが入らないようになっているので、以下のように別途インストールしてください。

$ npm i stylelint stylelint-config-rational-order stylelint-config-recommended stylelint-scss --save

テーマ名(デフォルト: develop)を変更した場合は、package.json の config.theme を変更してください。もし、LiveReload を使用する場合は、実行しているローカル環境のアドレスに合わせて config.local を変更してください。

/themes/develop/package.json

"config": {
  "local": "localhost",
  "theme": "テーマ名"
},

用意しているビルドコマンドについて

コマンドは、npm run **になります。**の部分に下記のコマンドが入ります。


コマンド 概要
start CSSとJSファイルの変更を監視してビルドを行う。LiveReloadあり。
dev CSSとJSファイルの変更を監視してビルドを行う。
build CSSとJSファイルのビルドを行う。納品時には使用する。

npm run startnpm run dev では、JavaScriptに余分なコードが入ったり、最適化されません。納品時には必ず npm run build を行なってください。

一度、npm run startと実行すると、以下のページが立ち上がるのを確認してみてください。


localhost:3000 でページが立ち上がります


基本的なテーマの使い方は以上となります。 それでは、このハンズオン記事では以下のことを行なっていきます。

  • 組み込みJSを使わず、lazy-loadを使ってみよう
  • ファーストビューに含まれるCSSをインライン化してみよう
  • Font Awesome 5 のSVG with JavaScriptを使ってみよう

組み込みJSを使わず、lazy-loadを使ってみよう

パフォーマンス向上のために、組み込みJSを外す場合は、include/head/js.html で読み込んでいる組み込み JSをTouch_SessionWithContribution を使って、投稿者以上の場合だけ読み込むようにします。

/include/head/js.html

developテーマの/include/head/js.htmlには以下のように記述されています。タッチモジュールの冒頭に「!(エクスクラメーション)」が記述されているので、今回は削除してください。

<!-- 組み込みJSを使わない場合、エクスクラメーションを外して、投稿者以上の場合だけ読み込むようにする -->
<!-- !BEGIN_MODULE Touch_SessionWithContribution -->
<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 -->
<!-- !END_MODULE Touch_SessionWithContribution -->

以下のようになります。

<!-- 組み込みJSを使わない場合、エクスクラメーションを外して、投稿者以上の場合だけ読み込むようにする -->
<!-- BEGIN_MODULE Touch_SessionWithContribution -->
<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 -->
<!-- END_MODULE Touch_SessionWithContribution -->

組み込みJSを読み込まない場合、スライダーや画像ビューワーなどのすべての組み込みJSが動作しなくなるためご注意ください。

必要な機能やライブラリは、自分でインストール、実装する必要があります。

バンドル環境が整っていますので、 npm経由でライブラリをインストールし、 importする方式をお勧めします。以下 Lazy Load を実装する例になります。

$ npm i vanilla-lazyload

index.js 6行目

import LazyLoad from 'vanilla-lazyload';

index.js 34行目 domContentLoadedイベント内に追記

domContentLoaded(() => {
  new LazyLoad({elements_selector: '.js-lazy-load'});
});

HTMLに以下のソースコードを記述して、表示してみましょう。 成功した場合、一瞬プレースホルダー画像が現れた後、すぐに猫の写真が表示されます。

<img data-src="http://placekitten.com/400/300" src="/images/placeholder/image.svg" width="400" class="js-lazy-load">

ファーストビューに含まれるCSSをインライン化してみよう

スタイルの読み込みについて

カスタムスタイルは、include/head/preload.html で読んでいます。 以下記述のように preload 属性を使って読み込むようにしており、非同期でスタイルを読み込んでいます。

<link rel="preload" href="/dest/bundle.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="/dest/bundle.css"></noscript>

Above the fold(ファーストビュー)に含まれる CSS のインライン化

preload属性を使って、非同期にスタイルを読むようにしたことで、スタイル読み込みでブロックされずレンダリングが速くなります。 ただその影響で、スタイルが当たっていないHTMLが一瞬表示される可能性があります。これを解決するために、Above the fold(ファーストビュー)のCSSをインライン化して読み込みます。

手順

  1. ファーストビューのスタイルが完成したら、themes/develop/src/index.html に 現在のソース貼り付けます。(ブラウザで表示したときのソースを貼り付ける)
  2. npm run build コマンドを実行します。
  3. ビルドコマンドを実行すると、themes/develop/dest/index.html にファイルができます。
  4. dest/index.html にインラインCSSが書き出されている(17行目あたり)ので、このCSSを、include/head/preload.html に設置します。
<style>
<!-- ファーストビュー(above the fold )のインラインCSS を挿入。インラインCSSは webpackでbuildすると、dest/index.html に生成される。 -->
</style>

ファーストビューのスタイルの配布

ハンズオンしやすいように、簡単なスタイルを用意したファイルを用意しました。以下のファイルをご利用ください。


所定の場所にファイルをおいたら、$ npm run startすると以下のようなページが作成されます。


ページの表示を確認できたら、上記の手順に沿ってnpm run buildしてみてください。

確認方法

ちゃんとファーストビューのインラインのCSSが読み込まれているかどうかは、ブラウザの開発者ツールから確認できます。Google Chrome をお使いの場合は、下記の手順で確認できます。

  1. Networkタブを開く
  2. 実装したドメインと同じ項目を探し、クリックする
  3. Previewタブを開く

そうすると、通常であればCSSが当たっていない素のHTML表示されますが、スタイルが当たったHTML要素が確認できます。もし、CSSが当たっていないHTMLが表示された場合は、手順を見直してください。


preload.htmlにインラインCSSを記述していない場合

preload.htmlにインラインCSSを記述した場合

preload.htmlではファーストビューで使用しているCSSを記述すればいいので、今後開発して行く際はいつものように制作していただければ大丈夫です。

Font Awesome 5 のSVG with JavaScriptを使ってみよう

アイコンの利用を考え、developテーマでは、Font Awesome 5 の SVG with JavaScript が利用できるようになっています。

アイコンのインポート

SVG with JavaScript では必要なアイコンのみインポートして利用します。 アイコンの種類により、インポートするパッケージが違うので気をつけてください。例えばブランドアイコン系は、@fortawesome/free-brands-svg-icons から読み込みます。

themes/develop/src/fonts.js

import { faUser, faSignOutAlt } from '@fortawesome/free-solid-svg-icons';
import { faFacebook, faTwitter, faInstagram } from '@fortawesome/free-brands-svg-icons';

命名規則はクラス名(ケバブケース)をキャメルケースにしたものになります。

.fa-sign-out-alt のアイコンを使いたい場合は、 faSignOutAlt を読み込みます。

themes/develop/src/fonts.js

import { faSignOutAlt } from '@fortawesome/free-solid-svg-icons';

アイコンの登録

インポートしたアイコンを以下のように使用できるように登録します。使用するアイコン全てを指定します。

themes/develop/src/fonts.js

library.add(faUser, faSignOutAlt, faFacebook, faTwitter, faInstagram);

アイコンの表示

あとは、以下のようにアイコンを表示させることができます。

<i class="fab fa-twitter"></i>
<i class="fab fa-facebook"></i>
<i class="fas fa-sign-out-alt"></i>

Font Awsome の公式サイトから好きなアイコンを探して、developテーマで使えるようにしてみましょう。

使いやすい編集画面を作ってみよう


この口座はa-blog cms Training Camp 2021 Autumnで行った内容です。
当日の内容がYouTubeに上がっているため、よければご覧ください。



下準備

管理画面側で読み込むCSSとJavaScriptファイルを作成して、エントリー編集画面に読み込んでおきましょう。

実践

使用テーマ直下に admin-asset 作成し、フォルダの中に field-edit.css と field-edit.js を作成しておきます。

1. 管理画面側編集ページでの読み込み

/使用テーマ/admin.htmlをひらき、 先程作成したcssとjsファイルを Touch_Edit の中で下記のように読み込みます。

@extends("/_layouts/admin.html")

@section("admin-css")
@parent

<!-- カスタムCSSを記述 -->
<!-- BEGIN_MODULE Touch_Edit -->
<link rel="stylesheet" href="/dest/admin.css">
<link rel="stylesheet" href="/admin-asset/field-edit.css">
<!-- END_MODULE Touch_Edit -->
@endsection

@section("admin-js")
@parent

<!-- カスタムJSを記述 -->
<script src="/dest/vendor.js" async></script>
<script src="/dest/admin.js" charset="UTF-8"></script>
<!-- BEGIN_MODULE Touch_Edit -->
<script src="/admin-asset/field-edit.js"></script>
<!-- END_MODULE Touch_Edit -->
@endsection

2. 表側編集ページでの読み込み

/使用テーマ/include/head/link.html をひらき、 作成したcssファイルを Touch_SessionWithContribution の中で下記のように読み込みます。

<!-- BEGIN_MODULE Touch_SessionWithContribution -->
<link rel="stylesheet" href="/css/acms-admin.min.css">
<link rel="stylesheet" href="/admin-asset/field-edit.css">
<!-- END_MODULE Touch_SessionWithContribution -->

/使用テーマ/include/head/js.html をひらき、 作成したjsファイルを Touch_SessionWithContribution の中で下記のように読み込みます。

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

これで下準備は完了です。

カスタムフィールドの必須解除ができるチェックボックスを実装してみよう

目標


実践

1. カスタムフィールドメーカーでコード生成

/使用テーマ/admin/entry/field.html を開いておきます。

カスタムフィールドメーカーで入力欄を生成します。

カスタムフィールドメーカー
https://developer.a-blogcms.jp/tools/custom-field.html

生成内容
  • カスタムフィールド

  • チェックボックス
    タイトル : フィールド設定
    フィールド : test_f1
    項目名 : 必須解除
    値 : on

  • テキスト
    タイトル : フィールドタイトル
    フィールド : test_f2
    オプション > 入力チェック > バリデータ:必須 [ フィールドタイトルが入力されていません ]

※今回はJavaScriptによるバリデートを使用するにチェックは入れないでください。

生成した入力用ソースをコピーして、あらかじめ開いておいた /使用テーマ/admin/entry/field.html に貼り付けます。

管理画面 > エントリー > エントリー作成 からエントリー作成画面を表示してフィールドが追加されたことを確認します。
保存ボタンを押してバリデータによってエラー表示されることも確認しておいてください。

2. スタイル調整

テーブルに見出しをつけます。
先程追加したフィールドテーブルの上に下記ソースを貼り付けてください。

<h2 class="acms-admin-admin-title2 acms-admin-margin-top-medium">必須切り替えテスト</h2>

必須ラベルをつけます。
「フィールドタイトル」の後ろ(thタグの中)に下記ソースを貼り付けてください。

<span class="acms-admin-label acms-admin-label-danger acms-admin-margin-left-mini js-test_f2_label">必須</span>

フィールドタイトルのテキストinputの長さを調整します。
フィールドタイトルのテキストinputのクラス acms-admin-form-width-full を acms-admin-form-width-large に書き換えてください。

エラー文の余白調整を調整します。
acms-admin-text-error に acms-admin-margin-top-mini クラスを追加してください。

エラー文にアイコンをつけます。
acms-admin-text-error 要素の中身を下記で置き換えてください。

<span class="acms-admin-icon acms-admin-icon-attention"></span><span class="acms-admin-align-middle">フィールドタイトルを入力してください</span>

スタイルが整ったかエントリー編集画面を再度確認します。

3. JSで必須解除する

エラー文のpタグに js-test_f2-error-text クラス を追加します。

/使用テーマ/admin-asset/field-edit.js に下記ソースを貼り付けてください。

document.addEventListener('DOMContentLoaded', function() {
  // チェックボックスのinput要素を取得
  var checkbox = document.getElementById('input-checkbox-test_f1-on');
  // 必須バリデータ要素を取得
  var checkHidden = document.getElementById('test_f2-v-required');
  // 必須ラベル要素を取得
  var label = document.querySelector('.js-test_f2_label');
  // ページロード時にチェックボックスにチェックが入っていた場合はバリデータ無効化
  if (checkbox.checked) {
    checkHidden.disabled = true;
    label.style.display = 'none';
  }
  // チェックボックスをON/OFFした時の処理
  checkbox.addEventListener('change', function(event) {
    var errorText = document.querySelector('.js-test_f2-error-text');
    if (event.target.checked) {
      // チェックした時はバリデータを無効化し、エラー文が出ていたら非表示にする
      checkHidden.disabled = true;
      label.style.display = 'none';
      if (errorText) {
        errorText.style.display = 'none';
      }
    } else {
      // チェック外した時はバリデータを有効化し、エラー文非表示のスタイルを消す
      checkHidden.disabled = false;
      label.style.display = '';
      if (errorText) {
        errorText.style.display = '';
      }
    }
  });
});

動きの確認をしてください。

詳細設定の公開日時と掲載期限を抜き出してみよう

目標


実践

1. 公開日時と掲載期限の情報を入れるテーブルを用意

下記ソースを /使用テーマ/admin/entry/field.html に貼り付けます。

<h2 class="acms-admin-admin-title2 acms-admin-margin-top-medium">イベント情報</h2>
<table class="acms-admin-table-admin-edit"><tbody class="js-date-prepend"></tbody></table>

今貼り付けたソースには、すでにJSで制御する時に使用する js-date-prepend クラスがつけてあります。
h2タグ見出しもついていますが、不要な場合は削除してください。

2. 期限要素を移動させる

下記ソースを /使用テーマ/admin-asset/field-edit.js に追記してください。

document.addEventListener('DOMContentLoaded', function() {
    // ~ 割愛 ~

  ACMS.addListener("acmsDispatch", function() {
    // 公開期間をカスタムフィールド内へ移動
    var datePrepend = document.querySelector('.js-date-prepend');
    var entryStartDateDisplay = document.getElementById('entry-start-date-display');
    var entryEndDateDisplay = document.getElementById('entry-end-date-display');
    // 所得したカスタムフィールドのテーブル要素の末尾に期限要素を追加していく
    datePrepend.appendChild(entryStartDateDisplay);
    datePrepend.appendChild(entryEndDateDisplay);
  });
});

公開日時と掲載期限が移動するかエントリー編集画面を開いて確認します。

3. スタイル調整

期限入力欄が間延びしているので、詳細設定にあった時とおなじようなスタイルに調整します。
下記ソースを /使用テーマ/admin-asset/field-edit.css に貼り付けてください。

/* 公開日時と掲載期限をエントリーのカスタムフィールドに移動 */
.js-date-prepend .entryFormDateBlockWrap {
  margin-right: 10px;
}
@media screen and (min-width: 480px) {
  .js-date-prepend .entryFormDateBlockWrap{
    display: inline-block;
  }
  .js-date-prepend .entryFormDateBlock {
    display: inline-block;
    width: 150px;
    vertical-align: middle;
  }
}

スタイルが整ったかエントリー編集画面を再度確認します。

カスタムフィールドグループにデフォルト値を入れておくには

目標


実践

1. カスタムフィールドメーカーでコード生成

/使用テーマ/admin/entry/field.html を開いておきます。

カスタムフィールドメーカーで入力欄を生成します。

カスタムフィールドメーカー
https://developer.a-blogcms.jp/tools/custom-field.html

生成内容
  • カスタムフィールドグループ

  • グループのタイトル : イベント情報
    フィールド名 : group_test_f3
    横向きレイアウト

  • テキスト
    タイトル : 見出し
    フィールド : test_f3_item_title

  • テキストエリア
    タイトル : テキスト
    フィールド : test_f3_item_note

生成した入力用ソースをコピーして、あらかじめ開いておいた /使用テーマ/admin/entry/field.html に貼り付けます。

管理画面 > エントリー > エントリー作成 からエントリー作成画面を表示してフィールドが追加されたことを確認します。

2. デフォルト値用の入力欄を作成する

入力欄を設置します。
先ほど生成たコードの group_test_f3:loop 内をコピーして、:loop開始コメントの上に3回ペーストしてください。

タイトルをデフォルト値に書き換えます。
ペーストしたコード内 name="test_f3_item_title[]" 要素の value をそれぞれ「出演」「企画」「協賛」に置き換えてください。

テキストをデフォルト値に書き換えます。
ペーストしたコード内の textarea 要素の中身を全て「内容を書き換えてください。不要な場合は項目ごと削除してください。」に置き換えてください。

3. 新規エントリー作成時にのみデフォルト値が読み込まれるようにする

下記IF文でペーストしたコードを囲ってください。

<!-- BEGIN_IF [%{EID}{test_f3_item_title}{test_f3_item_note}[delnl]/em] -->
 ~ ここにデフォルト値を設定したフィールドが入ります。 ~ 
<!-- END_IF -->

管理画面 > エントリー > エントリー作成 からエントリー作成画面を表示して確認します。
デフォルト値がエントリー新規作成時にのみ読み込まれて、エントリー編集時/エントリー保存失敗時に不要なフィールドが増えないことを確認してください。

4. SetTemplateでテンプレートをスッキリさせる

デフォルト値が設定されている部分が冗長なのでSetTemplateを使いテンプレートの変数化をしていきます。 @include でも同様のことができので、どちらで対応してもOKです。

SetTemplate を用意します。 下記コードを /使用テーマ/admin/entry/field.html の上の方に貼り付けてください。

<!-- BEGIN_SetTemplate id="tpl_test_f3_item" -->
<!-- END_SetTemplate -->

デフォルト値設定しているtr要素の一つをコピーし、SetTemplateの中に貼り付けてください。
次に、SetTemplate 内の name="test_f3_item_title[]" 要素の value を {{tpl_item_title}} で置き換えます。

GET_Template を設置します。
<!-- BEGIN_IF [%{EID}/em/_and_/<!-- BEGIN_MODULE Admin_Messages -->{message}<!-- END_MODULE Admin_Messages -->/neq/failure] --> の中を下記で置き換えてください。

<!-- エントリー作成時のデフォルト設定 -->
<!-- GET_Template id="tpl_test_f3_item" tpl_item_title="出演" -->
<!-- GET_Template id="tpl_test_f3_item" tpl_item_title="企画" -->
<!-- GET_Template id="tpl_test_f3_item" tpl_item_title="協賛" -->

GET_Templateできているかエントリー新規作成して確認します。

5. スタイル調整

「イベント情報」見出しが2つある場合は削除してください。

theadは不要かと思いますので削除してください。

name="test_f3_item_title[]" が入っている tdth に変更してください。

必要であれば placeholder を入れてください。

テーブルがくっついて線が2重になっている場合は、/使用テーマ/admin-asset/field-edit.css に下記を追記してください。

.acms-admin-table-admin-edit + .acms-admin-table-admin-edit {
  border-top: 0;
}

スタイルが整ったかエントリー編集画面を再度確認します。

6. テキストエリアを Lite Editor にする

js-lite-editor-field クラスを name="test_f3_item_note[]" 要素につけてください。
※ 表示側の解説は本記事でしていませんが、表示する時には校正オプションの[raw]が必要になります。

カスタムフィールド用の Lite Editor JS をカスタマイズします。
/使用テーマ/admin-asset/field-edit.js に下記を追記してください。

document.addEventListener('DOMContentLoaded', function() {
  // ~ 割愛
  ACMS.Ready(function() {
    ACMS.Config.LiteEditorFieldConf.btnPosition = 'bottom';
    ACMS.Config.LiteEditorFieldConf.classNames = {
      LiteEditor: 'entryFormLiteEditor',
      LiteEditorBtnGroup: 'acms-admin-btn-group acms-admin-btn-group-inline',
      LiteEditorBtn: 'acms-admin-btn',
      LiteEditorBtnActive: 'acms-admin-btn acms-admin-btn-active',
      LiteEditorBtnClose: '',
      LiteEditorTooltipInput: 'acms-admin-form-width-full'
    };
    ACMS.Config.LiteEditorFieldConf.btnOptions = [
    { label: 'リンク', tag: 'a', className: '', sampleText: 'リンクテキスト' },
    { label: '強調', tag: 'em', className: '', sampleText: ' ' },
    { label: '重要', tag: 'strong', className: '', sampleText: ' ' }
    ];
  });
});

Lite Editor のスタイル調整もしておきます。
js-lite-editor-field の親要素に field-lite-editor-wrap クラスを付けてください。

次に、/使用テーマ/admin-asset/field-edit.css に下記を追記します。

.field-lite-editor-wrap .lite-editor-toolbox {
  margin-top: 6px;
  padding: 0;
  background-color: transparent;
  border: none;
  border-radius: 0;
}
.field-lite-editor-wrap .lite-editor-btn-group-wrap {
  padding-left: 0;
}

エントリーの編集ページが Lite Editor 化されているか確認します。

ユーザー情報をセレクトできるようにしてみよう

目標


実践

1. ユーザー追加

これからユーザー情報を表示させたいので、ユーザーがあまりいない場合はユーザー追加しておきましょう。 管理画面 > ユーザー の [ユーザー作成] から追加できます。 10件以上あると後から行うカスタマイズで変化がわかりやすいです。

2. カスタムフィールドメーカーでコード生成

/使用テーマ/admin/entry/field.html を開いておきます。

カスタムフィールドメーカーで入力欄を生成します。

カスタムフィールドメーカー
https://developer.a-blogcms.jp/tools/custom-field.html

生成内容
  • カスタムフィールドグループ

  • グループのタイトル : 担当者
    フィールド名 : group_test_f4
    横向きレイアウト

  • セレクトボックス
    タイトル : 担当者名
    フィールド : test_f4_item_user
    項目名 : 名前
    値 : ユーザーID

生成した入力用ソースをコピーして、あらかじめ開いておいた /使用テーマ/admin/entry/field.html に貼り付けます。

エントリー編集画面を表示してフィールドが追加されたことを確認します。

3. User_Search モジュールを追加する

User_Search モジュールのスニペットと変数表を開きます。

ビルトインモジュール
https://developer.a-blogcms.jp/document/reference/built_in.html#entry-6
※ 他のUser系モジュールでも問題ないです。

スニペットから下記の必要なものをコピぺしていきます。
値が空になっていないoption要素を囲うように貼り付けてください。

  • モジュールの開始と終了
  • user:loopの開始と終了

変数表から下記の必要なものをコピぺしていきます。
値が空になっていないoption要素内に貼り付けます。

  • ユーザーID ... valueに当たる部分に変数を中括弧で括って入れます。
  • ユーザー名 ... option要素の表示テキストとして変数を中括弧で括って入れます。

4. User_Search内のエントリーフィールド値をエスケープする

group_test_f4:loop 内の option要素に中括弧が2重になっている部分があるので、その一番外側をエスケープします。

<option value="{id}" \{test_f4_item_user:selected#{id}\}>{name}</option>

5. User_Search モジュールにIDを設定

管理画面 > モジュールID を開きモジュールIDを作成します。

  • モジュール : User_Search
    モジュールID : user_search_test
    名前 : カスタマイズ講座用(ユーザー情報をセレクトできるようにしてみよう)
    ※ モジュールIDや名前はなんでもOKです。わかりやすいものにしてください。

  • ブログID : ユーザーが登録されている(またはこれから登録する)ブログを選択

一度保存します。

表示設定を開き、表示件数や権限などを調整します。
※表示件数を10件以上にしておくとこの後に行うカスタマイズでの変化がわかりやすくなります。

作成したモジュールIDをコピーして、テンプレート側のモジュールに貼り付けます。

<!-- BEGIN_MODULE User_Search id="user_search_test" -->

エントリー編集画面を確認し、担当者のselectにユーザー情報が反映されていることを確認します。

6. ユーザーが増えても困らないようにする

現在ユーザー選択はただのselectボックスなのでユーザーが増えた場合に探すのが大変です。 こういう時は、select2.js の組み込みJSを入れておくと便利です。 ユーザーが10こ以上になるとテキスト検索がかけれるようになります。

担当者名のセレクトボックスに js-select2 クラスをつけておきましょう。

7. スタイル調整

value が空の option には「選択してください」を入れておくと親切かと思います。

担当者の見出しが上の要素とくっついている場合は、余白クラスをつけておきましょう。

<h2 class="acms-admin-admin-title2 acms-admin-margin-top-medium">担当者</h2>

おわり

お疲れ様でした。
今回は裏側の作り込み方や小技紹介をさせていただきました。
この記事をみて気になる項目がありましたら表側の実装にも挑戦してみてください。

9月19日(金)a-blog cms DAYを開催しました

先日の9月19日(金)にa-blog cms DAYを開催しました。

a-blog cms DAYとは、全国各地でa-blog cmsの勉強をする日です。ビデオチャットを通して全国各地のa-blog cmsユーザーと繋がることができ、リアルタイムでわからないところを質問することができます。5カ所の都市で開催されていますが、ビデオチャットで各地とつながっているため、お近くに会場がない場合は開催していただくこともできますし、ご自宅からでもご参加できます。

当日は山形、名古屋、神戸、広島、金沢の5カ所のサテライト会場で開催されました。今回、金沢があたらしくサテライト会場として追加されました。


a-blog cms DAY 名古屋会場風景

当日は名古屋会場から#ablogcms STREAMの放送、当日会場に来られた方のサポート、各サテライト会場からのご質問にもお答えしました。

#ablogcms STREAMの放送では、a-blog cmsの開発担当から先日リリースしたVer.2.1.1の解説に加え、a-blog cmsを使って主に受託案件をこなしているスタッフから便利機能・カスタマイズなどについてご紹介しました。スタッフからの新機能、カスタマイズ方法のご紹介につきましては後日YouTubeにまとめて公開する予定です。

名古屋会場には東京からの参加者にもお越し頂きました


#ablog cms STREAMの放送だけではなくサポートも行っています

東京にはまだサテライト会場がなく、名古屋会場には東京からのご参加もありました。まだまだサテライト会場の募集をしているので、お問い合わせやa-blog cmsのFacebookTwitterアカウントでお知らせいただければと思います。


次回のa-blog cms DAYは10月17日(土)の開催です。ご興味ある方はお近くの会場、またはオフィスやご自宅からぜひご参加ください。

CSVファイルからのインポート

管理ページからカンマ区切りデータ(csv形式)をエントリー・カスタムフィールド、ユニットに変換してインポートすることができます。

実行は慎重に

データ数が多いインポート処理はサーバーへの負荷が高くなります。そのため、作業時間・タイミングに注意しておこなってください。

カテゴリーコードとエントリーコードの重複

既存のコンテンツとインポートされるコンテンツとの間で同じコードをもつエントリーやカテゴリーが存在する場合はコードの重複が発生します。その場合はコンテンツが正しく表示されない可能性がありますので、インポート後に管理ページから個別に修正してください。

インポートの仕様

CSVファイルの内容によって、以下のような仕様があります。

  • CSVファイルに、カスタムフィールドの情報のみが含まれる場合は、エントリー情報は自動で作成されます。
  • CSVに entry_category_id を指定することで、優先してそのカテゴリーにインポートされます。
  • CSVに entry_id (エントリーID)フィールドを用意すると、同じエントリーIDのエントリーを上書きするようになります。 すべて、新規追加する場合は、 entry_id を指定しないでください。
  • データとして改行を含みたい場合は、値をダブルクウォートで囲みます。

プロフェッショナル版以上

プロフェッショナルライセンス以上限定になりますが、 CSVの項目に entry_id がなく「*(アスタリスク)」から始まる項目名(1つ)がある場合、その項目をキーにして一意(unique)になるエントリーをアップデートします。

CSVに指定できるフィールド


フィールド名 フォーマット 説明 指定なしの場合
entry_id 数値 エントリーIDを指定。 123 新規eid
entry_code 文字列 コード(ファイル名)を指定。 entry-123.html 通常エントリ作成時と同様
entry_sort 数値 表示順を指定(新規追加のみ)。 1 通常エントリ作成時と同様
entry_user_sort 数値 ユーザーを指定して一覧表示する時の表示順を指定(新規追加のみ)。 1 通常エントリ作成時と同様
entry_category_sort 数値 カテゴリーを指定して一覧表示する時の表示順を指定(新規追加のみ)。 1 通常エントリ作成時と同様
entry_status open | close | draft | trash ステータスを指定(open: 公開、close: 非公開、draft: 下書き、trash: ゴミ箱)のいずれかを指定。 open open
entry_title 文字列 タイトルを指定。 テストエントリー CSV_IMPORT-[eid]
entry_link 文字列 リンク先URLを指定。 https://www.a-blogcms.jp/
entry_datetime yyyy-MM-dd H:mm:ss 日付を指定。 2018-12-06 15:08:01 インポート時の日時
entry_start_datetime yyyy-MM-dd H:mm:ss 公開日時を指定。 2018-12-06 15:08:01 1000-01-01 00:00:00
entry_end_datetime yyyy-MM-dd H:mm:ss 掲載期限を指定。 2018-12-06 15:08:01 9999-12-31 23:59:59
entry_posted_datetime yyyy-MM-dd H:mm:ss 作成日を指定。 2018-12-06 15:08:01 インポート時の日時
entry_updated_datetime yyyy-MM-dd H:mm:ss 更新日を指定。 2018-12-06 15:08:01 インポート時の日時
entry_hash 文字列 ハッシュ値を指定(新規追加のみ)。 通常エントリ作成時と同様
entry_summary_range 数値 ユニットの「続きを読む」の位置を指定(例: 3 -> 上から3番目のユニットを一覧で出力)。 3
entry_indexing on | off インデキシング(一覧に出力するかどうか)を設定(on: 出力する、off: 出力しない)。 on on
entry_members_only on | off 会員限定エントリーを設定(on または、off) on off
entry_primary_image 数値 メイン画像のユニットIDを指定。 123
entry_category_id 数値 カテゴリーIDを指定。 1
entry_user_id 数値 エントリー所有者のユーザーIDを指定。 1 インポート実行者のUID
entry_tag 文字列/文字列/文字列 エントリーのタグを指定。 aaa/bbb/ccc
entry_sub_category カンマ区切り数値 サブカテゴリーの数値をカンマ区切りで指定(必ずダブルクウォートで囲むこと)。 "1,2,3"
geo_lat 数値 エントリーの経度を指定。 136.761737
geo_lng 数値 エントリーの緯度を指定。 35.424289
geo_zoom 数値 エントリーのズームを指定。 10
unit@タグセレクト[数値] 文字列 テキストユニットの追加。
タグセレクト: テキストタグセレクトで設定できるもの [p, h2, h3, ul, markdown, none....] 
[]の中の数値: ユニットの順番を指定
テストユニット
unit@block-editor[数値] HTML文字列 ブロックエディターユニットの追加
[]の中の数値: ユニットの順番を指定
&lt;p&gt;ブロックエディターユニット&lt;/p&gt;
カスタムフィールド変数 カスタムフィールド としてインポートされます。インポート先のフィールド仕様にあった値を設定ください。
また、保存されるカスタムフィールドの値は、自動的に検索対象となります。

※ エントリーの追加や更新が混ざっている CSV でインポートする際には、新規追加のエントリーID は 空ではなく -1 を設定 ください。

CSVファイルからのインポート手順

  1. インポートするカンマ区切りデータ(csv形式)を用意します。
  2. ログインをして管理ページのインポートにアクセスします。(図1)
  3. インポート先のブログを確認し、インポート先のカテゴリーを必要に応じて選択してください。(図2)
  4. インポート元になるCSVファイルを選択します。
  5. [インポートを実行する]ボタンをクリックすると、インポートを実行します。

(図1)インポート管理トップ

(図1)インポート管理トップ

(図2)CSVインポート画面

(図2)CSVインポート画面

CSVファイルの例

"entry_title","entry_code","zip","tel","address","unit@p[1]","unit@markdown[2]"
"アップルップル","csv-1","450-0002","052-485-8577","名古屋市中村区名駅3-18-5 モンマートビル5F","1つ目のユニット","## 見出し2"
"あっぷるっぷる","csv-2","000-0000","000-000-0000","指定したentry_titleやentry_codeの通りにエントリーが生成されます", "1つ目のユニット","### 見出し3"
"appleple","csv-3","111-1111","111-111-1111","フィールド名は任意の英数字で指定できます","1つ目のユニット","
## 見出し2

ダブルクウォートで囲むことで改行できます。

- リスト1
- リスト2
- リスト3
"
  • entry_title:エントリーのタイトル
  • entry_code:エントリーのコード(既存のエントリーとの重複を避けユニークな文字列を指定してください。拡張子はいりません。)
  • zip:カスタムフィールド、郵便番号として利用
  • tel:カスタムフィールド、電話番号として利用
  • address:カスタムフィールド、住所として利用
  • unit@[1] : 1番目のテキストユニット
  • unit@markdown[2] : 2番目のマークダウンテキストユニット

Webhookで外部サービスとCMSを連携してみよう


この講座では、Ver.2.12の新機能、Webhookをカスタマイズする方法をご紹介します。

また、この講座の内容はYouTubeにアップされています。記事と合わせてご覧ください。



UTSUWAテーマを元にカスタマイズを紹介するので、 ablogcms.io ベータ版 にてインストールしてください。デフォルトでUTSUWAが指定された状態でインストールされます。

この講座では以下の環境が必要になります。事前に取得しておくとスムーズに講座が受けられます。

  • Slackで自由に使えるワークスペース(テスト用にチャンネルにbotを追加します)
  • Googleのアカウント(Google Driveに送信した画像ファイルを保存します)
  • IFTTTのアカウント(1つ、Appletを追加します)

APIとWebhookの違い

APIはApplication Programming Interfaceの略で、「アプリケーションとプログラムを繋ぐ」という意味になります。例えば、基本的にはリクエストを出してあげないと動いてくれません。

Webhookはリクエストしなくてもレスポンスをしてくれます。ただし、あらかじめ設定した条件を満たした場合に限ります。例えば、どこかのサイトが更新されたら自動的に通知されるなど、ユーザーが何もしていなくてもレスポンスを返してくれます。

例えば、サイトの通知を受け取りたい場合、APIの場合は更新されたか何度も確認させる必要がありますが、Webhookの場合は最初に更新したら通知するという指示を与えておき、更新されるたびに通知できるようになります。

Webhookに対応したサービス

Webhookに対応したサービスです。

  • Slack
  • ChatWork
  • Facebook
  • Twitter
  • LINE
  • Trello
  • PayPay
  • PayPal
  • Dropbox
  • Evernote
  • Google Drive

などのたくさんのサービスが対応しています。

a-blog cms がサポートしているイベント

  • エントリー(作成・更新・削除・公開)
  • フォーム(送信)

例えば、a-blog cms でエントリーが更新されたら、ツイッターやFacebookページに自動的に投稿することが可能になります。

SlackやChatworkなどはすでに拡張アプリも用意してありますが、こちらはフォーム送信時のみになりますが、Webhookの場合はSlackやChatworkを使った際にもエントリーに対応しすることができます。

今回は、Slackに通知する方法と、IFTTTを使ってGoogle Driveにファイルを送信する方法をご紹介します。

Webhookを有効化する

ルートディレクトリにあるconfig.server.phpのHook_Enableを1にし、Webhookを有効化します。

define('HOOK_ENABLE', 1);

カスタマイズ1:エントリーを公開したらSlackに通知する

CMSでエントリーを公開したら、Slackに通知が行くように設定しましょう。

最終的には、以下のような通知が届くようになります。


Slackの設定

SlackのIncoming Webhookという機能を使います。

Incoming Webhookにアクセスしてください。 この時、右上のプルダウンで追加したいワークスペースか確認しましょう。追加したいワークスペースがない場合は新規作成してください。

  • Post to channel でチャンネルを選択する
  • 「スタッフブログ更新情報」チャンネルを新しく作成する
  • 「Add Incoming WebHooks integration」でWebhookの設定を追加する
  • Webhook URLをコピーしする

a-blog cms の設定

a-blog cms の管理画面で、webhookを追加し、必要な項目を入力していきます。

  • 名前は任意なものを指定する(例:Slack通知:エントリー公開用)
  • タイプは「エントリー」を選択
  • イベントは「エントリー公開」を選択
  • 先ほどコピーした Webhook URL をペーストする
  • リクエスト履歴にチェック(チェックすると、ログが残ります。基本的にはオンにする)
  • Slackとの連携では、ペイロードは必須なので、「ペイロードをカスタムする」にチェックする
  • SlackのIncoming Webhookのドキュメントを参考にテンプレートを指定する
    • \n で改行します
    • icon_emojiまたはicon_urlを指定します
  • 一度ペイロードのチェックを外しエントリーを公開し、一番新しいログのRequest Bodyを参考に変数を指定します(ペイロードのチェックを外した状態でログを表示すると、使用できる変数がわかります)
    • {{$contents->entry->title}}
    • {{$url}}

400になっているログのRequest Bodyでは、使用できる変数が表示される

最終的にはJSON形式でa-blog cmsに保存します。以下のようになります。

{
  "text": "ページを更新しました!\n「{{$contents->entry->title}}」\n{{$url}}",
  "username": "更新情報おまわりbot",
  "icon_emoji": ":dog:"
}

または

{
  "text": "ページを更新しました!\n「{{$contents->entry->title}}」\n{{$url}}",
  "username": "更新情報おまわりbot",
  "icon_url": "https://slack.com/img/icons/好きな画像のURL入れてください.png"
}

動作の確認

Webhookの設定をし、エントリーを公開した状態で作成すると、Slackに通知が来ます。

Slackの通知が来なかった場合は

来ていない場合は、a-blog cms の管理画面>Wehook>ログを表示し、ステータスコードが400になっていないか(400だとエラー、200だと成功)確認します。


400ステータスと200ステータス

もし400になっていて、ログ>Response Bodyの項目で missing_text_or_fallback_or_attachmentsと表示されていたら、ペイロードの書き方が悪いかもしれません。見直してみてください。


missing_text_or_fallback_or_attachmentsと表示されている様子

今回はエントリーの公開された記事を通知するようにしましたが、エントリーが削除した時も通知できるようになります。例えば、削除された記事の履歴を残すのにも使えそうですね。

それでは次はIFTTT経由でGoogle Driveに画像を保存する方法を紹介します。

カスタマイズ2:IFTTT経由で、CMSにフォーム送信した画像ファイルをGoogle Driveに保存する

先ほどはエントリーの更新でしたが、今度はフォームが送信された時に動作する仕組みを作ります。


Google Driveにペットのフォトコンテスト用のフォームを用意しました。

UTSUWAテーマで使用できるテンプレートです。ダウンロードしたら、themes/utsuwa/に設置してください。

管理画面>フォームの順にページを移動し、フォームIDを新規作成します。
フォームIDは以下のように設定します。設定ができたら、念のため、今の時点で画像が送信できるか確認しましょう。

基本設定


項目 入力内容
フォームID contestForm
フォーム名 フォトコンテスト

一般メール設定


項目 入力内容 テンプレート指定を無効
管理者宛 件名ファイル /contest/form/subject.txt
管理者宛 本文ファイル /contest/form/body.txt
管理者宛 本文HTMLファイル /contest/form/body.html
To
From info@example.com オン
Cc オン
Bcc オン
Reply-To オン

管理者宛メール設定


項目 入力内容 テンプレート指定を無効
管理者宛 件名ファイル /contest/form/adminsubject.txt
管理者宛 本文ファイル /contest/form/adminbody.txt
管理者宛 本文HTMLファイル /contest/form/adminbody.html
AdminTo info@example.com
AdminFrom info@example.com オン
AdminCc オン
AdminBcc オン
AdminReply-To オン
ファイル添付 「メールに添付する」をオン

今回はIFTTTを使います。(アカウント登録が必要になるので、アカウントを持っていない方はまずはアカウントの作成をお願いします)

「Create」ボタンをクリックして新しいAppletを作成します。

If Thisの設定

「If This」に「Webhooks」を指定します

  • 「Receive a web Request」を選択
  • 「Event Name」は任意でなんでも。ここでは「acms_trigger」とします

Then thatの設定

「Then that」に「Google Drive」を指定します

  • 「Upload file from URL」を選択
  • File URL は、フォームに追加した画像を指定したいです。ですが、a-blog cmsの変数をIFTTT側は知らないので、一旦「Add ingredient」ボタンをクリックし、Value1を選択して挿入します。
  • File nameは、日付と、ペットのなまえと飼い主の名前をつけたいので、OcurredAtに続き、「_」と「Add ingredient」からValue2とValue3を挿入します。
  • Drive folder pathは、ここで指定した階層にa-blog cmsのフォームから送信した画像が送られるようになります。今回はこのままでいいです。

If ThisとThen thatを設定したら

設定したら、Create actionをクリックします。

  • 「Continue」をクリック
  • 「Finish」をクリック

これで、連携の仕組みを保存できました。

Webhookのアイコンをクリックして、「Documentation」をクリックし、Webhook URLを取得します


Webhooksのアイコンをクリックする

Webhooksのページに移動したら、「Documentation」をクリックする


次に行うa-blog cmsの設定で必要なWebhook URLを取得する

Webhookの設定をする

a-blog cms に戻り、新しいWebhookを追加します

  • タイプは「フォーム」を選びます
  • イベントは「送信」にします
  • コピーしたWebhook URLをペーストします
    • eventには、「Event Name」に指定した文字列を入れます。「acms_trigger」と設定したので、記入します
  • 今回はAdd ingredientで変数を使っているので、ペイロードを使います。
    • ドキュメントのJSONの記述をコピペしし、テンプレートに貼ります。

ドキュメントのJSONの記述をa-blog cms のペイロードの記述で使います

  • Request Bodyを参考に変数を指定します
    • フォームで使用できる変数は、ペイロードをオフにしてフォームを送信し、ログを表示すると一覧で表示されます
    • URLは、外部からもアクセスできる必要があるので、グローバル変数を指定します。%{HTTP_ARCHIVES_DIR}{{$contents->field->pet_image@path}}
    • {{$contents->field->pet_name}}
    • {{$contents->field->name}

実際には、今回の場合は以下のようになります。

{
  "value1" : "%{HTTP_ARCHIVES_DIR}{{ $contents->field->pet_image_path }}",
  "value2" : "{{ $contents->field->pet_name }}",
  "value3" : "{{ $contents->field->name }}"
}

設定ができたら、フォトコンテストフォームを送信して、Google Driveに写真が入ってきているか確認します。 今回はDrive folder path を「IFTTT/MakerWebooks/{{EventName}}」に指定したので、もしなかった場合は新しくディレクトリが作られています。

以上で今回のカスタマイズは終了となります。


Google Driveに写真が入ってきている様子

もしエラーになっていたら、a-blog cms 管理画面の「ログ」か、IFTTTの作成したAppletのページで「View Activity」を見ると、Value1に正常な値が入っているか、urlに正常なURLが渡されているか確認することができます。


View activity をクリックした後の画面。どの変数にどんな値が入っているか確認できる。

最後に

これで講座は終了になります。
ぜひ a-blog cms と連携して、より便利なWebサイト運用を提供してください。