Si un plugin utilise un script (exemple évident: jQuery UI Datepicker), mais que vous n'êtes pas satisfait de la manière dont le script restitue la sortie, il existe alors deux possibilités:
Donc, vous devez d’abord vérifier la poignée, puis trouver la priorité et le crochet (wp_enqueue_scripts
, login_enqueue_scripts
, etc.) ... vous connaissez l’exercice.
Normalement - si le plugin n'est pas une merde - il passe à travers les paramètres de PHP à JS en utilisant
wp_localize_script( $handle, $object_name, array(
// data
) );
Maintenant, c’est un moyen astucieux d’ajouter vos données à un script JS, mais ... ce n’est pas filtrable par défaut. Ni WP_Scripts
ni WP_Dependencies
n'offre aucun des utilisateurs du filtre ne peut utiliser plus tard
Question: Comment pouvons-nous filtrer les arguments/paramètres qui sont déplacés de PHP vers Javascript à l'aide de
wp_localize_script
?
wp_localize_script()
appelle la méthode localize()
sur la variable globale $wp_scripts
. Nous pouvons définir cette variable sur une instance de child class of 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;
});
Le personnalisateur de thème ne l'utilise pas, il crée une instance distincte de WP_Scripts
(voir wp-admin/customize.php
). Il pourrait être possible de remplacer cela aussi:
add_action( 'customize_controls_init', function() {
$GLOBALS['wp_scripts'] = new Filterable_Scripts;
$GLOBALS['wp_scripts']->registered = $GLOBALS['registered'];
});
Rien de tout cela n'a été testé, juste une idée.
@toscho grande implémentation. Testé et vrai. Voici une version légèrement modifiée, qui transmet également les noms $ handle et $ object_name afin que vous puissiez filtrer uniquement lorsque cela est nécessaire.
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;
}
La réponse acceptée est super! Mais j’ai rencontré un problème en raison du fait que Advanced Custom Fields ne fonctionnait plus dans le backend à cause d’une erreur javascript. Après avoir creusé pendant quelques heures, je suis parvenu à la conclusion que l’objet Filterable_Scripts manquait des fichiers javascript enregistrés par le plugin ACF. Je ne sais pas exactement pourquoi il a agi de la sorte, mais j’ai trouvé une solution appropriée si vous rencontrez le même problème.
Heureusement, le $GLOBALS['wp_scripts']
contenait toujours les scripts appropriés. J'ai donc fait ce qui suit dans le 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;
});
Étant donné que l'objet contient un tableau de tous les scripts enregistrés et que les descripteurs sont également les clés du tableau, je pourrais utiliser array_diff_key pour déterminer les scripts manquants dans l'objet étendu et les rajouter. Je l'ai fait et pas seulement
$fscripts->registered = $GLOBALS['wp_scripts']->registered;
parce que je ne voulais pas écraser les modifications apportées par l'objet étendu.