Dove è meglio utilizzare add_filter

12 gen 2013, 07:23:45
Visualizzazioni: 30.3K
Voti: 15

Dovrei utilizzare la funzione add_filter nell'hook action init del mio plugin o semplicemente nello script principale del plugin?

A volte ho notato che le persone utilizzano i filtri ovunque e se li metto nell'hook init, potrebbe essere troppo tardi per alcuni casi.

Ci sono consigli generali sulla precedenza degli hook action e filter in modo da poter avere uno stile di codice più consistente?

0
Tutte le risposte alla domanda 1
1
18

add_filter() e add_action() sono disponibili prima che qualsiasi plugin venga caricato. Quindi puoi usarli entrambi nella prima riga del tuo plugin o tema.

Per migliorare la leggibilità, consiglio di raggruppare le registrazioni di azioni e filtri all'inizio del tuo file principale:

  • in un plugin, il file con l'intestazione del plugin
  • in un tema il functions.php

Ci sono eccezioni a questa regola:

  • Callback concatenati. In questo esempio registro un'azione per shutdown solo quando il primo filtro per wp_nav_menu_objects è stato chiamato. Quindi il secondo callback non può essere registrato allo stesso momento del primo.
  • Stile OOP. A volte devi impostare i membri della classe prima di poter registrare i callback. Usando un esempio molto simile ...

    add_action(
        'plugins_loaded',
        array ( T5_Plugin_Class_Demo::get_instance(), 'plugin_setup' )
    );
    class T5_Plugin_Class_Demo
    {
        public function plugin_setup()
        {
            $this->plugin_url    = plugins_url( '/', __FILE__ );
            $this->plugin_path   = plugin_dir_path( __FILE__ );
            $this->load_language( 'plugin_unique_name' );
    
            // altre operazioni: registra azioni e filtri
        }
    }
    

    ... vediamo che l'istanza della classe può essere interrotta da un altro plugin, e una classe figlia potrebbe registrare più filtri e azioni o diversi.

Oltre al raggruppamento, puoi fare un ulteriore passo avanti e offrire un'azione personalizzata per rendere più semplici le personalizzazioni per altri sviluppatori.
Ecco un esempio da un tema su cui sto lavorando:

add_action( 'activate_header',      't5_activate_screen' );
// wp_loaded è troppo tardi, il personalizzatore di WP non rileverebbe le funzionalità.
add_action( 'after_setup_theme',    't5_setup_custom_background' );
add_action( 'after_setup_theme',    't5_setup_custom_header' );
add_filter( 'body_class',           't5_enhance_body_class' );
add_action( 'comment_form_before',  't5_enqueue_comment_reply' );
add_action( 'content_before',       't5_frontpage_widget' );
add_action( 'footer_before',        't5_loop_navigation' );
add_action( 'get_the_excerpt',      't5_excerpt_clean_up', 1 );
add_action( 'header_before',        't5_skiplink', 0, 0 );
add_filter( 'the_title',            't5_fill_empty_title', 20, 1 );
add_action( 'wp_enqueue_scripts',   't5_enqueue_style' );
add_action( 'wp_enqueue_scripts',   't5_enqueue_script' );
add_action( 'wp_loaded',            't5_setup' );
add_action( 'wp_loaded',            't5_page_enhancements' );
add_action( 'wp_loaded',            't5_post_format_support' );
add_action( 'wp_loaded',            't5_load_theme_language' );
add_action( 'wp_loaded',            't5_setup_sidebars' );
add_filter( 'wp_nav_menu_items',    't5_customize_top_menu', 10, 2 );
add_filter( 'wp_nav_menu_args',     't5_nav_menu_args', 10, 1 );
add_filter( 'wp_title',             't5_wp_title_filter', 20, 2 );

add_shortcode( 'gallery',    't5_shortcode_gallery' );
add_shortcode( 'wp_caption', 't5_shortcode_img_caption' );
add_shortcode( 'caption',    't5_shortcode_img_caption' );

// Usa questa azione per deregistrare azioni e filtri del tema.
do_action( 't5_theme_hooks_registered' );

L'ultima riga è importante: un tema figlio o un plugin ora possono agganciarsi all'azione t5_theme_hooks_registered e deregistrare qualsiasi hook precedente. Questo eviterà di combattere con le priorità, e sono libero di cambiare le priorità delle mie callback in qualsiasi momento.

Ma non affidarti solo all'ordine del codice sorgente. Documenta gli hook che stai usando nel tuo blocco di documentazione. Uso un tag personalizzato wp-hook per questo. Ecco un esempio con hook concatenati dallo stesso tema:

/**
 * Registra il gestore per l'estratto auto-generato.
 *
 * @wp-hook get_the_excerpt
 * @param   string $excerpt
 * @return  string
 */
function t5_excerpt_clean_up( $excerpt )
{
    if ( ! empty ( $excerpt ) )
        return $excerpt;

    add_filter( 'the_content', 't5_excerpt_content' );

    return $excerpt;
}
/**
 * Rimuove parti dall'estratto auto-generato.
 *
 * @wp-hook the_content
 * @param   string $content
 * @return  string
 */
function t5_excerpt_content( $content )
{
    remove_filter( current_filter(), __FUNCTION__ );

    return preg_replace( '~<(pre|table).*</\1>~ms', '', $content );
}

Non devi scorrere verso l'alto per vedere dove queste funzioni sono chiamate, basta un'occhiata al blocco di documentazione. Questo richiede un po' di sforzo, perché devi mantenere sincronizzati sia la registrazione che il commento, ma a lungo andare fa risparmiare tempo prezioso.

12 gen 2013 08:08:49
Commenti

+1. Per lo "stile OOP", la mia preferenza è invece quella di delegare il controllo alla classe/oggetto che poi registra azioni/filtri nel suo costruttore (o più tardi se appropriato). Fornisce un migliore incapsulamento (OOP!) e differisce la registrazione degli hook fino a quando la classe viene utilizzata/istanziata.

webaware webaware
12 gen 2013 08:25:18