web-dev-qa-db-ja.com

特定のクエリフィルタとページ編集用のadd_rewrite_rule()の条件付き正規表現

私はいくつかの分類法とカスタムフィールドを共有する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');

そのため:

  1. $ matches [1]は投稿タイプを表します
  2. $ matches [2]は分類法をフィルタリングします。スラッシュで区切った/ tax1_name/term/tax2_name/term/tax3_name/termの形式の文字列です。
  3. 最初のルールの$ matches [3]は、matches [2]の記録を停止し、/ fields /プレースホルダの後の/ field1_name/value/field2_name/etceteraの後のもののマッチングを開始します。
  4. 最近、tax_filters []とfield_filters []の内容に従って、pre_get_postsを使用してWP_Queryをフィルタリングします。

したがって、私の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/../../

今、私も必要だから:

  1. my-cpt/fields/field1/value/fields2/value /のようなフィールドのみのフィルタリング
  2. 可能な各フィルタの組み合わせに対するページ付け:a)税のみ、b)フィールドのみc)税およびフィールド

これは6つの異なる規則をもたらし、それらは最長から最短まで特定の順序で書かれなければならず、そうでなければ後者は他を上書きするでしょう。

私は不思議に思っていました:結局これらすべての規則を一つにまとめるだろう正規表現を書くことは可能ですか?

私はいくつかの正規表現条件付きステートメントを試してみましたが、私はそれに精通していないので、私はパースエラーだけを得ました。

手助けできる人に感謝します。

1
frafor

私はなんとか問題を回避することができました。彼はさらなる参考のための解決策です。

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リストなどにあるかどうかのチェックなど)。

これが誰かに役立つことを願っています:)

2
frafor