私はいくつかの分類法とカスタムフィールドを共有する2つの投稿タイプを持つWebサイトに取り組んでいます。私はきれいなURLでフィルタリング機能を開発しました、そして今のところURLはこのように動作します:
1)クエリ変数を登録しました
function return_vars( $vars ) {
$vars[] = 'tax_filters';
$vars[] = 'field_filters';
return $vars;
}
add_filter( 'query_vars', 'return_vars' );
2)私はこのようにadd_rewrite_rule()を使ってこれらの書き換えルールを設定しました。
add_rewrite_rule( 'my-base/filters/([^\/]*)/([^&]*)/fields/([^&]*)/?', 'index.php?post_type=$matches[1]&tax_filters=$matches[2]&field_filters=$matches[3]', 'top');
add_rewrite_rule( 'my-base/filters/([^\/]*)/([^&]*)/?', 'index.php?post_type=$matches[1]&tax_filters=$matches[2]', 'top');
そのため:
したがって、私のURLは次のようになります。
(according to rule 1)
my-base/my-cpt/filters/tax1/term/tax2/term/../../fields/field1/value/fields2/value/../../
または税だけをフィルタリングする:
(according to rule 2)
my-base/my-cpt/filters/tax1_name/term/tax2_name/term/../../
今、私も必要だから:
これは6つの異なる規則をもたらし、それらは最長から最短まで特定の順序で書かれなければならず、そうでなければ後者は他を上書きするでしょう。
私は不思議に思っていました:結局これらすべての規則を一つにまとめるだろう正規表現を書くことは可能ですか?
私はいくつかの正規表現条件付きステートメントを試してみましたが、私はそれに精通していないので、私はパースエラーだけを得ました。
手助けできる人に感謝します。
私はなんとか問題を回避することができました。彼はさらなる参考のための解決策です。
1)クエリ変数は1つだけです。
function return_vars( $vars ) {
$vars[] = 'filters';
return $vars;
}
2)書き換え規則が次のように変更されました。
add_rewrite_rule( 'my-base/filters/([^\/]*)/([^&]*)/page/([0-9]{1,})/?', 'index.php?post_type=$matches[1]&filters=$matches[2]&paged=$matches[3]', 'top');
add_rewrite_rule( 'my-base/filters/([^\/]*)/([^&]*)/?', 'index.php?post_type=$matches[1]&filters=$matches[2]', 'top');
規則1:ページ区切りを処理する規則2:メインページのみを処理する
彼らはこの順番でなければなりません。
3)次に、このようにしてフィルタ文字列を多かれ少なかれフィルタします。
function my_pre_get_posts( $query ) {
$filters = get_query_var('filters');
// if no filter or if filters are odd, then return
if(!$filters || count(explode("/", $k4w_filters)) % 2 != 0) return;
// this is a global array with my 2 tax slugs in it
global $CUSTOM_TAXES_S;
$chunks = array_chunk(explode('/', $filters), 2);
$filter_data = array_combine(array_column($chunks, 0), array_column($chunks, 1));
// filter data, populate tax_data and field_data for queries
foreach($filter_data as $key => $value) {
if(in_array($key, $CUSTOM_TAXES_S)) {
$tax_data[$key] = $value;
} else {
$field_data[$key] = $value;
}
$query->set('debug_tax_data', $tax_data);
$query->set('debug_field_data', $field_data);
}
// if tax_data exist set tax_query
if($tax_data) {
foreach( $tax_data as $taxonomy => $slugs ) {
// append tax query
$tax_query[] = array(
'taxonomy' => get_tax_name($taxonomy), // that's a simple function that retrieves the taxonomy name from its slug
'field' => 'slug',
'terms' => explode(',', $slugs),
);
}
$query->set('tax_query', $tax_query);
}
// if field_data exist set meta_query
if($field_data) {
foreach( $field_data as $key => $value ) {
// append tax query
$meta_query[] = array(
'key' => $key,
'value' => explode(',',$value),
'compare' => 'IN',
);
}
$query->set('meta_query', $meta_query);
}
}
add_action('pre_get_posts', 'my_pre_get_posts', 10, 1);
このようにして、私は税のための複数の用語、またはフィールドのための値を提供することさえできます:
/my-base/filters/my-cpt/tax1/term1,term2/tax2/term1,term2/field1/val1,val2/goingon...
そしてそれはうまくいくでしょう!ページネーションも。
明らかに上記のコードは動作しますが、問題やハックを避けるためのチェックもいくつかあります(提供されたフィールド名が存在するかどうか、またはそれがfiltrable-fieldリストなどにあるかどうかのチェックなど)。
これが誰かに役立つことを願っています:)