Dove è meglio utilizzare add_filter
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?

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 perwp_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.

+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.
