これはちょっとめんどくさい。
完成イメージ
カスタム投稿を作ったとする。溜まった記事をソートしたい。ソートするのは複数のタクソノミーからの選択で、自由入力欄は使わない。一般的なブログで言う年月の指定とタグの指定を組み合わせるみたいな感じ。
カスタム投稿の記事一覧はタームを指定した絞り込みが可能で、複数のタクソノミーにも対応している。
なので、ソート機能的には問題ない。どうやって絞り込みの条件を指定するか、反映させるかが肝になる。
<?php
$myQuery = new WP_Query();
$param = array(
'posts_per_page' => '-1',
'post_type' => '【カスタム投稿スラッグ】',
'tax_query' => array(
array(
'taxonomy' => '【タクソノミースラッグ】',
'field' => 'slug',
'terms' => '【タームスラッグ】',
),
array(
'taxonomy' => '【タクソノミースラッグ】',
'field' => 'slug',
'terms' => '【タームスラッグ】',
),
),
);
$myQuery->query($param);
?>
<?php if($myQuery->have_posts()): ?>
<?php while($myQuery->have_posts()) : $myQuery->the_post(); ?>
<?php endwhile; ?>
<?php endif; ?>
動作ギミック
URLパラメータに放り込んで、取得して、発火させる感じにする。
https://example.jp/【カスタム投稿スラッグ】/?【タクソノミー1】=【ターム】&【タクソノミー2】=【ターム】
パラメータの生成はjs、パラメータの取得から一覧の生成はPHPでやっていくとする。
それぞれの役割
select、inputの情報からjsでGETを作る、phpでGETを取得して処理するという形。
POSTの方がURL的に美しいけど、特定の絞り込みが掛かった状態で表示するリンクを出力したい場合を考えたら、URLが間延びしてでもGETでやっていく方がいい。
ソート用フォーム
<div id="sort">
<select name="【タクソノミー1スラッグ】">
<option value="">区分なし</option>
<?php
$terms = get_terms('【タクソノミー1スラッグ】');
foreach ( $terms as $term ) :
if($_GET["【タクソノミー1スラッグ】"] == $term->slug){$selected = 'selected';}else{$selected = '';}
?>
<option value="<?php echo $term->slug; ?>" <?php echo $selected; ?>><?php echo $term->name; ?></option>
<?php endforeach; ?>
</select>
<select name="【タクソノミー2スラッグ】">
<option value="">すべての年度</option>
<?php
$terms = get_terms('【タクソノミー2スラッグ】',array('order'=>'DESC',));
foreach ( $terms as $term ) :
if($_GET["【タクソノミー2スラッグ】"] == $term->slug){$selected = 'selected';}else{$selected = '';}
?>
<option value="<?php echo $term->slug; ?>" <?php echo $selected; ?>><?php echo $term->name; ?></option>
<?php endforeach; ?>
</select>
<input type="hidden" name="url" value="<?php echo get_post_type_archive_link('【カスタム投稿スラッグ】');?>">
<button>ソート</button>
</div>
各タクソノミーのターム一覧、現在のURLが必要。
ターム一覧はそれぞれselectに仕込むとして、パラメータに入ってたら該当タームにseletedを付ける。
URLはすでにパラメータとかハッシュタグが付いてると邪魔くさいのできれいな形で出力する。ページ送りのことを考えたら固定ページよりもarchive-○○.php上で動かしたほうが動作的に安心できる。
おまけとして、「Intuitive Custom Post Order」を仕込むなら15行目みたいにorderを指定する。
js側の構成
$(function(){
$('#sort button').on('click',function(){
var taxonomy01Val = $('#sort select[name="【タクソノミー1スラッグ】"]').find('option:selected').val();
var taxonomy02Val = $('#sort select[name="【タクソノミー2スラッグ】"]').find('option:selected').val();
var sortArray = [];
var thisURL = $('#sort input[name="url"]').val();
if(taxonomy01Val != ''){
var arraytmp = {};
arraytmp.name = '【タクソノミー1スラッグ】';
arraytmp.value = taxonomy01Val;
sortArray.push(arraytmp);
}
if(taxonomy02Val != ''){
var arraytmp = {};
arraytmp.name = '【タクソノミー2スラッグ】';
arraytmp.value = taxonomy02Val;
sortArray.push(arraytmp);
}
if(taxonomy01Val != '' || taxonomy02Val != ''){
var urlParam = '';
for(let i = 0; i < sortArray.length; i++){
if(i == 0){
urlParam = '?';
}else{
urlParam += '&';
}
urlParam += sortArray[i].name+'='+sortArray[i].value;
}
var refleshURL = thisURL+urlParam;
document.location = refleshURL;
}
})
})
やりたいこと優先で組んだのでキレイじゃないけど動作はする。
各種selectの選択した値とurlを取得して、パラメータの書式でURLにくっつけてリダイレクトさせる。
php側の構成
パラメータを取得して多次元連想配列を生成してtax_queryにぶち込む。
<?php
$taxQueryArray = array();
if(!empty($_GET["【タクソノミー1スラッグ】"])):
array_push($taxQueryArray, array('taxonomy' => '【タクソノミー1スラッグ】', 'field' => 'slug', 'terms' => $_GET["【タクソノミー1スラッグ】"],));
endif;
if(!empty($_GET["【タクソノミー2スラッグ】"])):
array_push($taxQueryArray, array('taxonomy' => '【タクソノミー2スラッグ】', 'field' => 'slug', 'terms' => $_GET["【タクソノミー2スラッグ】"],));
endif;
$myQuery = new WP_Query();
$param = array(
'posts_per_page' => '-1',
'post_type' => '【カスタム投稿スラッグ】',
'tax_query' => $taxQueryArray,
);
$myQuery->query($param);
?>
<?php if($myQuery->have_posts()): ?>
<?php while($myQuery->have_posts()) : $myQuery->the_post(); ?>
<?php endwhile; ?>
<?php endif; ?>
tax_queryの中身が空っぽだったら絞り込みがないということで、全部出る。
なんでこんなことをしたか
今回言いたいのは作り方よりもこっちの方だったり。
通常の手法による検索はtaxonomy.phpやらsearch.phpやらを使うことになる。検索の内訳によって使用するファイル(ページ)が異なるのがWPの仕様。でもそれに対応させるとファイル数が膨大になって面倒くさいので表示するページを指定してその中で動作させるほうが楽だ、という結論になった。
コメント