Je travaille sur un site Web avec deux types de publication partageant plusieurs taxonomies et champs personnalisés. J'ai développé une fonctionnalité de filtrage avec de jolies URL, et les urls fonctionnent pour le moment de cette manière:
1) J'ai enregistré mes vars de requête
function return_vars( $vars ) {
$vars[] = 'tax_filters';
$vars[] = 'field_filters';
return $vars;
}
add_filter( 'query_vars', 'return_vars' );
2) J'ai configuré ces règles de réécriture en utilisant add_rewrite_rule () de cette manière:
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');
pour que:
Donc, mes URL peuvent être:
(according to rule 1)
my-base/my-cpt/filters/tax1/term/tax2/term/../../fields/field1/value/fields2/value/../../
ou filtrer uniquement les taxes:
(according to rule 2)
my-base/my-cpt/filters/tax1_name/term/tax2_name/term/../../
Maintenant, puisque j'ai besoin de même:
Cela donnerait 6 règles différentes, qui doivent être écrites dans un ordre spécifique, du plus long au plus court, sinon ces dernières écraseront les autres.
Je me demandais: est-il possible d'écrire une regex qui combinerait éventuellement toutes ces règles en une?
J'ai essayé avec plusieurs expressions conditionnelles regexes, mais je n'y suis pas compétent, je n'ai donc que des erreurs d'analyse.
Merci à tous ceux qui pourraient aider!
J'ai réussi à contourner le problème. Il est la solution pour référence ultérieure.
1) Je n'ai qu'une seule requête var maintenant:
function return_vars( $vars ) {
$vars[] = 'filters';
return $vars;
}
2) Mes règles de réécriture ont été modifiées en:
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');
Règle 1: gestion de la pagination Règle 2: gestion de la page principale uniquement
Ils doivent être dans cet ordre.
3) Ensuite, je filtre plus ou moins la chaîne de filtres de cette manière
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);
De cette façon, je peux même fournir plusieurs termes pour les taxes ou des valeurs pour les champs, tels que:
/my-base/filters/my-cpt/tax1/term1,term2/tax2/term1,term2/field1/val1,val2/goingon...
Et ça va marcher! Avec la pagination aussi.
Évidemment, le code ci-dessus fonctionne, mais il y a aussi plusieurs vérifications pour éviter les problèmes et les hacks (par exemple, vérifier si un nom de champ fourni existe ou non, ou s'il se trouve dans une liste de champs filtrable, etc.).
J'espère que cela aidera quelqu'un :)