Hai bisogno di aiuto con add_rewrite_rule


55

SOLUZIONE


Sono andato con l'aggiornamento 3 e l'ho fatto funzionare. Ciò che avevo frainteso era che credevo che una regola di riscrittura sarebbe cambiata designers/?designer=some-designer&bid=9in /designers/some-designer. Ma è ovviamente il contrario.


Ho fatto qualche ricerca, ma non capisco come usare add_rewrite_rule () .

Questo post è abbastanza vicino a quello di cui ho bisogno, ma ho davvero bisogno di quel codice?

Il mio link attuale è questo:
http://www.norwegianfashion.no/designers/?designer=Batlak-og-Selvig&bid=9
Quello che voglio è questo
http://www.norwegianfashion.no/designers/Batlak-og-Selvig /

  1. Come si usa add_rewrite_rule()?
  2. Devo passare l'ID designer (offerta). Come posso farlo quando uso le regole re.write senza che sia mostrato nell'URL?

Aggiornamento 1

Ho trovato questo che è un po 'più esplicativo. Ma non funziona:

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')

Aggiornamento 2

Ecco un'altra soluzione che ho provato, suggerita da Jan Fabry in un altro thread. L'ho inserito nel mio function.php, ma non ha alcun effetto.

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;
}

Aggiornamento 3
Ho trovato alcuni esempi anche qui . Ma neanche questo funziona :(

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;
}

Aggiornamento 4 Ho anche provato questa soluzione, ma ancora senza successo.

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 );

}

Aggiornamento 5
Sembra che le mie regole di riscrittura non siano state aggiunte. Eseguendo le seguenti nuove regole:, print_r($wp_rewrite)non include le mie nuove regole di riscrittura.

Aggiornamento 6
Ho testato la soluzione di Jan. Ma l'URL non cambia :(

/* 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;
}

Lo apprezzerei davvero se qualcuno fosse in grado di aiutarmi a risolvere questo problema.


Sembra molto simile alla prima domanda che hai posto qui e per la quale ho dato una risposta . Da allora la situazione è cambiata, quindi la mia risposta non è più valida? Se non desideri l'ID designer nel tuo URL, dovrai convertire tu stesso lo "slug" nell'ID, WordPress non può farlo per te. I designer sono ancora un oggetto esterno?
Jan Fabry,

@ Jan Fabry Sì, ho scoperto che dopo aver pubblicato questo (l'avevo dimenticato). Ora capisco meglio il tuo suggerimento. Vedi il mio codice aggiornato qui. I miei designer sono ancora voci in un DB personalizzato. È possibile utilizzare POST insteed og GET per passare lungo il bid?
Steven,

L'uso di una richiesta POST non mi preoccuperà se copio il link e lo invio a qualcun altro. È un problema rendere unico lo slug e cercare i dati da lì?
Jan Fabry,

@ Jan Fabry: cosa intendi con slug? `Recuperare i dati di Designer è molto più facile da usare bidpiuttosto chedesigner
Steven il

Risposte:


87

Alcuni retroscena sulle regole di riscrittura

Il sistema WP Rewrite sembra complicato, ma in realtà non è così difficile capire come funziona. Viene utilizzato per analizzare graziosi URL ( /designers/) come se fossero non graziosi ( /index.php?pagename=designers). L'idea di base è che hai un elenco di regole di riscrittura , espressioni regolari che possono corrispondere agli URL in arrivo e riscrivili in altri URL, principalmente sotto forma di index.phpalcune variabili di query. Queste variabili sono impostate su parti dell'espressione regolare che corrispondono all'URL. Le regole vengono valutate dall'alto verso il basso, quindi se due regole possono corrispondere, la prima "vince".

Queste regole di riscrittura vengono archiviate nel database chiamando flush_rewrite_rules(), ma poiché la generazione e la scrittura di queste regole è un'operazione costosa, non dovresti farlo su tutti init. Invece, lo fai solo quando modifichi le regole: probabilmente all'attivazione del plugin (usando register_activation_hook()), o manualmente visitando la pagina delle impostazioni di Permalink ( perché è difficile farlo automaticamente all'attivazione del tema ). Se non si scarica le regole, la chiamata add_rewrite_rule()non ha alcun effetto. Non è un problema fare appello add_rewrite_rule()a tutti init, anche dopo aver scaricato le regole.

Esistono molti modi per aggiungere le regole di riscrittura e se si desidera aggiungere solo una regola, è possibile farlo con add_rewrite_rule(). Poiché le regole per i posti, pagine, tassonomie, ... risultato in più regole, sono creati con le funzioni di alto livello come add_rewrite_tag(), add_permastruct(), ... Ma questi non sono necessari per il caso semplice che abbiamo qui.

Ci sono anche alcuni filtri, quindi puoi anche aggiungere le tue regole usando i ganci generate_rewrite_ruleso generate_rewrite_rules_array. Questi ti danno un controllo molto dettagliato sulle regole complete, ma, di nuovo, add_rewrite_rule()è sufficiente se vuoi solo aggiungere una regola.

Ho creato un piccolo plugin che ti consente di analizzare le regole di riscrittura correnti e (ovviamente) ti consiglio di usarlo quando provi a cambiare qualcosa.

Ottieni le tue informazioni extra dall'URL

Costruiamo sull'esempio che hai dato. Hai il marchio del designer Batlak og Selvig, con l'ID numerico ( bid) 9. Non vuoi questo ID nell'URL, ma solo il nome. Chiamiamo la versione URL-friendly del nome (senza spazi o caratteri speciali) della lumaca : Batlak-og-Selvig.

In generale, l'URL deve contenere tutte le informazioni per identificare il contenuto che si desidera mostrare sulla pagina. È possibile utilizzare i cookie o le richieste POST per memorizzare l'ID del designer che si desidera visualizzare, ma ciò si interromperà se qualcuno condivide il collegamento, inviandolo via mail, Facebook, Twitter o semplicemente leggendolo ad alta voce al telefono. Se non vuoi usare l'ID numerico nel tuo URL, assicurati che lo slug sia univoco: quindi prima devi cercare l'ID in base allo slug e continuare come hai fatto prima.

Quindi quello che abbiamo imparato ora è che vogliamo aggiungere una regola di riscrittura per il modello " /designers/seguito da qualcosa fino al successivo /" e salvare quel "qualcosa" nella designer_slugvariabile query. Nel tuo caso credo che tu voglia usare anche la pagina con la lumaca designerscome contenuto generale della pagina, quindi lo diremo anche a 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' );
}

L'unica cosa che resta da fare è dire a WordPress di mantenere anche designer_slugle variabili della query, in modo da poter accedere in un secondo momento. WordPress utilizza una whitelist di variabili di query consentite, per impedire alle persone di modificare ogni parametro della query di post tramite l'URL. Tutto ciò che non è in questo elenco viene ignorato. Aggancia l' query_varshook e aggiungi la tua variabile extra:

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

Come puoi vedere, questa risposta è sostanzialmente la stessa della mia precedente risposta , ma senza che la regola venga scaricata nel codice (quindi puoi usarla nel tuo tema functions.phpanziché in un plug-in) e con un po 'più di certezza e spiegazione perché ho imparato molto su come riscrivere le regole da quando (e grazie a) rispondere alla tua prima domanda.

Discussione della chat room

Abbiamo risolto i problemi finali di questa domanda nella chat room . Alla fine, Steven ha usato il generate_rewrite_rulesgancio, perché la add_rewrite_rule()funzione non sembrava funzionare per lui.


2
@Steven: pagenameè la lumaca della pagina di WordPress che si desidera visualizzare (registrare nel database). Questa pagina può quindi indicare che desidera utilizzare il designers.phpfile modello nell'area di amministrazione di WP. Quindi fai riferimento alla lumaca della pagina, non al nome del modello, poiché lo stesso modello può essere utilizzato per più pagine: in questo caso WordPress non sa cosa vuoi fare.
Jan Fabry,

1
@Steven: penso che tu abbia complicato troppo il modo in cui hai installato i ganci. Rimuovere la add_rewrite_rules()funzione e chiamare add_filter()/add_action()direttamente. Se questo si trova in un file di temi, rimuovi flush_rewrite_rules()e visita semplicemente la pagina delle impostazioni di permalink per svuotare le regole (oppure aggiungile wpse5413_init()e rimuovile in un secondo momento). E il mio plugin mostra le attuali regole di riscrittura. Ricorda che ciò cambia solo il modo in cui vengono gestiti gli URL in entrata, non il modo in cui il tuo codice scriverà gli URL nell'HTML.
Jan Fabry,

1
@Steven: non penso nemmeno che tu debba premere il pulsante Salva, anche solo l'apertura della pagina dei permalink lo scaricherà. E ancora, questo aggiungerà solo la capacità di WordPress di accettare gli /designers/designer-slug/URL, è necessario modificare i luoghi in cui si scrivono questi URL nel proprio HTML. Provalo andando /designers/Batlak-og-Selvig/da solo, se funziona, trova tutti i luoghi che generano questi URL e modificali per utilizzare la nuova struttura.
Jan Fabry,

1
Ah, ora penso di iniziare a udnerstand. Ho pensato che le regole di riscrittura avrebbero cambiato il modo in cui l'URL veniva eliminato nel campo URL del browser. Ma ciò che significa è che devo effettivamente generare l'URL www.mysite.com/batlat-og-selvig/9e quindi questo è "tradotto" in/?designer=Batlak-og-Selvig&bid=9
Steven

1
@Steven: Sì, infatti: le regole di riscrittura gestiscono i collegamenti in entrata e (solo in alcuni casi selezionati) non influiscono sui collegamenti generati nel tuo codice.
Jan Fabry,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.