Dove, quando e come scaricare correttamente le regole di riscrittura nell'ambito di un plug-in?


10

Sto riscontrando un problema un po 'strano con le regole di riscrittura che non funzionano correttamente.

Ho provato a usare flush_rewrite_rules();e flush_rewrite_rules(true);.

Ho anche provato a globalizzare $wp_rewriteusando $wp_rewrite->flush_rules();e$wp_rewrite->flush_rules(true);

Nessuno dei due sembra svuotare correttamente le regole di riscrittura. Quelle chiamate stanno effettivamente svuotando le regole di riscrittura quando vengono chiamate. Come faccio a saperlo? Utilizzando la soluzione per il debug risciacquo flushing delle regole .

Attualmente, ho riscritto le regole scaricate sull'attivazione e la disattivazione del plugin. Nessun problema lì.

Ho una pagina delle impostazioni di amministrazione del plugin per gli utenti per configurare il plugin. Alcune impostazioni regolano la struttura del permalink, pertanto è necessario scaricare le regole di riscrittura nella pagina delle impostazioni di amministrazione del plug-in "Salva impostazioni". (Utilizza lo standard update_option();) per il salvataggio delle impostazioni.

Vorrei sottolineare che, a seconda delle impostazioni specificate, vengono creati tipi di posta personalizzati in base alle impostazioni specificate dall'utente. Pertanto, le regole di riscrittura devono essere scaricate immediatamente dopo il salvataggio delle impostazioni. Questo è dove le cose non funzionano in modo appropriato.

La soluzione di collegamento sopra per il debug delle regole di riscrittura fornita da @toschosta mostrando che sta scaricando tonnellate di regole di riscrittura. Tuttavia, quando si visita l'elemento singolare del tipo di post personalizzato, o addirittura l'archivio del tipo di post personalizzato, ognuno restituisce come errori 404.

Il tipo di post personalizzato è registrato correttamente e in modo appropriato. So per certo che non è questo il problema.

Immediatamente dopo con il salvataggio delle impostazioni della pagina di amministrazione del plugin. Vengono creati i tipi di post personalizzati, la struttura del permalink viene modificata e si tenta di svuotare tutte le regole di riscrittura.

I tipi di post personalizzati vengono quindi caricati sempre e caricati initcome al solito.

Per qualche ragione, le regole di riscrittura non stanno scaricando correttamente, perché come ho detto prima, visitando sezioni singole o di archivio del tipo di post personalizzato restituisce errori 404.

Ora la parte strana, se tutto ciò che faccio è semplicemente visitare la pagina delle impostazioni dei permalink di amministrazione e quindi tornare al front-end per visualizzare sezioni singole o di archivio del tipo di post personalizzato, funzionano magicamente come previsto.

Che cosa fa quella pagina delle impostazioni dei permalink di amministrazione che non sto facendo che consente alle regole di riscrittura di svuotare in modo appropriato e il mio no?

Voglio dire, come soluzione temporanea, sto reindirizzando l'utente alla pagina delle impostazioni dei permalink di amministrazione dopo aver salvato la pagina delle impostazioni di amministrazione del plug-in, ma questa non è una soluzione ideale. Preferirei che le regole di riscrittura si scarichino correttamente nel codice del mio plugin.

C'è un certo punto in WordPress in cui svuotare le regole di riscrittura non scarica più TUTTE le regole?

admin_menu - La pagina delle impostazioni del plugin viene aggiunta all'amministrazione di WordPress.

add_options_page() - La pagina delle impostazioni del plugin viene aggiunta nel menu Impostazioni.

La pagina delle impostazioni viene visualizzata nel callback per add_options_page(). Questo è anche il punto in cui $_POSTviene elaborato per aggiornare le impostazioni del plug-in e svuotare le regole di riscrittura.

Dal momento che questa è già una lunga domanda, sarei disposto a fornire blocchi di codice (se aiuta) in un collegamento fuori sede che aiuta a produrre una risposta valida.


1
sembra che forse hai sbagliato l'ordine delle cose, è difficile dirlo senza vedere un po 'di codice. la pagina di amministrazione di permalink chiama solo flush_rewrite_rules, che elimina solo l' rewrite_rulesopzione e la rigenera, puoi aprire il file wp-admin/options-permalinks.phpe vedere dove questo accade. poiché questa operazione elimina l'intera opzione, non è possibile svuotare parzialmente le regole.
Milo,

@Milo Penso che tu abbia ragione. Ho una classe che viene caricata su initcui registra i tipi di posta. Ho pensato, le impostazioni della pagina venivano salvate e la pagina si sarebbe ricaricata ... quindi sparando di initnuovo il gancio per registrare i tipi di post necessari. Quindi ho pensato che i tipi di post sarebbero già stati caricati, e tutto ciò che dovevo fare era aggiornare l'opzione, quindi svuotare le regole di riscrittura dalla mia pagina delle impostazioni del plugin. Pubblicherò una risposta su come ho trovato una soluzione.
Michael Ecklund,

Solo un avviso flush_rewrite_rules () nel mio plugin ha finito per essere parte del problema per me. Ho eliminato l'hook php e ho finito per aggiornare manualmente i permalink e i miei errori CPT 404 sono scomparsi.
myol,

Risposte:


4

Il posto migliore per scaricare le regole di riscrittura è l'attivazione / disattivazione del plugin.

function myplugin_activate() {
    // register taxonomies/post types here
    flush_rewrite_rules();
}

register_activation_hook( __FILE__, 'myplugin_activate' );

function myplugin_deactivate() {
    flush_rewrite_rules();
}
register_deactivation_hook( __FILE__, 'myplugin_deactivate' );

Vedi l'articolo sul codice

Mi scuso in anticipo, non ho superato la tua domanda, quindi questa è una risposta da cookie cutter.


1
Grazie per il tuo suggerimento, ma ne sono consapevole. Il problema non riguarda l'attivazione / la disattivazione del plugin. Ha a che fare con gli utenti che cambiano le impostazioni nel plug-in già attivo, che regola le regole di riscrittura, richiedendo quindi un flush.
Michael Ecklund,

1
Ho pensato che potesse essere il caso, ma ero piuttosto stanco quando stavo leggendo la tua domanda. La soluzione di ialocin sembra promettente, spero che tu l'abbia risolto.
Helgatheviking

4

Difficile dire cosa c'è che non va, senza vedere il tuo codice. Ma dopo aver salvato alcune impostazioni è pratico agganciarsi admin_initcome mostrato di seguito per svuotare le regole di riscrittura.

Codice:

add_action('admin_init', 'wpse_123401_plugin_settings_flush_rewrite');
function wpse_123401_plugin_settings_flush_rewrite() {
    if ( get_option('plugin_settings_have_changed') == true ) {
        flush_rewrite_rules();
        update_option('plugin_settings_have_changed', false);
    }
}


Devi impostare l'opzione in qualche punto nella tua pagina delle impostazioni o per essere esatti in qualche parte nel processo di salvataggio delle impostazioni. Farlo senza l'opzione è negativo, perché non si desidera svuotare le regole ogni volta.


Nota: non testato


2
O potresti usare un transitorio forse? Ma sicuramente +1 per non aver scaricato le regole su ogni admin_init.
Helgatheviking

Ovviamente hai ragione sul transitorio, immagino di aver optato per la *_option()pagina delle impostazioni. @helgatheviking
Nicolai,

Questo è stato molto utile. Ho avuto una situazione simile a Michael. Ho finito per incorporare il suggerimento di Helga sull'uso di un transitorio e l'ho impostato nella funzione di validazione per le impostazioni. Ho finito per aver bisogno di impostare il transitorio su false dopo aver scaricato o altrimenti ha continuato a scaricarsi su ogni caricamento della pagina di amministrazione fino alla scadenza del transitorio. Quindi utilizzare funzionalmente un'opzione o un transitorio era lo stesso. Immagino che il transitorio potrebbe essere utile solo per mantenere un po 'più pulita la tabella delle opzioni. Ma un punto minore.
Matthew,

La differenza è in effetti minore, specialmente se i transitori sono permanenti, non in scadenza, ma ovviamente i transitori hanno altre capacità, benefici che sono piacevoli. @MatthewLee
Nicolai,

3

Avevo un file di classe di tipi di post che era responsabile della lettura delle impostazioni delle opzioni del plug-in e della creazione dei tipi di post personalizzati necessari in base alle impostazioni specificate dall'utente.

Questo file di classe post post è stato caricato all'hook init.

Ho pensato che tutto ciò che avrei dovuto fare fosse aggiornare le impostazioni del plugin, quindi svuotare le regole di riscrittura. Poiché la classe dei tipi di post era già stata caricata in base alle impostazioni del plug-in. Ma con le pagine di amministrazione, vengono caricate DOPO il initgancio.

I tipi di post non sono mai stati effettivamente registrati, perché le impostazioni non erano ancora state effettivamente impostate. La classe di registrazione dei tipi di posta ha terminato prematuramente senza alcun tipo di posta registrato.

La soluzione era:

  1. Aggiorna le impostazioni del plugin.
  2. Caricare il file di classe dei tipi di post SOLO una volta qui in modo da creare le nuove regole di riscrittura.
  3. Svuota le regole di riscrittura.

(In precedenza ... mancava il passaggio 2 - Come menzionato sopra ...)

D'ora in poi, i tipi di post verranno caricati initall'uncinetto e saranno già state specificate le impostazioni, consentendo la creazione e l'abbinamento dei tipi di post con le regole di riscrittura appropriate.

Per qualsiasi motivo, ho dovuto aggiungere una chiamata JavaScript per reindirizzare alla pagina corrente, dopo aver eseguito i tre passaggi precedenti.

Ho anche dovuto aggiungere una chiamata alla flush_rewrite_rules();pagina delle impostazioni di amministrazione del plugin.

Quindi, per garantire che tutto sia a filo ...

Passaggio 1) Passa alla pagina delle impostazioni di amministrazione del plug-in. - flush iniziale.

Passaggio 2) Aggiorna le impostazioni del plug-in. - Seconda vampata.

Passaggio 3) La pagina reindirizza alla pagina delle impostazioni del plug-in. Causare il ... terzo e ultimo flush (uguale al flush iniziale - Fatto automaticamente quando viene visitata la pagina delle impostazioni del plugin)

Non sto dicendo che questa è una soluzione pratica, ma ha funzionato per me. Problema molto strano e molto probabilmente ha a che fare con la mia infrastruttura di codifica.


1

@ tazo-todua questo ha funzionato anche per me quando si utilizza il multisito.

add_action( 'wpmu_new_blog', 'set_my_permalink_structure', 11, 2 );

function set_my_permalink_structure( $blog_id ) {

    switch_to_blog( $blog_id );

    global $wp_rewrite;
    $wp_rewrite->set_permalink_structure( '/%postname%/' );
    $wp_rewrite->flush_rules();
    $wp_rewrite->init();

    restore_current_blog();
}

0

LA MIA SOLUZIONE trovata ERA:

global $wp_rewrite; $wp_rewrite->flush_rules(); $wp_rewrite->init();

0

Stavo avendo esattamente lo stesso problema. Nel mio plugin, ho tipi di post creati dinamicamente. Pertanto, non possono essere registrati tramite register_post_type()un metodo statico durante il activation_hooke pertanto non sono ancora attivi quando flush_rewrite_rules()viene eseguito durante questo hook (che è normalmente il modo consigliato di svuotare le regole di riscrittura).

La soluzione più pulita che ho potuto trovare alla fine è stata svuotare le regole di riscrittura dopo la registrazione dei tipi di posta, ma ovviamente solo se tale svuotamento fosse effettivamente necessario (perché l'operazione è lenta). Nel mio caso in realtà ho diversi tipi di post personalizzati che ereditano da una singola classe di base e quindi era desiderabile implementare il codice che esegue lo svuotamento lì.

È possibile stabilire se il lavaggio sia necessario osservando l'output di get_option( 'rewrite_rules' ):

class MyPostTypeClass {

public final function register_as_custom_post_type() {
    ...   //do all the setup of your post type here     
    $args = array(
                  ... //populate the other arguments as you see fit
                  'rewrite' => array('slug' => 'slug-of-your-post-type')
                 );
    register_post_type('post-type-name-of-your-post-type', $args );

    $rewrite_rules_must_be_fluhed = true;
    foreach( get_option( 'rewrite_rules' ) as $key => $rule)
        if(strpos($key, $args['rewrite']['slug'] ) === 0)
        {
            $rewrite_rules_must_be_fluhed = false;
            break;
        }
    if($rewrite_rules_must_be_fluhed)
        flush_rewrite_rules(true);
}
}

svantaggi:

  • Si basa in una certa misura su quali regole di riscrittura esatte vengono generate da WP register_post_type().
  • Controllare se lo svuotamento è necessario durante ogni caricamento della pagina crea anche un sovraccarico.

vantaggi:

  • Completamente incapsulato nella classe che rappresenta il tipo di post.
  • Svuota le regole di riscrittura solo se veramente necessario.

Utilizzare solo questo se non è possibile registrare il tipo di messaggio in una funzione statica che può chiamare sia durante inite activation_hook!

La dipendenza da come register_post_type()appaiono le regole di riscrittura generate durante può essere mitigata sostituendo il test if(strpos($key, $args['rewrite']['slug'] ) === 0)con qualcosa di più elaborato, cioè un'espressione regolare.

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.