※この投稿は、
Wordpress、ACF(Advanced Custom Fields)、カスタムフィールド、カスタム投稿、pre_get_posts
この辺りのキーワードに関する記事です。
<やりたいこと>
WordpressのACFで作成した病院の施設情報の(施設名、住所、診療科)を、カスタム投稿で何件か作成して、pre_get_postsの書き方で表示する。
チェックボックスと、フリーのキーワード検索の機能を追加して、検索結果も表示する。
例えば、、、
キーワード検索の欄に、"長崎県"と入力→住所が長崎県の施設を取得
チェックボックスに”消化器内科”、キーワード検索の欄に"長崎県"と入力→長崎県にある消化器内科がある施設を取得
ACFの参考サイト
https://usagicode.com/wordpress/how-to-use-advanced-custom-fields/
<環境>
wordpressのプラグインACFを使用
post_type:hospitals
病院名:投稿のタイトル
住所:カスタムフィールドの名前(hospital_address)
診療科:カスタムフィールドの名前(hospital_medical)
↓
functions.phpを通してarchive.phpへ
↓
archive.phpで
病院名、住所、診療科目の表示
↓"クリニック"とキーワード検索したときの画面
ちなみに、、、、
初めは、archive.phpで検索画面と検索結果のどちらも表示していた。
(archive.phpで検索して、結果もarchive.phpで表示)
検索した時に、該当のデータの数は取れるが、中身がちゃんと表示されていない状況
↓
検索画面と検索結果の画面を分けた → うまく表示されるようになった。
<コード一覧>
・index.php
<h2>診療科目選択</h2>
<!-- 検索フォーム -->
<form role="search" method="get" id="searchform" class="searchform" action="<?php echo esc_url(home_url('/hospitals')); ?>">
<?php
// 全ての施設情報を取得
$posts = get_posts(
array(
'post_type' => 'hospitals',
'posts_per_page' => -1,
)
);
$specialities = array(); // 診療科目を保存する配列
foreach ($posts as $post) { // 取得した投稿をループ処理
$specialities_array = get_field('hospital_medical', $post->ID); //診療科目を取得
if (is_array($specialities_array)) {
foreach ($specialities_array as $item) {
if (!in_array($item, $specialities)) { // 診療科目がまだ配列に追加されていなければ追加
$specialities[] = $item;
}
}
}
}
// 診療科目のチェックボックスを表示
foreach ($specialities as $item) {
// チェックされた値を取得
$checked = '';
if (isset($_GET['specialities_array']) && in_array($item, $_GET['specialities_array'])) {
$checked = ' checked="checked"';
}
echo '<input type="checkbox" name="specialities_array[]" value="' . esc_attr($item) . '">' . esc_html($item) . '<br>';
}
?>
<div>
<label class="screen-reader-text" for="s"><?php _x('Search for:', 'label'); ?></label>
<input type="text" value="<?php echo get_search_query(); ?>" name="s" id="s" placeholder="キーワード検索">
<input type="submit" id="searchsubmit" value="検索">
<a href="<?php echo esc_url(home_url('hospitals/')); ?>">リセット</a>
</div>
</form>
<!-- 検索フォームここまで -->
・archive.php
<h2>検索結果</h2><br>
<!-- アーカイブ表示 -->
<?php
// アーカイブページのメインループ
if(have_posts()){
while ( have_posts() ) : the_post();?>
<!-- // タイトル表示 -->
<h2><?php the_title(); ?></h2>
<p>住所:<?php the_field('hospital_address'); ?></p>
<p>診療科目:<?php the_field('hospital_medical'); ?></p>
<?php echo '<hr>';
endwhile;
echo paginate_links();
} else {
echo "記事なし";
}
?>
<br>
<a href="<?php echo esc_url(home_url('/')); ?>">検索画面へ</a>
・functions.php
<?php
//サイト内検索の設定
add_filter('pre_get_posts', 'filter_search');
function filter_search($query)
{
if ( is_admin() && !$query->is_main_query() ){
return;
}
if ($query->is_search()) {
$query->set('post_type', 'hospitals');
$page = get_query_var('paged') ? get_query_var('paged') : 1;
$query->set('paged', $page);
$query->set( 'posts_per_page', -1 );
}
}
// 検索
add_filter('posts_search', 'custom_search', 10, 2);
function custom_search($search, $wp_query)
{
global $wpdb;
if (!$wp_query->is_archive) {
return $search;
}
if (!isset($wp_query->query_vars)) {
return $search;
}
$search_words = isset($wp_query->query_vars['s']) ? $wp_query->query_vars['s'] : "";
$search_words = explode(' ', $search_words);
// タイトル検索用のSQLを構築
if (count($search_words) > 0) {
$search = '';
$search .= " AND post_type = 'hospitals' ";
foreach($search_words as $search_word ) {
if (!empty($search_word)){
$search_word = '%'. esc_sql($search_word) .'%';
// var_dump($search_word);
$search .= " AND ({$wpdb->posts}.post_title LIKE '{$search_word}'
OR {$wpdb->posts}.ID IN (
SELECT distinct post_id
FROM {$wpdb->postmeta}
WHERE meta_value LIKE '{$search_word}')
)";
}
}
}
return $search;
}
?>
<?php
function filter_hospital_query( $query ) {
//is_admin() をチェックして管理画面のクエリには影響ないようにする
//$query->is_main_query() でメインクエリであることをチェック
if ( is_admin() && !$query->is_main_query() ){
return;
}
if ($query->is_archive) {
$query->set('post_type', 'hospitals');
$page = get_query_var('paged') ? get_query_var('paged') : 1;
$meta_query = array();
// var_dump($meta_query);
$selected_specialities = isset( $_GET['specialities_array'] ) ? $_GET['specialities_array'] : array();
// var_dump($selected_specialities);
// チェックボックスのみの時
if ( $selected_specialities && empty($search_term) ) {
foreach ( $selected_specialities as $selected ) {
$meta_query[] = array(
'key' => 'hospital_medical',
'value' => $selected,
'compare' => 'LIKE',
);
}
$query->set('paged', $page);
$query->set( 'posts_per_page', -1 );
$query->set( 'meta_query', $meta_query );
}
}
}
add_action( 'pre_get_posts', 'filter_hospital_query' );
?>
参考サイト