Blog

Arhitectura Hook-urilor WordPress: Acțiuni vs. Filtre Explicate

Fundația fiecărui plugin grozav. Aflați cum PAGEnza AI folosește hook-uri și filtre pentru a crea cod mentenabil și scalabil.

Fiecare plugin WordPress face una din două lucruri: rulează cod la un moment specific (acțiune) sau modifică o valoare înainte ca aceasta să fie utilizată (filtru). Asta e tot. Întregul ecosistem de plugin-uri WordPress este construit pe această distincție.

Înțelegerea diferenței — și când să folosești fiecare — este ceea ce separă plugin-urile care funcționează de plugin-urile care cauzează probleme.

Acțiuni: fac ceva la un moment dat

Un hook de acțiune este un semnal pe care WordPress (sau un alt plugin) îl trimite la un moment specific. Atașezi o funcție la acel semnal, iar funcția ta rulează când semnalul este declanșat.

add_action( 'wp_enqueue_scripts', 'my_plugin_load_assets' );

function my_plugin_load_assets() {
    wp_enqueue_style( 'my-plugin', plugin_dir_url( __FILE__ ) . 'style.css' );
    wp_enqueue_script( 'my-plugin', plugin_dir_url( __FILE__ ) . 'script.js', ['jquery'], '1.0', true );
}

wp_enqueue_scripts este declanșat atunci când WordPress se pregătește să încarce resurse pentru partea frontală. Atașarea la acesta este modalitatea corectă de a încărca CSS și JS — nu de a insera etichete <script> direct în șabloane.

Hook-uri de acțiune comune pe care le veți folosi constant:

  • init — rulează devreme, bun pentru înregistrarea tipurilor de postări și a taxonomiilor
  • wp_enqueue_scripts — încarcă resurse pentru partea frontală
  • admin_enqueue_scripts — încarcă resurse pentru partea de administrare
  • save_post — rulează când o postare este salvată, bun pentru procesarea câmpurilor personalizate
  • wp_ajax_{action} — gestionează cererile AJAX de la utilizatori autentificați
  • wp_ajax_nopriv_{action} — gestionează cererile AJAX de la utilizatori nelogați

Filtre: modifică o valoare înainte ca aceasta să fie utilizată

Un hook de filtru îți oferă o valoare, îți permite să o modifici și se așteaptă să returnezi versiunea modificată. WordPress folosește apoi valoarea ta modificată în loc de cea originală.

add_filter( 'the_content', 'my_plugin_append_cta' );

function my_plugin_append_cta( $content ) {
    if ( ! is_single() ) {
        return $content;
    }
    $cta = '<div class="post-cta">Gata să încerci PAGEnza? <a href="#">Începe gratuit →</a></div>';
    return $content . $cta;
}

Regula critică: returnează întotdeauna ceva dintr-un filtru. Dacă uiți return, valoarea devine null și ai stricat tot ce o folosea.

Hook-uri de filtru comune:

  • the_content — conținutul postării înainte de afișare

  • the_title — titlul postării

  • wp_nav_menu_items — HTML pentru meniul de navigație

  • upload_mimes — tipuri de fișiere permise la încărcare

  • plugin_action_links_{plugin-file} — link-uri afișate pe pagina listei de plugin-uri

Cum folosește PAGEnza AI hook-urile

Când Plugin Builder generează un plugin, structurează codul în jurul unei clase cu metode atașate la hook-uri în constructor. Acest model evită coliziunile de nume de funcții globale și menține codul organizat.

class My_Plugin {
    public function __construct() {
        add_action( 'init', [ $this, 'register_post_type' ] );
        add_action( 'wp_enqueue_scripts', [ $this, 'load_assets' ] );
        add_filter( 'the_content', [ $this, 'append_content' ] );
    }

    public function register_post_type() { /* ... */ }
    public function load_assets() { /* ... */ }
    public function append_content( $content ) {
        // returnează întotdeauna
        return $content;
    }
}

new My_Plugin();

Scanarea de securitate verifică în mod specific dacă gestionarii AJAX includ atât o verificare a nonce-ului, cât și o verificare a permisiunilor înainte de a face orice:

add_action( 'wp_ajax_my_action', [ $this, 'handle_ajax' ] );

public function handle_ajax() {
    // Securitate: verifică nonce-ul
    check_ajax_referer( 'my_nonce_action', 'nonce' );

    // Securitate: verifică permisiunile
    if ( ! current_user_can( 'manage_options' ) ) {
        wp_send_json_error( 'Permisiuni insuficiente', 403 );
    }

    // Acum este sigur de procesat
    $data = sanitize_text_field( $_POST['data'] ?? '' );
    wp_send_json_success( [ 'result' => $data ] );
}

Lipsa oricăruia dintre acestea este marcată ca o problemă de securitate și blochează lansarea plugin-ului.

Prioritate și coada de hook-uri

Când mai multe funcții sunt atașate la același hook, ele rulează în ordinea priorității (număr mai mic = rulează primul). Prioritatea implicită este 10.

add_action( 'init', 'runs_first', 5 );
add_action( 'init', 'runs_second', 10 );   // implicit
add_action( 'init', 'runs_last', 20 );

Acest lucru contează atunci când plugin-ul tău trebuie să ruleze înainte sau după codul altui plugin. Dacă modifici ceva ce alt plugin modifică, prioritatea controlează cine câștigă.

Un model comun: dacă suprascrii un filtru al temei, folosește prioritatea 20 sau mai mare pentru a te asigura că rulezi după codul temei.

Eliminarea hook-urilor

Poți elimina un hook pe care l-a adăugat altcineva — inclusiv hook-uri de temă și plugin:

remove_action( 'wp_head', 'wp_generator' );  // elimină versiunea WP din <head>
remove_filter( 'the_content', 'wpautop' );   // elimină împachetarea automată în paragrafe

Capcana: poți elimina un hook doar dacă apelezi remove_action/remove_filter după ce add_action/add_filter original a rulat. Acest lucru înseamnă, de obicei, atașarea eliminării tale la o acțiune ulterioară.