Comprendere add_rewrite_rule
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)

Una regola di base che funzionerebbe per il tuo esempio:
function wpd_foo_rewrite_rule() {
add_rewrite_rule(
'^foo/([^/]*)/?',
'index.php?pagename=$matches[1]¶m=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.

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.

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.

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.

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.

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/*).

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.

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.

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?
