Comprendere add_rewrite_rule

31 dic 2016, 01:34:12
Visualizzazioni: 52.3K
Voti: 21

Sto cercando di far funzionare add_rewrite_rule per estrarre un parametro dall'URL e passarlo attraverso la richiesta. Ho visto diversi post su questo argomento, ma non riesco a farlo funzionare.

Se un URL inizia con una determinata stringa, vorrei rimuoverla dall'URL e passarla come parametro di query.

URL di esempio della richiesta:

http://domain.com/foo/my_page

Questo verrebbe trasformato in:

http://domain.com/my_page?param=foo

Se 'foo' non è presente, dovrebbe essere gestito come una normale richiesta. Questa logica dovrebbe applicarsi a qualsiasi URL di pagina o URL di custom post type sul mio sito (praticamente foo/*). Penso che dovrebbe funzionare come un pass through: se l'URL ha 'foo', lo rimuove e poi lo passa a WordPress per gestirlo normalmente.

Ho già inserito 'param' tra le query_vars consentite.

In totale, dovrebbe funzionare per i seguenti casi:

  • /foo/my_page (Pagina)
  • /foo/my_folder/my_page (Sotto-pagina)
  • /foo/example_type (Archivio Custom Post)
  • /foo/example_type/example_post (Custom Post Singolo)
2
Commenti

qualsiasi URL, quindi post, categorie, tag, ecc., non solo il tipo di post page, o semplicemente qualsiasi pagina? e le pagine genitore/figlio nella gerarchia?

Milo Milo
31 dic 2016 02:05:08

@Milo Ho chiarito questo punto per te. Sto utilizzando solo pagine e tipi di post personalizzati (pagine di archivio e singole).

Louis W Louis W
31 dic 2016 02:07:00
Tutte le risposte alla domanda 2
8
17

Una regola di base che funzionerebbe per il tuo esempio:

function wpd_foo_rewrite_rule() {
    add_rewrite_rule(
        '^foo/([^/]*)/?',
        'index.php?pagename=$matches[1]&param=foo',
        'top'
    );
}
add_action( 'init', 'wpd_foo_rewrite_rule' );

Questo prende qualsiasi cosa venga dopo foo/ e lo imposta come pagename per la query, mentre param riceve il valore statico foo. Se hai bisogno di diversi schemi di URL, dovrai aggiungere regole extra per ogni schema unico. Fai riferimento alla documentazione di WP_Query per le varie variabili di query che possono essere impostate nelle regole di riscrittura. Non dimenticare di svuotare le regole di riscrittura dopo averne aggiunte di nuove. Puoi farlo visitando la pagina delle Impostazioni dei Permalink.

Ora visitando il tuo URL di esempio:

http://domain.com/foo/my_page

caricherà la pagina corretta, ma non si comporterà esattamente come visitare:

http://domain.com/my_page?param=foo

perché quando si usano riscritture interne, param è impostato all'interno dell'oggetto query $wp_query, non nel superglobale $_GET. Se hai bisogno di lavorare con codice che cerca un valore in $_GET, dovrai un passaggio aggiuntivo per impostare quel valore:

function wpd_foo_get_param() {
    if( false !== get_query_var( 'param' ) ){
        $_GET['param'] = get_query_var( 'param' );
    }
}
add_action( 'parse_query', 'wpd_foo_get_param' );

Un altro metodo da considerare è l'uso degli endpoint, in modo che /foo/ sia alla fine degli URL anziché come prefisso. Il vantaggio è che l'API add_rewrite_endpoint semplifica l'aggiunta di tutte le regole necessarie, inclusa l'abilitazione della paginazione.

2 gen 2017 05:15:52
Commenti

Grazie per la spiegazione dettagliata. Sembra funzionare per le pagine, ma mi dà un errore 404 per gli URL degli archivi e delle singole pagine di post personalizzati.

Louis W Louis W
2 gen 2017 06:51:46

Beh sì, come ho detto, devi aggiungere regole aggiuntive che corrispondano a ciascuno di quei pattern. Non so come siano strutturati quegli URL nel tuo setup.

Milo Milo
2 gen 2017 09:00:13

Ho un tipo di pagina personalizzata chiamato 'projects' che ha archivi e pagine singole. Puoi fornirmi un esempio per quello, così posso creare tutti gli altri.

Louis W Louis W
2 gen 2017 18:50:49

Inoltre, non sembra funzionare per le sotto-pagine.

Louis W Louis W
2 gen 2017 20:59:03

Esatto, funziona solo per il singolo esempio specifico che ho menzionato sopra, ed è per questo che alla fine suggerisco di utilizzare un endpoint invece. Se vuoi gestire vari livelli di sotto-pagine, archivi con impaginazione, singoli articoli, ecc., finirai per dover aggiungere molte regole. Questo plugin di analisi rewrite ti aiuterà a vedere come le regole vengono interpretate nelle query vars, e potrebbe darti alcuni suggerimenti su come costruire regole aggiuntive.

Milo Milo
3 gen 2017 00:08:39

Scusa, l'endpoint non funzionerà perché ho bisogno che la variabile sia all'inizio dell'URL. Non voglio essere difficile, ma non posso accettare questa come soluzione finché non soddisfa i requisiti indicati nel post originale, che includono archivi/singoli di custom post e (anche se non esplicitamente) dovrebbe funzionare per le sotto-pagine (foo/*).

Louis W Louis W
3 gen 2017 00:25:18

Modifica la tua domanda per aggiungere un esempio di ogni schema URL che necessita di una regola. Non sono realmente preoccupato che la mia risposta venga accettata, a volte riesco a far sì che le persone rispondano da sole alle loro domande fornendo loro qualcosa con cui iniziare.

Milo Milo
3 gen 2017 02:15:12

Sono stati aggiunti degli esempi.

Louis W Louis W
3 gen 2017 04:09:42
Mostra i restanti 3 commenti
1

Ok, ho ottenuto esempi funzionanti per tutti e 3 i tipi di richieste. Ci è voluto un sacco di sperimentazione e tentativi per farli funzionare. Immagino che Milo sia bravo a spingere le persone a rispondere alle proprie domande.

Dopo innumerevoli modifiche e ricaricamenti dei permalink, ho capito che era molto più semplice capire gli url al di fuori di add_rewrite_url e una volta che funzionavano, definire la riscrittura. Ad esempio index.php?param=foo&post_type=example_type.

Un'altra cosa ovvia, ma la aggiungo qui perché potrebbe aiutare qualcun altro. È necessario definire le regole add_rewrite_rule per i custom post type PRIMA di definire le regole con i caratteri jolly per le pagine/sotto-pagine. Ho perso un bel po' di tempo con questo e penso sia stata la cosa principale che mi ha impedito di capire perché le regole non funzionassero.

Ecco le 3 regole che funzionano per tutte le mie esigenze. La regola per Pagina/Sotto-Pagina è stata combinata in una sola.

// Archivio Custom Post
add_rewrite_rule(
    '^foo/example_type/?$',
    'index.php?param=foo&post_type=example_type',
    'top'
    );

// Custom Post Singolo
add_rewrite_rule(
    '^foo/example_type/([^/]*)/?$',
    'index.php?param=foo&example_type=$matches[1]',
    'top'
    );

// Pagine, Principali e Sotto-Pagine
// Questa DEVE essere posizionata nel codice DOPO le add_rewrite_rule per i custom post
add_rewrite_rule(
    '^foo/(.+)/?$',    
    'index.php?param=foo&pagename=$matches[1]',
    'top'
    );

Inoltre ho impostato un ciclo per aggiungere regole per più custom post type. Ricorda, devi definire le regole add_rewrite_rule per i custom post type PRIMA di definire le regole con i caratteri jolly per le pagine/sotto-pagine.

$custom_types = array('example_type', 'projects', 'people');

foreach($custom_types as $type) {

    // Archivio Custom Post
    add_rewrite_rule(
        '^foo/'.$type.'/?$',
        'index.php?param=foo&post_type='.$type,
        'top'
        );

    // Custom Post Singolo
    add_rewrite_rule(
        '^foo/'.$type.'/([^/]*)/?$',
        'index.php?param=foo&'.$type.'=$matches[1]',
        'top'
        );

}

L'Rewrite Analyzer che Milo ha condiviso è stato molto utile per capire meglio come WordPress esegue le query per pagine/post.

5 gen 2017 17:51:59
Commenti

Mi unisco in ritardo, ma posso chiederti un altro esempio? Tieni presente che non capisco assolutamente il parametro $tag di add_rewrite_rule. Non ho idea di cosa significhi. Né capisco l'esempio che usa pagename=$matches[1]'. HUH??? Ho un URL come domain.com/detail?id=2&it=3. Vorrei che la pagina fosse domain.com/detail/2-3/. Sei disponibile?

Debbie Kurth Debbie Kurth
10 nov 2019 10:52:42