サイトを作成する際に検索機能があると、
ユーザーも必要な情報が早く見つけられていいですよね。
wordpressにはデフォルトでサイト内検索の機能がありますが、
そのままだと機能が不十分な部分があります。
そこで今回はデフォルトの検索機能をカスタマイズして、
カスタム投稿なども検索対象に含める方法を記載します。
目次
検索機能の構造
検索機能は
search.phpというテンプレートを用意して作成します。
このファイルから検索機能が作られています。
search.php には
検索した結果を表示する情報
が書かれています。
しかしこのファイルのみだと不十分な部分が
出来てきますので、
下記で追加ファイルを紹介します。
使用ファイル一覧
下記が使用ファイルになります。
<PHP ファイル>
search.php
検索結果ページ
<?php get_header(); ?>
<h2>検索結果一覧</h2>
<!– searchform.php 取得 –>
<?php get_search_form(); ?>
<!– searchform.php 取得 –>
<div id=”count_rel”>
<p>
<?php if (have_posts()): ?>
<?php
if ( isset( $_GET[ ‘s’ ] ) && empty( $_GET[ ‘s’ ] ) ) {
echo ‘検索キーワード未入力’; // 検索キーワードが未入力の場合のテキストを指定
} else {
echo ‘“’ . $_GET[ ‘s’ ] . ‘”の検索結果:’; // 検索キーワードと該当件数を表示
}
if ( have_posts() ):
my_result_count(); // ここら辺で表示します
while ( have_posts() ):
the_post();
/* do stuff */
endwhile;
else :
/* Nothing Found */
endif;
?>
</p>
</div>
<?php endif; ?>
<!– content-archive.php 取得 –>
<?php
if ( have_posts() && get_search_query() ):
while ( have_posts() ):
the_post();
get_template_part( ‘content-archive’ );
endwhile;
else :
?>
<!– content-archive.php 取得 –>
<p class=”no_result”>該当する記事が存在していません。</p>
<?php endif; ?>
<?php get_footer(); ?>
|
searchform.php
検索ボタン(複数のページに検索窓を入れるので、テンプレートを分けます)
<form method=”get” class=”searchform” action=”<?php bloginfo(‘url’); ?>”>
<input type=”text” placeholder=”<?php the_search_query(); ?>”/>
<button type=”submit” class=”search”></button>
</form>
|
content-archive.php
デザイン用テンプレート
※名前は任意で大丈夫です。
・該当記事が存在する場合search.php内に
content-archive.php を呼ぶ、
<div class=”serch_text”>
<ul>
<!– ページタイトル取得 –>
<li>
<a href=”<?php the_permalink(); ?>”>
<?php if(mb_strlen($post->post_title)>25) { $title= mb_substr($post->post_title,0,25) ; echo $title. ・・・ ;
} else {echo $post->post_title;}?>
</a>
</li>
<!– ページタイトル取得 –>
<!– ページ内容取得 –>
<li>
<?php
//文字制限
$pattern = ‘/(^.{100})(.+)/u’; //ここに文字数
$subject = post_custom( ‘detail’ ); //ここにカスタムフィールドのスラッグを
$matches = array();
preg_match( $pattern, $subject, $matches );
if ( $matches[ 2 ] != ” ) {
$out = $matches[ 1 ] . ‘ …’ . ‘<a href=”‘ . get_permalink( $post->ID ) . ‘”>’ . ” . ‘</a>’;
} else {
$out = $subject;
}
echo( $out );
?>
<?php print strip_tags(get_the_excerpt(“”));?>
</li>
<!– ページ内容取得 –>
<!– ページURL取得 –>
<li>
<a href=”<?php the_permalink(); ?>”>
<?php the_permalink(); ?>
</a>
</li>
<!– ページURL取得 –>
</ul>
</div>
|
none.php
・検索窓を空欄で叩いた場合のページ
(ページャープラグインがページを認識してしまい、
ページャーが付いてしまうため、検索窓を空白のまま叩いた場合は
該当ページへリダイレクトさせる)
<?php
/*
Template Name: 「」の検索結果
*/
?>
<?php get_header(); ?>
<h2>「」の検索結果</h2>
<p>該当する記事が存在していません。</p>
<?php get_footer(); ?>
|
function.phpに検索機能の関数を追加
上でテンプレートファイルの作成が出来ましたら、
次はテーマ内で検索機能をカスタマイズするので、
下記追記をします。
1. 検索窓を空白のまま叩いた時に、ページャープラグインがページを認識してしまい、
ページャーが付いてしまうため、検索窓を空白のまま叩いた場合は該当ページへリダイレクト
するよう関数に記載。
function set_redirect_template(){
if (isset($_GET[‘s’]) && empty($_GET[‘s’])) {
include(TEMPLATEPATH . ‘/none.php’);
exit;
}
}
add_action(‘template_redirect’, ‘set_redirect_template’);
|
2. ~” の検索結果:全~件中 1~10 件目を表示(search.php で表示)
function my_result_count() {
global $wp_query;
$paged = get_query_var( ‘paged’ ) – 1;
$ppp = get_query_var( ‘posts_per_page’ );
$count = $total = $wp_query->post_count;
$from = 0;
if ( 0 < $ppp ) {
$total = $wp_query->found_posts;
if ( 0 < $paged )
$from = $paged * $ppp;
}
printf(
‘<p> 全%1$s 件中 %2$s%3$s 件目を表示</p>’,
$total,
( 1 < $count ? ($from + 1 . ‘~’) : ” ),
($from + $count )
);
}
|
3. wordpress の標準の検索範囲ではカスタム投稿が含まれないため、
下記を記載してカスタム投稿も検索対象に含めます。
function posts_search_custom_fields( $orig_search, $query ) {
if ( $query->is_search() && $query->is_main_query() && ! is_admin() ) {
global $wpdb;
$q = $query->query_vars;
$n = ! empty( $q[‘exact’] ) ? ” : ‘%’;
$searchand = ”;
foreach ( (array) $q[‘search_terms’] as $term ) {
$include = ‘-‘ !== substr( $term, 0, 1 );
if ( $include ) {
$like_op = ‘LIKE’;
$andor_op = ‘OR’;
} else {
$like_op = ‘NOT LIKE’;
$andor_op = ‘AND’;
$term = substr( $term, 1 );
}
$like = $n . $wpdb->esc_like( $term ) . $n;
// カスタムフィールド用の検索条件を追加します。
$search .= $wpdb->prepare( “{$searchand}(($wpdb->posts.post_title $like_op %s)
$andor_op ($wpdb->posts.post_content $like_op %s) $andor_op (custom.meta_value $like_op %s))”, $like, $like, $like );
$searchand = ‘ AND ‘;
}
if ( ! empty( $search ) ) {
$search = ” AND ({$search}) “;
if ( ! is_user_logged_in() )
$search .= ” AND ($wpdb->posts.post_password = ”) “;
}
return $search;
}
else {
return $orig_search;
}
}
add_filter( ‘posts_search’, ‘posts_search_custom_fields’, 10, 2 );
/**
* カスタムフィールド検索用のJOIN を行います。
*/
function posts_join_custom_fields( $join, $query ) {
if ( $query->is_search() && $query->is_main_query() && ! is_admin() ) {
// group_concat() したmeta_value をJOIN することでレコードの重複を除きつつ検索しやすくします。
global $wpdb;
$join .= ” INNER JOIN ( “;
$join .= ” SELECT post_id, group_concat( meta_value separator ‘ ‘) AS meta_value FROM $wpdb->postmeta “;
// $join .= ” WHERE meta_key IN ( ‘test’ ) “;
$join .= ” GROUP BY post_id “;
$join .= ” ) AS custom ON ($wpdb->posts.ID = custom.post_id) “;
}
return $join;
}
add_filter( ‘posts_join’, ‘posts_join_custom_fields’, 10, 2 );
|
4. 3でカスタム投稿を検索範囲にいれた後、下記赤文字部分に該当カスタム投稿のpost_typeを記載して、
(カスタム投稿のpost_typeが AAAであれば AAAと記載)
検索対象を指定します。(‘post’ 普通の投稿、’page’ 固定ページ)
/*【 出力カスタマイズ】投稿タイプを指定して検索対象を絞り込む */
function SearchFilter($query) {
if ( !is_admin() && $query->is_main_query() && $query->is_search() ) {
$query->set(‘post_type’, array(‘post’, ‘page’, ‘AAA’)); // カスタム投稿タイプ を追加
}
}
add_action( ‘pre_get_posts’,’SearchFilter’ );
|
以上function.php内に
記載が出来ましたら、テーマフォルダー内にアップを
します。
まとめ
検索機能は作成に少し時間がかかりますが、
記事数が多いサイトなどでは
該当の記事を探すのにすごく便利ですので、
ぜひ作成してみてください。
参考サイト:
https://creive.me/archives/9113/