ADD_REWRITE_RULE()中的条件正则表达式,用于特定的查询过滤器和分页

时间:2017-12-03 作者:frafor

我在一个网站上工作,有两种帖子类型,共享几种分类法&;自定义字段。我开发了一个具有漂亮URL的过滤功能,目前URL的工作方式如下:

1) 我已经注册了查询变量

function return_vars( $vars ) {
$vars[] = \'tax_filters\';
$vars[] = \'field_filters\';
return $vars;
}
add_filter( \'query_vars\', \'return_vars\' );
2)我使用add\\u rewrite\\u 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\');
以便:

$matches[1]表示post类型筛选器分类法。它是一个字符串,由斜线分隔,格式为/tax1\\u name/term/tax2\\u name/term/tax3\\u name/term

  • $matches[3]在第一条规则中,停止匹配[2]记录,并开始匹配/fields/占位符后的内容,如下所示/field1\\u name/value/field2\\u name/etcetera最近,我根据tax\\u filters[]的内容,使用pre\\u get\\u posts筛选WP\\u查询;field\\u筛选器[]
  • ,因此我的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/../../
    
    现在,因为我甚至需要:

    仅对字段进行筛选,如:我的cpt/字段/字段1/值/字段2/值/每个可能的筛选组合的分页:a)仅税务,b)仅字段c)税务和字段这将导致6个不同的规则,这些规则必须按照从最长到最短的特定顺序编写,否则后者将覆盖其他规则。

    我想知道:是否有可能编写一个最终将所有这些规则结合在一起的正则表达式?

    我尝试了几个regex条件语句,但我并不精通,所以我只遇到了解析错误。

    感谢所有能帮忙的人!

    1 个回复
    最合适的回答,由SO网友: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...
    
    它会起作用的!也使用分页。

    显然,上面的代码是可行的,但也有一些检查可以避免问题和黑客攻击(例如检查提供的字段名是否存在,或者是否在可过滤字段列表中等等)。

    希望这对某人有所帮助:)

    结束

    相关推荐

    有没有办法在Custom Post Listing页面上重新排序Custom Taxonomy下拉菜单?

    我用过register_taxonomy() 具有\'show_admin_column\' => true 成功获取自定义帖子类型列表页面上的下拉列表。默认情况下,下拉列表按ID顺序显示术语。有人知道把这个改成字母顺序的方法吗?