Come intercettare script già localizzati


10

Se un plugin utilizza alcuni script (esempio di spicco: jQuery UI Datepicker), ma non sei soddisfatto del modo in cui lo script esegue il rendering dell'output, allora ci sono due possibilità:

1. Annullare la registrazione dello script> Aggiungi la tua versione

Quindi, prima avresti bisogno di controllare la maniglia, poi trovare la priorità e il gancio ( wp_enqueue_scripts, login_enqueue_scripts, ecc) ... sapete di cosa parlo.

2. Modificare i parametri del plug-in jQuery

Normalmente - se il plugin non è una schifezza - passa attraverso i parametri da PHP a JS usando

wp_localize_script( $handle, $object_name, array( 
    // data
) );

Ora questo è un modo intelligente di aggiungere i tuoi dati a uno script JS, ma ... non è filtrabile per impostazione predefinita. Né WP_ScriptsWP_Dependenciesofferte eventuali utenti di filtro possono poi utilizzare

Domanda: Come possiamo filtrare gli argomenti / parametri che vengono spostati da PHP a Javascript usando wp_localize_script?

Risposte:


9

wp_localize_script()chiama il metodo localize()sulla variabile globale $wp_scripts. Possiamo impostare questa variabile su un'istanza di una classe figlio di WP_Scripts:

class Filterable_Scripts extends WP_Scripts
{
    function localize( $handle, $object_name, $l10n )
    {
        $l10n = apply_filters( 'script_l10n', $l10n, $handle, $object_name );
        return parent::localize($handle, $object_name, $l10n);
    }
}

add_action( 'wp_loaded', function() {
    $GLOBALS['wp_scripts'] = new Filterable_Scripts;
});

Il personalizzatore del tema non lo utilizza, crea un'istanza separata di WP_Scripts(vedi wp-admin/customize.php). Potrebbe essere possibile sostituire anche quello:

add_action( 'customize_controls_init', function() {
    $GLOBALS['wp_scripts'] = new Filterable_Scripts;
    $GLOBALS['wp_scripts']->registered = $GLOBALS['registered'];
});

Niente di tutto questo è stato testato, solo un'idea.


Potresti specificare cosa è $ l10n? Capisco passandogli la maniglia e l'oggetto, ma non $ l10n. Grazie.
Eric Leroy,

1
@EricLeroy È il terzo parametro di wp_localize_script(): un array singolo o multidimensionale .
fuxia

Questa implementazione mi ha aiutato moltissimo, ma voglio avvertirti che ha rovinato i miei script di amministrazione alla grande, ACF ha smesso di funzionare perché i javascript non sono stati stampati a causa della soluzione sopra. Non ho ancora una soluzione, ma la sto cercando ora.
Ogier Schelvis,

4

@toscho ottima implementazione. Testato e vero. Ecco una versione leggermente modificata, che passa anche $ handle e $ object_name in modo da poter filtrare solo quando necessario.

class Filterable_Scripts extends WP_Scripts
{
    function localize( $handle, $object_name, $l10n )
    {
        $l10n = apply_filters( 'script_l10n', $l10n, $handle, $object_name );
        return parent::localize($handle, $object_name, $l10n);
    }
}

add_action( 'init', function() {
    $GLOBALS['wp_scripts'] = new Filterable_Scripts;
});

add_filter('script_l10n', 'se108362_example_filter', 10 , 3);

// Example
function se108362_example_filter($l10n, $handle, $object_name ) {
    if('js-handle' == $handle && 'jsVariable' == $object_name) {
       return 'Something Else';
    }
    return $l10n;
}

1

La risposta accettata è fantastica! Ma ho riscontrato un problema per cui i campi personalizzati avanzati hanno smesso di funzionare nel backend a causa di un errore JavaScript. Dopo aver scavato per alcune ore sono giunto alla conclusione che all'oggetto Filterable_Scripts mancavano i file javascript registrati dal plug-in ACF. Non so esattamente perché lo abbia fatto, ma ho trovato una soluzione adeguata a questo se riscontri lo stesso problema.

La $GLOBALS['wp_scripts']fortuna ancora conteneva gli script corretto. Quindi ho fatto quanto segue in add_action:

add_action( 'wp_loaded', function() {
    $fscripts = new Filterable_Scripts();

    $missing_scripts = array_diff_key( $GLOBALS['wp_scripts']->registered, $fscripts->registered);
    foreach($missing_scripts as $mscript){
        $fscripts->registered[$mscript->handle] = $mscript;
    }

    $GLOBALS['wp_scripts'] = $fscripts;
});

Poiché l'oggetto contiene una matrice di tutti gli script registrati e le maniglie sono anche le chiavi della matrice, potrei usare array_diff_key per determinare quali script mancavano dall'oggetto esteso e aggiungerli nuovamente. L'ho fatto e non solo

$fscripts->registered = $GLOBALS['wp_scripts']->registered;

perché non volevo sovrascrivere le modifiche apportate dall'oggetto esteso.


1
Ho avuto un altro modo per farlo, che era quello di aggiungere salvare i due tag script acf $acf_field_group = $GLOBALS['wp_scripts']->registered['acf-field-group'];(anche acf-input) e quindi aggiungerli di nuovo all'istanza del WP_Scriptstag esteso :, $GLOBALS['wp_scripts']->registered['acf-field-group'] = $acf_field_grouppoi ho capito che ACF sta usando solo gli script all'interno di Admin e sono solo l10ndi fronte, quindi ho appena concluso l'azione e il filtro in un !is_admintest.
MikeiLL,

Bene, dal punto di vista delle prestazioni la tua soluzione funziona meglio. Sto anche aggiungendo il controllo is_admin alla mia versione personale di questo codice. La cosa che mi piace ancora del mio approccio è che se l'ID degli script dovesse cambiare in futuro o ci fossero nuovi script mancanti nelle versioni successive del plug-in ACF (o altri plug-in), non devo cambiare il mio codice.
Ogier Schelvis,

Sì, questo ha senso anche per me. Non sono sicuro che sia necessario se si esegue solo l'azione sul front-end.
MikeiLL,

Hmm .. touché. Immagino che a volte mi faccia prendere così tanto dalla ricerca della soluzione perfetta che mi dimentichi quale fosse il problema iniziale. Tuttavia, se la necessità nell'amministratore potrebbe mai cambiare, abbiamo già fatto i calcoli ;-)
Ogier Schelvis,

Lo stesso qui, amico, ma si tratta di imparare, no?
MikeiLL,
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.