送信ボタンを押さずに検索結果を表示する(post include)

a-blog cmsでは、フォームの送信ボタンを押さずに検索結果をAjaxを使用して表示できる機能が標準で実装されています。

通常は検索フォームにデータを入力して送信ボタンを押すと、新しいページを読み込んで検索結果を表示しますが、この機能を利用するとフォームの送信ボタンを押さずに同じページ内で検索結果を表示することができます。

ここでは例として、ある特定のキーワードで検索した場合の検索結果を表示する手順を説明します。

1. 検索結果の表示を用意する

(1)フォームを送信した後に表示する内容をテンプレートとして用意します。ここではsearchResultSample.htmlというテンプレートを用意するとします。このテンプレートには検索結果の表示部分のみ記述しています。

<!-- BEGIN_MODULE Entry_List -->
<ul><!-- BEGIN entry:loop -->
<li><a href="{url}">{title}</a></li><!-- END entry:loop -->
</ul>
<!-- END_MODULE Entry_List -->

(2)手順1(1)で作成したモジュールをモジュールIDにし、引数設定の[keyword]にチェックを入れます。これで、フォームから送られたキーワードに合致するエントリーが表示されるようになります。

<!-- BEGIN_MODULE Entry_List id="searchResultSample" -->
<ul><!-- BEGIN entry:loop -->
<li><a href="{url}">{title}</a></li><!-- END entry:loop -->
</ul>
<!-- END_MODULE Entry_List -->

モジュールIDの引数設定

モジュールIDの引数設定


2. 非表示のフォームを用意する


(1)検索フォームを用意します。

<form action="" method="post">
  <input type="hidden" name="bid" value="%{BID}" />
  <input type="submit" name="ACMS_POST_2GET" />
</form>

(2)form要素にclass属性を追加します。「class="js-post_include-ready"」はこのとおりに記述します。

<form action="" method="post" class="js-post_include-ready">
  <input type="hidden" name="bid" value="%{BID}" />
  <input type="submit" name="ACMS_POST_2GET" />
</form>

(3)検索結果を表示するテンプレートを参照します。

例)include/searchResultSample.html というテンプレートを参照する場合の例です。

<form action="" method="post" class="js-post_include-ready">
  <input type="hidden" name="tpl" value="include/searchResultSample.html" />
  <input type="hidden" name="bid" value="%{BID}" />
  <input type="submit" name="ACMS_POST_2GET" />
</form>

(4)検索キーワードを指定します。

例)「サマリー」というキーワードで検索する場合

<form action="" method="post" class="js-post_include-ready">
  <input type="hidden" name="keyword" value="サマリー" size="15" />
  <input type="hidden" name="tpl" value="include/searchResultSample.html" />
  <input type="hidden" name="bid" value="%{BID}" />
  <input type="submit" name="ACMS_POST_2GET" />
</form>

これで、送信ボタンを押さずに検索結果を表示するようになります。

動作サンプル

下のリストは、フォームで特定のキーワード「サマリー」で検索して合致したエントリーが検索結果として表示されています。フォーム自体は表示されず、検索結果が表示されます。

  • 送信ボタンを押さずに検索結果を表示する(post include)

Yahoo! 地図とYahoo! Map Clusterをためしてみよう


Yahoo! 地図とは

まず、Yahoo!地図とはヤフー株式会社が提供する地図サービスで下のようにWeb上に地図を埋め込めるAPIも提供しています。

a-blog cmsは以前からYahoo!地図に対応しており、APIの利用登録をすることにより、エントリー作成画面でYahoo! 地図ユニットを使えたり、組み込みJSでYahoo!地図を表示したりすることが可能になっています。

Yahoo!地図を利用するメリット

Webサイトへの地図の埋め込みに Google Maps を利用する機会も多いと思います。昨年、Google Maps がクレジットカード情報の登録が必須になり、無料での利用が 28,000pv/月までと仕様が変更になりました。

それに対してYahoo!地図は現在のところ、クレジットカードの登録は必要がなくAPIの利用上限もGoogle Mapsと比べると50倍以上となっています。日本国内の地図であれば、Yahoo!地図 を利用することも検討に加えていいサービスではないでしょうか。

今回のハンズオンはa-blog cmsでGoogle Mapsの代替としてYahoo! Mapを使いこなすためのものとなっています。

Yahoo! 地図 の設定方法

以下の手順で a-blog cmsでYahoo! 地図を利用可能になります。

  1. Yahoo! デベロッパーネットワークにてAPIの利用申請
  2. a-blog cmsの管理画面よりアプリケーションIDを登録
  3. Yahoo! 地図ユニットの追加

Yahoo! デベロッパーネットワークにてAPIの利用申請

Yahoo!デベロッパーネットワーク のサイトにて登録を行いAPIキーを取得する必要があります。
まず、Yahoo!にログインした後にアプリケーションの登録を行います。


a-blog cmsの管理画面よりアプリケーションIDを登録

登録が完了しますと、アプリケーションIDが発行されます。このアプリケーションIDをa-blog cmsの管理画面にて登録をします。


管理メニューの コンフィグ > プロパティ設定にて、APIキーを登録します。


Yahoo! 地図ユニットの追加

管理メニューの コンフィグ > 編集設定にて、ユニット追加ボタンにYahoo!地図の追加を行います。モードは「Yahoo!地図」、ラベルは任意の名前を設定します。


設定が問題なく完了していますと、ユニット追加ボタンにYahoo!地図のボタンが表示され、ボタンを押すとYahoo!地図の設定ユニットが表示されます。


Yahoo! Map Clusterを使ってみよう

さてここからがハンズオンです!今回のハンズオンでは、site2019の「物件情報(https://ドメイン/realestate/)」を利用します。ここのエントリーに登録されているカスタムフィールドを「Yahoo!地図」に切り替えて、一覧ページでは「Yahoo! Map Cluster」を利用して物件情報を表示してみましょう。

地図のカスタムフィールドをOpenStreetMapからYahoo!地図に変更

管理画面側の設定

エントリーのカスタムフィールド

/themes/site2019/admin/entry/field/realestate.htmlを編集します。

realestate.htmlの最後に記述されているOpenStreetMapのカスタムフィールドの記述をコメントアウトまたは削除します。代わりにYahoo! 地図がカスタムフィールドとして表示されるように以下のHTMLを貼り付けてください。

<table class="entryFormTable acms-table-entry">
  <tr class="js-yolp-editable js-map-editable">
    <th>地図</th>
    <td>
      <div class="acms-form-group acms-admin-margin-bottom-small">
        <!-- BEGIN_IF [%{PROTOCOL}/eq/https] -->
        <img class="column-map js-map_editable-container" src="//map.yahooapis.jp/map/V1/static?appid=%{YAHOO_API_KEY}&lat={map_lat}&lon={map_lng}&z={map_zoom}&width=400&height=400&pointer=on" width="400" height="400">
        <!-- ELSE -->
        <img class="column-map js-map_editable-container" src="//map.olp.yahooapis.jp/OpenLocalPlatform/V1/static?appid=%{YAHOO_API_KEY}&lat={map_lat}&lon={map_lng}&z={map_zoom}&width=400&height=400&pointer=on" width="400" height="400">
        <!-- END_IF -->
      </div>
      <div class="acms-form-group">
        緯度 <input type="text" name="map_lat" value="{map_lat}" size="9" class="js-map_editable-lat" />
        経度 <input type="text" name="map_lng" value="{map_lng}" size="10" class="js-map_editable-lng" />
        ズーム <input type="text" name="map_zoom" value="{map_zoom}" size="10" class="js-map_editable-zoom" />
      </div>
      <input type="hidden" name="field[]" value="map_lat" />
      <input type="hidden" name="field[]" value="map_lng" />
      <input type="hidden" name="field[]" value="map_zoom" />
    </td>
  </tr>
</table>

以下のようにエントリー編集画面にYahoo!地図登録用のUIが表示されます。


カテゴリーのカスタムフィールド

/themes/site2019/admin/category/field_realestate.htmlを編集します。 以下のHTMLに内容を置き換えてください。

<h3 class="acms-admin-admin-title2">一覧ページで表示させる地図の中心の緯度経度設定</h3>
<table class="adminTable acms-admin-table-admin-edit">
  <tr>
    <th>地図</th>
    <td class="js-map-editable js-yolp-editable">
      <div class="acms-admin-form-group acms-admin-osm-container">
      <!-- BEGIN_IF [%{PROTOCOL}/eq/https] -->
      <img class="column-map js-map_editable-container" src="//map.yahooapis.jp/map/V1/static?appid=%{YAHOO_API_KEY}&lat={index_map_lat}&lon={index_map_lng}&z={index_map_zoom}&width=400&height=400&pointer=on" width="400" height="400">
      <!-- ELSE -->
      <img class="column-map js-map_editable-container" src="//map.olp.yahooapis.jp/OpenLocalPlatform/V1/static?appid=%{YAHOO_API_KEY}&lat={index_map_lat}&lon={index_map_lng}&z={index_map_zoom}&width=400&height=400&pointer=on" width="400" height="400">
      <!-- END_IF -->
      </div>
      <div class="acms-form-group">
        緯度 <input type="text" name="index_map_lat" value="{index_map_lat}" size="9" class="js-map_editable-lat" />
        経度 <input type="text" name="index_map_lng" value="{index_map_lng}" size="10" class="js-map_editable-lng" />
        ズーム <input type="text" name="index_map_zoom" value="{index_map_zoom}" size="10" class="js-map_editable-zoom" />
      </div>
      <input type="hidden" name="field[]" value="index_map_lat"/>
      <input type="hidden" name="field[]" value="index_map_lng"/>
      <input type="hidden" name="field[]" value="index_map_zoom"/>
    </td>
  </tr>
</table>

表示側の設定

物件情報の一覧ページ

次に表示側の設定です。/themes/site2019/include/parts/map.htmlを編集します。ここにはオープンストリートマップで地図を表示するようにテンプレートが記述されていますが、その記述をコメントアウトまたは削除していただき以下のソースコードを記述してください。

<!-- BEGIN_MODULE Category_Field -->
<div class="realestate-map">
  <div id="map" style="width:100%;height: 400px;"></div>
  <style>
  .yolp-infowindow td {
    padding: 0;
    border: none;
  }
  </style>
  <script src="https://unpkg.com/yahoo-map-cluster@latest/bundle/ymap-cluster.js"></script>
  <script>
    ACMS.Ready(function() {
      ACMS.Library.yahooLoadProxy({
        'callback': function () {
          var ymap = new Y.Map("map");
          ymap.drawMap(new Y.LatLng({index_map_lat}, {index_map_lng}), {index_map_zoom}, Y.LayerSetId.NORMAL);
          var markers = [];
          <!-- BEGIN_MODULE Entry_Summary id="map_list" -->
          <!-- BEGIN entry:loop -->
          <!-- BEGIN_IF [{map_lat}/nem/_and_/{map_lng}/nem] -->
          var marker = new Y.Marker(new Y.LatLng({map_lat},{map_lng}));
          markers.push(marker);
          marker.bindInfoWindow('<a href="{url}"><!-- BEGIN_IF [{main_photo@path}/nem/] --><img src="%{ARCHIVES_DIR}{main_photo@path}" width="200" alt="" /><br/><!-- END_IF -->{title}</a>');
          <!-- END_IF -->
          <!-- END entry:loop -->
          <!-- END_MODULE Entry_Summary -->
          new YmapCluster(ymap, markers);
          var control = new Y.ZoomControl();
          ymap.addControl(control);
        }
      });
    });
  </script>
</div>
<!-- BEGIN_MODULE Touch_SessionWithCompilation --> <p class="edit-link">[<a href="%{BLOG_URL}bid/%{BID}/cid/%{CID}/admin/category_edit/">編集</a>]</p><!-- END_MODULE Touch_SessionWithCompilation -->
<!-- END_MODULE Category_Field -->
物件情報の詳細ページ

また、/themes/site2019/include/field/entry_realestate.html を編集して、物件情報の詳細ページもYahoo!地図が表示されるように以下のHTMLでOpenStreetMapに対応する箇所を置き換えます!

<!-- BEGIN lat:veil -->
<div class="realestate-map realestate-map-entry" style="margin-bottom:20px">
<!-- BEGIN_IF [%{PROTOCOL}/eq/https] -->
<img class="column-map" src="//map.yahooapis.jp/map/V1/static?appid=%{YAHOO_API_KEY}&lat={map_lat}&lon={map_lng}&z={map_zoom}&pointer=on" style="width:100%; height: auto;">
<!-- ELSE -->
<img class="column-map" src="//map.olp.yahooapis.jp/OpenLocalPlatform/V1/static?appid=%{YAHOO_API_KEY}&lat={map_lat}&lon={map_lng}&z={map_zoom}&pointer=on" style="width:100%; height: auto;">
<!-- END_IF -->
</div>
<!-- END lat:veil -->

最終的に物件情報の一覧ページ(https://ドメイン/realestate/)にアクセスした際に以下のように地図が表示されていればカスタマイズ成功です。


ページを移動せずにフォームの検索結果を表示する(post include)

a-blog cmsでは、フォーム送信後の結果を、ページを移動せずにAjaxを使用して表示できる機能が標準で実装されています。この方法は組み込みJSのpost include機能を利用します。

通常は検索フォームにデータを入力して送信ボタンを押すと、新しいページを読み込んで検索結果を表示しますが、この機能を利用するとページを移動せずに同じページ内で検索結果を表示することができます。

ここでは例として、サイト内検索フォームから検索すると、ある特定のコンテンツエリアを書き換えて検索結果を表示する手順を説明します。

Cloud Translation API を使った多言語対応


Google の「Cloud Translation API」を使った a-blog cms用拡張アプリが公開されています。この拡張アプリを使用すると、 エントリー(記事)の多言語化を簡単に行うことができますのでぜひ試してみましょう。

現状この拡張アプリはプロ版以上での利用に限定されています。(スタンダード版でも有償になりますが、ご利用いただけるように準備中です)


仕組み概要

この拡張アプリでの多言語エントリーの管理の仕方ですが、言語ごとにブログを切り、言語毎の記事を別エントリーとして管理するようにします。

1つのエントリーで一元管理できていないので、あまりよくないように思いますが、別管理とすることで以下のようなメリットがあります。

  • 既存の仕組みで管理できる
  • 言語ごとに承認機能を利用できる
  • 言語ごとにコンテンツの内容を大きく変更できる
  • 一部の言語にしかないコンテンツを用意できる

ただ各言語が別管理になってしまうので、管理しづらいところがあります。そこでこの拡張アプリではエントリー詳細で、各言語にリンクできるようになっており、ステータスの状態を確認できるようになっています。


完成イメージ

完成イメージ


下準備

さっそく実装していきましょう。

ここでは、beginner2019テーマの初期インストール状態を例に解説していきます。環境が異なる場合はご自身の環境に合わせて読み替えてください。

フック機能の有効化

config.server.php の HOOK_ENABLE を「1」に設定します。

define('HOOK_ENABLE', 1);

APIキーの取得

まずは Google Translate API を使用するためにAPIキーの発行が必要になります。

ablogcms.io をお使いの場合

以下のAPIキーを使用します。

AIzaSyA9uMj7N7oWXDJGcRcPA00pL8O_f7pp7zY

ご自身で取得する場合

ablogcms.io 以外で試している場合、以下の方法でAPIキーを取得します。

Google API Console にアクセスしてログインしてください。ログイン後、任意の名前でプロジェクトを作成します。 下画像のように 1, 2 の手順でプロジェクトを新規作成できます。


Google API Console

Google API Console


左上のセレクトメニューをクリックし、先ほど作成したプロジェクトを選択します。


プロジェクトの選択

プロジェクトの選択


次は、サブカラムより「ライブラリ」という項目をクリックし、API ライブラリのページに移動します。そのページにて、Google Cloud Translation APIという項目を検索して有効化してください。


ライブラリに移動

ライブラリに移動


Translate API の有効化

Translate API の有効化


最後に「認証情報」をクリックして認証情報の設定画面に移動します。そこで新たに API key を作成します。

必ずキーの制限 をかけるようにしてください。HTTPリファラー での制限はできませんので、IPアドレスによる制限になります。


認証情報に移動

認証情報に移動


APIキーの作成

APIキーの作成


この時発行される API key を覚えておきましょう。

英語用のブログを作成する

サイトを多言語化するにあたり、各言語をブログを切って設計します。 今回の場合は、ルートブログ(日本語)と子ブログ(英語)だけで大丈夫です。 英語ブログのコードを「en」としておきましょう。

日本語サイト
   ┗ 英語サイト

英語用ブログの作成

英語用ブログの作成


もし他ブログや言語が増えた場合は以下のような構成になります。 各言語ともブログ構造を保って作ります。

例:
日本語サイト
   ┗ 日本語ブログ
   ┗ 英語サイト
     ┗英語ブログ
   ┗ 中国語サイト
     ┗中国語ブログ

拡張アプリのインストール

まずは、Google Translate for a-blog cms から zipファイルをダウンロードし、解凍したディレクトリ(GoogleTranslate)を extension/plugins/ に設置します。


拡張アプリのファイル設置

拡張アプリのファイル設置


次に、管理者で a-blog cms にログインし、 拡張アプリに移動し、「Google Translate」をインストールします。多言語管理するブログ全てで、「Google Translate」拡張アプリを有効にします。


拡張アプリのインストール

拡張アプリのインストール


子ブログでも有効化

子ブログでも有効化


これで拡張アプリのインストールは完了です。

拡張アプリの設定

拡張アプリをインストールすると、拡張メニューに「Google Translate」が増えます。ベースとなる言語ブログのみで設定を行なっていきます。つまり日本語サイトのルートブログで設定を行います。



設定項目 説明
ベース言語 翻訳元となる言語を設定します
Google Translate API Key 事前準備で用意した APIキー を設定します
カテゴリー作成 翻訳先の記事を作成するときに、カテゴリーも自動で複製するか設定します
ベース言語(このブログ)と関連づける他言語ブログを設定 ベース言語のブログと翻訳先のブログの関連を設定します
訳対象のフィールドを設定します 翻訳対象のカスタムフィールド名を指定します
eidを指定するカスタムフィールドを設定します eidを設定するようなフィールドを指定します
bidを指定するカスタムフィールドを設定します bidを設定するようなフィールドを指定します
cidを指定するカスタムフィールドを設定します cidを設定するようなフィールドを指定します

ここでは以下の設定だけ行えば大丈夫です。

  • ベース言語の設定: 日本語を指定
  • カテゴリー作成: 作成するにチェック
  • 下準備で取得したAPIキーの設定
  • ベース言語(このブログ)と関連づける他言語ブログを設定

アプリの設定

アプリの設定


試してみる

ここまで設定できると、実際に翻訳できるようになります。エントリー編集画面に移動すると、下画像のようなメニューがあります。ここで「翻訳して作成」ボタンを押すと、このエントリーを設定した、ブログに翻訳して記事を非公開で複製します。

実際に試してみましょう。


多言語メニュー

多言語メニュー


表側でもこのメニューを表示するには、以下のコードをテンプレートに追記してください。

<!-- BEGIN_MODULE Touch_Entry -->
<!-- BEGIN_MODULE Touch_SessionWithAdministration -->
<!-- BEGIN_MODULE GoogleTranslate_EmptyModule -->
<!-- BEGIN_MODULE Admin_InjectTemplate id="admin-entry-editor-top" --><!-- END_MODULE Admin_InjectTemplate -->
<!-- END_MODULE GoogleTranslate_EmptyModule -->
<!-- END_MODULE Touch_SessionWithAdministration -->
<!-- END_MODULE Touch_Entry -->

Google帰属表示

試すだけならここで終わってもいいのですが、実際に運用することを考えて、Translation APIを使った時のGoogle帰属表示に対応しましょう。

参考: https://cloud.google.com/translate/attribution

概要

以下のような対応が必要になってきます。

ロゴ表示について

Cloud Translation API を使用する際には、Googleへの帰属表示が必須になります。ロゴ画像をつかってリンクを表示するようにします。


Google ロゴ

Google ロゴ


Translation API マークアップ

変更されていない Cloud Translation API の結果をウェブ上で公開し、検索できるようにする場合、 翻訳されるテキストを機械翻訳されたコンテンツとして指定する必要があります。

<テキストの翻訳先言語の言語コード>-x-mtfrom-<原文の言語の言語コード>

次のように、HTML ドキュメントの headタグ内 に link要素を追加し、 rel="" 属性を "alternate machine-translated-from" に、hreflang="" 属性を翻訳元の言語コードに、href="" を翻訳元のページに設定します。

<html lang="en-x-mtfrom-ja">
<head>
    <link rel="alternate machine-translated-from" hreflang="ja" href="http://ja.example.com/hello.html">
</head>
<body>
...

実装方法

上記のロゴと Translation API マークアップ を行うのに便利なグローバル変数とモジュールが用意されていますので用いましょう。



変数 説明
%{TRANSLATION_LANG_BASE_CODE} 翻訳元の言語コード ja
%{TRANSLATION_LANG_CODE} 現在いるページの言語コード en, en-x-mtfrom-ja
%{TRANSLATED_BY_GOOGLE} 機械翻訳されたページのみ「yes」を出力 yes
%{TRANSLATION_ORIGIN_URL} 翻訳元記事のURL http://ja.example.com/hello.html

%{TRANSLATION_LANG_CODE} 変数は、人力翻訳、機械翻訳を判断して、Translation API マークアップ にあった コードを出力します。

このグローバル変数と専用モジュールを使って、Translation API マークアップ をします。

<html lang="%{TRANSLATION_LANG_CODE}">
<head>
    <!-- BEGIN_MODULE GoogleTranslate_EntryList -->
    <!-- BEGIN_IF [%{TRANSLATED_BY_GOOGLE}/eq/yes] -->
    <link rel="alternate machine-translated-from" href="%{TRANSLATION_ORIGIN_URL}" hreflang="%{TRANSLATION_LANG_BASE_CODE}">
    <!-- END_IF -->
    <!-- BEGIN lang:loop -->
    <!-- BEGIN_IF [{base_bid}/neq/{relation_bid}/_and_/%{BID}/neq/{relation_bid}] -->
    <link rel="alternate" href="{url}" hreflang="{lang_code}">
    <!-- END_IF -->
    <!-- END lang:loop -->
    <!-- END_MODULE GoogleTranslate_EntryList -->
</head>
<body>
...

ロゴも、%{TRANSLATED_BY_GOOGLE} という機械翻訳されたページか判定するグローバル変数があるので、IFブロックなどで、ロゴ画像を表示、非表示を切り替えてあげればOKです。

以上で完了です。お疲れ様でした。

CSVインポートを使ったユーザー作成について

CSVファイルを使ったインポートには、通常WordPressからのエントリーのインポート、Movable Typeからのエントリーのインポート、CSVファイルのエントリーのインポート機能が利用できます。
その他に、ユーザーをCSVファイルからインポートする事も可能です。利用するには、エンタープライズライセンスか、無制限ユーザーのオプションが必要になります。



  • CSV形式のファイル(カンマ区切りデータ)をユーザーと、ユーザーのカスタムフィールドに変換してインポートします。
  • user_code, user_mail, user_passは必須項目です。
  • CSVに user_id を指定することで既存のユーザーを上書きすることができます。