web-dev-qa-db-fra.com

Besoin d'aide avec add_rewrite_rule

SOLUTION


Je suis allé avec la mise à jour 3 et je la fais fonctionner. Ce que j'avais mal compris, c'est que je croyais qu'une règle de réécriture changerait designers/?designer=some-designer&bid=9 en /designers/some-designer. Mais c'est bien sûr l'inverse.


J'ai fait des recherches, mais je ne comprends pas trop comment utiliser add_rewrite_rule () .

Ce message est assez proche de ce dont j'ai besoin, mais ai-je vraiment besoin de tant de code?

Mon lien actuel est le suivant:
http://www.norwegianfashion.no/designers/?designer=Batlak-og-Selvig&bid=9
Ce que je veux c'est ça
http://www.norwegianfashion.no/designers/Batlak-og-Selvig/

  1. Comment utiliser add_rewrite_rule()?
  2. Je dois transmettre l'ID de concepteur (enchère). Comment puis-je faire cela lorsque j'utilise des règles re.write sans que cela apparaisse dans l'URL?

Mise à jour 1

J'ai trouvé cela qui est un peu plus explicatif. Mais ça ne marche pas:

function add_rewrite_rules( $wp_rewrite ) 
{
    $new_rules = array(
        '('.$template_page_name.')/designers/(.*?)/?([0-9]{1,})/?$' => 'designers.php?designer='.
        $wp_rewrite->preg_index(1).'&bid='.
        $wp_rewrite->preg_index(2)
    );
       // Always add your rules to the top, to make sure your rules have priority
    $wp_rewrite->rules = $new_rules + $wp_rewrite->rules;
}
add_action('generate_rewrite_rules', 'add_rewrite_rules');

function query_vars($public_query_vars) {

    $public_query_vars[] = "designer";
    $public_query_vars[] = "bid";
    return $public_query_vars;
}
add_filter('query_vars', 'query_vars')

Mise à jour 2

Voici une autre solution que j'ai essayée, que Jan Fabry suggère dans un autre thread. Je mets cela dans mon functions.php, mais cela n’a aucun effet.

add_action('generate_rewrite_rules', 'add_rewrite_rules');
add_filter('query_vars', 'query_vars');

/* Custom re-write rules for desigenrs
------------------------------------------------------------------------------*/
function add_rewrite_rules( $wp_rewrite ) 
{
    add_rewrite_rule('^designers/([^/]*)/([^/]*)$ /designers/?designer=$1&bid=$2 [L]', 'top');
    flush_rewrite_rules(false);
}


function query_vars($public_query_vars) {

    $public_query_vars[] = "designer";
    $public_query_vars[] = "bid";
    return $public_query_vars;
}

Mise à jour 3
J'ai trouvé quelques exemples ici aussi. Mais cela ne fonctionne pas non plus :(

add_filter('rewrite_rules_array','wp_insertMyRewriteRules');
add_filter('query_vars','wp_insertMyRewriteQueryVars');
add_filter('init','flushRules');  

// Remember to flush_rules() when adding rules
function flushRules(){
    global $wp_rewrite;
    $wp_rewrite->flush_rules();
}

// Adding a new rule
function wp_insertMyRewriteRules($rules)
{
    $newrules = array();
    $newrules['(designers)/(\d*)$'] = 'index.php?pagename=designers&designer=$matches[1]';
    return $newrules + $rules;
}

// Adding the bid var so that WP recognizes it
function wp_insertMyRewriteQueryVars($vars)
{
    array_Push($vars, 'designer');
    return $vars;
}

Update 4 J'ai aussi essayé cette solution, mais toujours pas de succès.

add_filter('search_rewrite_rules', 'designers_createRewriteRules');

function designers_createRewriteRules($rewrite) {
global $wp_rewrite;

// add rewrite tokens
$designer_token = '%designers%';
$wp_rewrite->add_rewrite_tag($designer_token, '(.+)', 'designers=');

$bid_token = '%bid%';
$wp_rewrite->add_rewrite_tag($bid_token, '(.+)', 'bid=');

$keywords_structure = $wp_rewrite->root . "designers/$designer_token/$bid_token";
$keywords_rewrite = $wp_rewrite->generate_rewrite_rules($keywords_structure);

return ( $rewrite + $keywords_rewrite );

}

Mise à jour 5
Il semble que mes règles de réécriture ne soient pas ajoutées. L’exécution des nouvelles règles suivantes: print_r($wp_rewrite), n’inclut pas les nouvelles règles de réécriture.

Mise à jour 6
J'ai testé la solution de Jan. Mais l'URL ne change pas :(

/* Initiation script for NF template
------------------------------------------------------------------------------*/   
add_action('after_setup_theme','norwegianfashion_setup');

if ( ! function_exists( 'norwegianfashion_setup' ) ):

  function norwegianfashion_setup() { 
    /* Here I do a lot of stuff */

    // SEO friendly URL for desigenrs
    add_action( 'init', 'wpa5413_init' );
    add_filter( 'query_vars', 'wpa5413_query_vars' );
  }

endif;


/* Custom re-write rules for desigenrs
------------------------------------------------------------------------------*/
function wpa5413_init()
{
    // Remember to flush the rules once manually after you added this code!
    add_rewrite_rule(
        'designers/([^/]+)/?',
        'index.php?pagename=designers&designer=$matches[1]',
        'top' );
}

function wpa5413_query_vars( $query_vars )
{
    $query_vars[] = 'designer';
    return $query_vars;
}

Je voudrais vraiment apprécierais que quelqu'un puisse m'aider à résoudre ce problème.

54
Steven

Quelques informations sur les règles de réécriture

Le système de réécriture WP a l'air compliqué, mais en réalité, il n'est pas si difficile de comprendre son fonctionnement. Il est utilisé pour analyser les jolies URL (/designers/) comme si elles n'étaient pas jolies (/index.php?pagename=designers). L'idée de base est que vous disposiez d'une liste de règles de réécriture, expressions rationnelles pouvant correspondre aux URL entrantes, et que vous les réécriviez dans d'autres URL, principalement sous la forme de index.php avec certaines variables de requête. Ces variables sont définies sur des parties de l'expression régulière correspondant à l'URL. Les règles sont évaluées de haut en bas. Par conséquent, si deux règles peuvent correspondre, la première "gagne".

Ces règles de réécriture sont stockées dans la base de données en appelant flush_rewrite_rules(), mais étant donné que générer et écrire ces règles est une opération coûteuse, vous ne devez pas le faire à chaque init. Au lieu de cela, vous ne le faites que lorsque vous modifiez les règles: probablement lors de l'activation du plug-in (avec register_activation_hook()), ou manuellement en visitant la page Permaliens paramètres ( car il est difficile de le faire automatiquement lors de l'activation du thème ). Si vous ne videz pas les règles, appeler add_rewrite_rule() n'a aucun effet. Ce n'est pas un problème d'appeler add_rewrite_rule() sur chaque init, même après avoir vidé les règles.

Il existe de nombreuses façons d’ajouter vos règles de réécriture, et si vous ne souhaitez ajouter qu’une règle, vous pouvez le faire avec add_rewrite_rule(). Parce que les règles pour les articles, les pages, les taxonomies, ... résultent en plusieurs règles, elles sont créées avec des fonctions de haut niveau telles que add_rewrite_tag(), add_permastruct(), ... Mais elles ne sont pas nécessaires pour le cas simple que nous avons ici.

Il existe également certains filtres, vous pouvez donc ajouter vos règles à l'aide des points d'ancrage generate_rewrite_rules ou generate_rewrite_rules_array. Celles-ci vous donnent un contrôle très détaillé sur l’ensemble des règles, mais là encore, add_rewrite_rule() suffit, si vous souhaitez simplement ajouter une règle.

J'ai créé un petit plugin qui vous permet d'analyser les règles de réécriture actuelles , et (bien sûr) je vous recommande de l'utiliser lorsque vous essayez de changer quelque chose.

Obtenir vos informations supplémentaires à partir de l'URL

Construisons sur l'exemple que vous avez donné. Vous avez la marque de designer Batlak og Selvig, avec l'ID numérique (bid) 9. Vous ne voulez pas cet identifiant dans l'URL, mais seulement le nom. Nous appelons la version conviviale du nom (sans espaces ni caractères spéciaux) le slug : Batlak-og-Selvig.

En général, l'URL doit contenir toutes les informations permettant d'identifier le contenu que vous souhaitez afficher sur la page. Vous pouvez utiliser des cookies ou des demandes POST pour enregistrer l'ID de concepteur que vous souhaitez afficher. Toutefois, cette erreur échouera si quelqu'un partage le lien, en l'envoyant par courrier électronique, Facebook, Twitter ou en le lisant simplement. fort au téléphone. Si vous ne souhaitez pas utiliser l'ID numérique dans votre URL, vous devez vous assurer que le slug est unique: vous devez d'abord rechercher l'ID basé sur le slug et continuer comme auparavant.

Donc, ce que nous avons appris maintenant, c’est que nous voulons ajouter une règle de réécriture pour le motif "/designers/ suivi de tout jusqu’au prochain /", et enregistrer ce "rien" dans le designer_slug variable de requête. Dans votre cas, je pense que vous souhaitez également utiliser la page avec le slug designers comme contenu général de la page, nous allons donc le signaler également à WordPress.

add_action( 'init', 'wpa5413_init' );
function wpa5413_init()
{
    // Remember to flush the rules once manually after you added this code!
    add_rewrite_rule(
        // The regex to match the incoming URL
        'designers/([^/]+)/?',
        // The resulting internal URL: `index.php` because we still use WordPress
        // `pagename` because we use this WordPress page
        // `designer_slug` because we assign the first captured regex part to this variable
        'index.php?pagename=designers&designer_slug=$matches[1]',
        // This is a rather specific URL, so we add it to the top of the list
        // Otherwise, the "catch-all" rules at the bottom (for pages and attachments) will "win"
        'top' );
}

La seule chose à faire est de dire à WordPress de conserver également le designer_slug dans les variables de la requête afin de pouvoir y accéder ultérieurement. WordPress utilise une liste blanche de variables de requête autorisées afin d'empêcher les utilisateurs de modifier chaque paramètre de la requête de publication via l'URL. Tout ce qui ne figure pas sur cette liste est ignoré. Accrochez simplement le crochet query_vars et ajoutez votre variable supplémentaire:

add_filter( 'query_vars', 'wpa5413_query_vars' );
function wpa5413_query_vars( $query_vars )
{
    $query_vars[] = 'designer_slug';
    return $query_vars;
}

Comme vous pouvez le constater, cette réponse est fondamentalement la même que ma réponse précédente , mais sans que la règle soit affichée dans le code (vous pouvez donc l'utiliser dans le functions.php de votre thème au lieu d'un plugin), et avec un peu plus de certitude. et explication parce que j’ai beaucoup appris sur les règles de réécriture depuis (et à cause de) répondre à votre première question.

Discussion en salle de chat

Nous avons éclairci les questions finales pour cette question dans la salle de discussion . À la fin, Steven a utilisé le hook generate_rewrite_rules, car la fonction add_rewrite_rule() ne semblait pas fonctionner pour lui.

87
Jan Fabry