プレビュー

"絞り込み検索"機能の設定 - 検索フォームのプレビュー画面

設定した検索フォームはプレビュータブで見た目と動作を確認できます。実際に検索をすると、適用中のテーマの検索結果ページがフレーム内に表示されます。「前へ戻る」「次へ進む」ボタンで簡易的なナビゲーションができます。「テーマのstyle.cssを適用する」にチェックを付けるとテーマのstyle.cssがプレビュー欄に適用されます。「「デザイン」のCSSを適用する」にチェックを入れると 検索 > デザイン に記述したCSSを適用した状態で検索フォームの外観を確認できます。

コード

"絞り込み検索"機能の設定 - 検索フォームを設置するためのコード一覧

4つ目のタブ「コード」には、完成した検索フォームを設置するためのコード一覧が表示されます。検索フォームを設置するには以下の2つの方法があります。

  1. テーマのテンプレートにFEAS専用のPHP関数を設置
  2. 投稿や固定ページ、テキストウィジェットなどにショートコードで設置

また、コードには以下の3つの種類があります。

  1. 検索フォームを表示する関数/ショートコード
  2. 記事数を表示する関数/ショートコード
  3. 検索実行後に指定した検索条件(語句)を表示する関数/ショートコード

「コード」タブにはそれぞれ表示されていますので、必要に応じてコピーして設置したい場所にペーストしてください。設置したら表示が崩れていないか、検索が機能するか動作確認を行ってください。

それぞれのコードについて詳しくはこちらのページをご覧ください:
絞り込み検索フォームを”設置”する

具体的な設置例としては以下が考えられます。

  1. 設定 > 表示設定 > フロントページに指定した固定ページ本文欄に検索フォームと記事数の2つのショートコードを設置
  2. 検索結果を表示するテーマのテンプレートはsearch.phpなので、search.phpを開き、ページ上部に検索条件と記事数を表示するPHPの関数を設置
  3. 検索結果ページからさらに絞り込めるように、search.php下部に検索フォームのPHP関数を設置
    1. フロントページに設置した検索フォームと同じフォームIDの検索フォームをsearch.phpに設置すると、ドロップダウンやチェックボックスの状態を引き継ぐことができますので、エンドユーザーはそこからさらに絞り込むことができます。

多言語サイトに絞り込み検索を実装する

WordPressサイトを多言語化するためのプラグインがいくつか存在しますが、そのうち以下のプラグインに対応しています:

これらのプラグインを併用時、FEASで絞り込み検索フォームを固定ページに設置するには以下の流れでおこないます(例:日本語、英語の2か国語に対応):

  1. 翻訳プラグインの仕様に従い、コンテンツ(記事)、カテゴリ/タームなどを翻訳する
  2. 1のコンテンツ(記事)を、それぞれの言語に翻訳されたカテゴリ/タームに登録する
    • →日本語の記事は日本語のターム、英語の記事は英語のタームに登録
  3. 検索フォームを設置するページ(日本語)を、固定ページで作成
  4. 3で作成した検索ページの翻訳ページ(英語)を作成
  5. FEASで日本語向けの検索フォームを作成、3の日本語検索ページにショートコードを配置
  6. FEASで英語向けの検索フォームを作成(フォームの各項目は5と同じ)、4の英語検索ページにショートコードを配置

以上で、言語スイッチャーなどで言語を切り替えた際に、それぞれの言語に対応した検索ページが表示されます。検索フォームのターム一覧はそれぞれの言語に翻訳されたタームのみが一覧表示され、検索を実行するとその言語の記事のみがヒットします。

フリーワード検索も同様に、現在選択されている言語の記事のみがヒットします。たとえ翻訳元・翻訳先の両方の記事に同じ単語…例えば日本語で「プログラミング」という単語が日・英、両方の記事に含まれていたとしても、言語スイッチャーで指定されている言語のコンテンツのみが検索にヒットします。

Ajaxフィルタリングに「Materialize」を適用する

「Materialize」のFormsなどのCSSフレームワークを検索フォームに適用すると、簡単に検索フォームに美しい動きのあるデザインを実装できますが、「Materialize」はFEASが出力したHTML(DOM構造)を動的に変えてしまうため、従来は「Ajaxフィルタリング」が正常に機能しませんでした。FEAS v1.9.6にて、AjaxフィルタリングにJavaScriptのフィルターフックを実装しましたので、これを使ってMaterializeの仕様に沿ったコードを別途記述することで、AjaxフィルタリングとMaterializeを併用することができます。

まず、Materializeに必要なファイルをヘッダーまたはフッターに読み込みます。

参考) https://materializecss.com/getting-started.html

<!-- Compiled and minified CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">

<!-- Compiled and minified JavaScript -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>

 そして、フッターのwp_footer()関数より後に、下記のコードを記述します:

<script>
	(function($){
		
		$('select').formSelect();
		
		// Ajaxフィルタリングの結果を取得後に再反映
		$(document).ajaxComplete(function(){
			M.AutoInit();
		});
		// デフォルト値(未指定)選択時はAjax通信が行われないためonchangeにて再反映
		$('select').on('change',function(){
			M.AutoInit();
		});
		
	})(jQuery);
</script>

以上で、FEASを含むサイト内のすべてのドロップダウン(select)要素にMateliarizeのデザインが適用されます。絞り込み検索フォームにのみ適用したい場合は、コード全体を例えば <?php if ( is_page( 123 ) ) : ?> と <?php endif; ?> で囲むことで、検索フォームを設置した固定ページ(例:記事ID=123)のみに限定して適用することができます。

続いて、Matelializeを適用した状態でもAjaxフィルタリングが動作するように処理を追加します。

まず、以下のコードをテーマのfunctions.phpに追記します:

function feas_wrap_dropdown_materialize( $html, $args ) {

	$formNo = $args['manag_no'];
	$itemNo = $args['number'];
	$depth  = $args['depth'];

	if( 0 === $formNo && 0 === $itemNo ) { // フォームIDとAjaxフィルタリング項目の出現位置(検索項目1つ目 = 0)

		$addNo = "_{$formNo}_{$itemNo}";
		if ( 0 !== $depth ) {
			$addNo .= "_{$depth}";
		}
		$preHtml  = "<div id='search_element{$addNo}' class='input-field'>";
		$postHtml = "</div>";
		$html     = $preHtml . $html . $postHtml;
	}
	return $html;
}
add_filter( 'feas_term_dropdown_group_html', 'feas_wrap_dropdown_materialize', 10, 2 );

これは、Materializeで指定されている .input-field というクラス名をともなったdivタグで、Ajaxフィルタリングの各階層のselectタグを囲みます。例として、フォームID=0、Ajaxフィルタリングが検索フォームの最初に位置する場合を想定しています。異なる場合は、7行目の 0 === $formNo && 0 === $itemNo の数値をそれぞれ、該当するフォームID、Ajaxフィルタリングの表示位置に変更してください。

次に、Ajaxフィルタリングを実行した際(ドロップダウンの値が変更された際)に、JavaScriptによってリセットされる子タームのselectタグまでのパスを変更します。以下のコードを、前述のコードの続きに記述してください:

/**
 * AjaxフィルタリングのDOM構造変更
 *
 * MaterializeによってDOMが変更されるため、子要素を指定するjQueryの記述を調整
 * (上位階層のドロップダウンを切り替えた際に下位階層のドロップダウンを初期化する記述)
 * hook.min.jsを使用するため、フックの優先度「99」として読み込む順番を下げる
 *
 * @package FE Advanced Search
 * @since v1.9.6
 */
function feas_adjust_dom_materialize() {
	?>
	<script>
	function feas_adjust_dom_materialize( content, parent_obj, form_id, item_no, depth, default_depth ) {

		// 親要素を変更時に初期化(削除)する子要素を指定する記述をMaterializeのDOMに合わせて書き換え
		if( 0 === form_id && 0 === item_no ){
			if ( 1 < default_depth ) {
				content = jQuery(parent_obj).closest('.input-field').nextAll('.input-field').find('select');
			} else {
				content = jQuery(parent_obj).closest('.input-field').nextAll().remove();
			}
		}
		return content;
	}
	wp.hooks.addFilter( 'feas.ajaxInitChild', 'feas', feas_adjust_dom_materialize );

	function feas_adjust_dom_materialize_fulldepth( content, parent_id, form_id, item_no, depth, default_depth ) {

		// 階層が未指定の場合に逐次追加されるselect要素をMaterializeに必要なDOM構造に書き換え
		if( 0 === form_id && 0 === item_no ){
			let preHtml = "<div id='search_element_" + form_id + "_" + item_no + "_" + depth + "' class='input-field'>";
			let postHtml = "</div>";
			content = preHtml + content + postHtml;
		}
		return content;
	}
	wp.hooks.addFilter( 'feas.ajaxDropdownGroupHtml', 'feas', feas_adjust_dom_materialize_fulldepth );
	</script>
	<?php
}
add_action( 'wp_footer', 'feas_adjust_dom_materialize', 99 );

17行目と31行目の 0 === form_id && 0 === item_no の数値は、前述のとおり実際のフォームID、Ajaxフィルタリングの表示位置に合わせてください。

以上で、FEASの検索フォームにMaterializeの美しいデザインを適用し、なおかつAjaxフィルタリングも正常に動作させることができます。