Besoin d'aide avec add_rewrite_rule


55

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=9en /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 ce
http://www.norwegianfashion.no/designers/Batlak-og-Selvig /

  1. Comment puis-je 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 a suggérée dans un autre fil. 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;
}

Mise à jour 4 J'ai également essayé cette solution, mais toujours sans 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)ne comprend 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;
}

J'apprécierais vraiment si quelqu'un pouvait m'aider à résoudre ce problème.


Cela ressemble beaucoup à la première question que vous avez posée ici et à laquelle j'ai donné une réponse . La situation a-t-elle changé depuis, alors ma réponse n'est plus valide? Si vous ne souhaitez pas que l'ID de concepteur figure dans votre URL, vous devrez convertir vous-même le "slug" en ID, WordPress ne peut pas le faire pour vous. Les concepteurs sont-ils toujours un objet externe?
Jan Fabry

@ Jan Fabry Oui, j'ai découvert cela après avoir posté ceci (j'avais oublié). Maintenant, je comprends mieux votre suggestion. Voir mon code mis à jour ici. Mes concepteurs sont toujours des entrées dans une base de données personnalisée. Est-il possible d'utiliser POST insteed og GET pour le transmettre bid?
Steven

L'utilisation d'une demande POST ne sera pas valable si je copie le lien et l'envoie à quelqu'un d'autre. Est-ce un problème de rendre le slug unique et d'effectuer la recherche de données à partir de là?
Jan Fabry

@ Jan Fabry: Qu'entendez-vous par slug? `Récupérer les données de Designer est beaucoup plus facile à utiliser bidquedesigner
Steven

Réponses:


87

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

Le système WP Rewrite semble compliqué, mais en réalité, il n’est pas difficile de comprendre son fonctionnement. Il est utilisé pour analyser les jolies URL ( /designers/) comme si elles étaient non-jolies ( /index.php?pagename=designers). L'idée de base est que vous disposiez d'une liste de règles de réécriture , d'expressions régulières pouvant correspondre aux URL entrantes, et que vous les réécriviez dans d'autres URL, principalement sous la forme de index.phpcertaines 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 par appel flush_rewrite_rules(), mais, comme générer et écrire ces règles est une opération coûteuse, vous ne devez pas le faire à chaque fois init. Au lieu de cela, vous ne le faites que lorsque vous modifiez les règles: probablement lors de l'activation du plug-in (utilisation register_activation_hook()), ou manuellement en visitant la page des paramètres de Permalinks ( car il est difficile de le faire automatiquement lors de l'activation du thème ). Si vous ne videz pas les règles, l'appel add_rewrite_rule()n'aura aucun effet. Ce n'est pas un problème d'appeler add_rewrite_rule()chaque fois init, même après avoir éliminé 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 postes, pages, taxonomies, ... suite à plusieurs règles, ils sont créés avec des fonctions de haut niveau comme add_rewrite_tag(), add_permastruct()... Mais ceux - ci ne sont pas nécessaires pour le cas simple que nous avons ici.

Il existe également certains filtres, vous pouvez donc également ajouter vos règles à l’aide des crochets generate_rewrite_rulesou generate_rewrite_rules_array. Celles-ci vous donnent un contrôle très détaillé sur l'ensemble des règles, mais encore une fois, cela 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 du 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 URL conviviale du nom (sans espaces ou caractères spéciaux) la limace : Batlak-og-Selvig.

En règle générale, 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 stocker l'ID de concepteur que vous souhaitez afficher, mais cette erreur échouera si quelqu'un partage le lien, en l'envoyant par courrier, Facebook, Twitter ou simplement en le lisant à haute voix par 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 modèle " /designers/suivi de rien jusqu'à la suivante /" et enregistrer ce "n'importe quoi" dans la designer_slugvariable de requête. Dans votre cas, je pense que vous souhaitez également utiliser la page avec le slug designerscomme contenu général de la page, nous allons donc le dire é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 qui reste à faire est de dire à WordPress de conserver également designer_slugles variables de la requête afin que vous puissiez 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-vous simplement au query_varscrochet 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 votre thème functions.phpplutôt que dans un plugin), et avec un peu plus de certitude et d'explication, car j'ai appris beaucoup sur les règles de réécriture depuis (et à cause de) répondre à votre première question.

Discussion en salle de chat

Nous avons résolu les dernières questions relatives à cette question dans la salle de discussion . À la fin, Steven a utilisé le generate_rewrite_rulescrochet, parce que la add_rewrite_rule()fonction ne semblait pas fonctionner pour lui.


2
@Steven: pagenameest le slug de la page WordPress que vous souhaitez afficher (enregistrez dans la base de données). Cette page peut ensuite indiquer qu'elle souhaite utiliser le designers.phpfichier de modèle dans la zone d'administration WP. Donc, vous pointez sur le slug de page, pas sur le nom du modèle, car le même modèle peut être utilisé pour plusieurs pages: dans ce cas, WordPress ne sait pas ce que vous voulez faire.
Jan Fabry

1
@ Steven: Je pense que vous compliquez exagérément la façon dont vous configurez les crochets. Supprimez la add_rewrite_rules()fonction et appelez add_filter()/add_action()directement. S'il s'agit d'un fichier de thème, supprimez-le flush_rewrite_rules()et visitez la page des paramètres de permaliens pour purger les règles (ou ajoutez-les wpse5413_init()et supprimez-les plus tard). Et mon plugin affiche les règles de réécriture actuelles. N'oubliez pas que cela ne modifie que la manière dont les URL entrantes sont traitées, pas la manière dont votre code écrira les URL dans le code HTML.
Jan Fabry

1
@ Steven: Je ne pense pas que vous ayez même à appuyer sur le bouton de sauvegarde, il vous suffira d'ouvrir la page des permaliens pour le vider. Et encore une fois, cela ne fera qu'ajouter à la capacité de WordPress d'accepter les /designers/designer-slug/URL, vous devez changer vous-même les endroits où vous écrivez ces URL dans votre code HTML. Testez-le en allant à /designers/Batlak-og-Selvig/vous-même, si cela fonctionne, trouvez tous les emplacements qui génèrent ces URL et modifiez-les pour qu'ils utilisent la nouvelle structure.
Jan Fabry

1
Ah, maintenant je pense que je commence à udnerstand. Je pensais que les règles de réécriture changeraient la manière dont l'URL était affichée dans le champ URL du navigateur. Mais ce que cela signifie, c’est que je dois sortir l’URL www.mysite.com/batlat-og-selvig/9et que celle-ci soit "traduite" en/?designer=Batlak-og-Selvig&bid=9
Steven

1
@Steven: Oui, en effet: les règles de réécriture gèrent les liens entrants et n'affectent (uniquement dans quelques cas sélectionnés) les liens générés dans votre code.
Jan Fabry
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.