如何拦截已经本地化的脚本


10

如果插件使用某些脚本(突出示例:jQuery UI Datepicker),但是您对脚本如何呈现输出不满意,则有两种可能性:

1.取消注册脚本>添加自己的版本

因此,首先你需要检查的手柄,然后找到优先级和钩(wp_enqueue_scriptslogin_enqueue_scripts,等)......你知道该怎么做。

2.更改jQuery插件参数

通常-如果插件不是废话-它会使用以下命令将参数从PHP推送到JS

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

现在,这是一种将数据添加到JS脚本的聪明方法,但是 ...默认情况下它是不可过滤的。以后都WP_Scripts没有WP_Dependencies提供任何过滤器供用户使用

问题:我们如何使用过滤从PHP移动到Javascript的参数/参数wp_localize_script

Answers:


9

wp_localize_script()调用localize()全局变量上的方法$wp_scripts。我们可以将此变量设置为的类的实例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;
});

主题定制器没有使用它,而是创建了一个单独的实例WP_Scripts(请参阅参考资料wp-admin/customize.php)。也有可能替换掉它:

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

这些都没有经过测试,只是一个想法。


您能否说明$ l10n是多少?我知道将句柄和对象传递给它,但不是传递$ 100亿。谢谢。
Eric Leroy 2013年

1
@EricLeroy它是以下各项的第三个参数wp_localize_script()单维或多维数组
fuxia

此实现对我很有帮助,但是我想警告您,它使我的管理脚本混乱了很多,ACF停止工作,因为上述解决方案未打印JavaScript。我还没有修复程序,但现在正在寻找它。
Ogier Schelvis,

4

@toscho很好的实现。经过测试和真实。这是一个经过稍微修改的版本,它还传递了$ handle和$ object_name,因此您只能在需要时进行过滤。

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

接受的答案很棒!但是我遇到一个问题,由于JavaScript错误,高级自定义字段在后端停止工作。经过几个小时的研究,我得出的结论是Filterable_Scripts对象缺少ACF插件注册的javascript文件。我不知道为什么会这样做,但是如果遇到相同的问题,我已经找到了解决这个问题的合适方法。

$GLOBALS['wp_scripts']幸好仍然包含正确的脚本。所以我在下面做了以下事情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;
});

因为对象包含所有已注册脚本的数组,并且句柄也是数组键,所以我可以使用array_diff_key来确定扩展对象中缺少哪些脚本,然后重新添加它们。我做到了,而不仅仅是

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

因为我不想覆盖扩展对象所做的任何更改。


1
我还有另一种方法,即添加保存两个acf脚本标签$acf_field_group = $GLOBALS['wp_scripts']->registered['acf-field-group'];(也为acf-input),然后将它们再次添加到扩展WP_Scripts标签的实例中:$GLOBALS['wp_scripts']->registered['acf-field-group'] = $acf_field_group,然后意识到ACF仅使用Admin中的脚本,而我只l10n在前面,所以只需将动作和过滤器包装在!is_admin测试中即可。
MikeiLL

好点,性能方面,您的解决方案效果更好。我还将is_admin检查添加到此代码的个人版本中。我仍然喜欢我的方法的事情是,如果脚本的ID将来要更改,或者在更高版本的ACF插件(或其他插件)中缺少新的脚本,则不必更改我的脚本。码。
Ogier Schelvis,

是的,这对我也很有意义。我不确定如果只在前端运行操作是否有必要。
MikeiLL

嗯..touché。我想有时候我在寻找完美解决方案时会被很多事情困扰,而忘记了最初的问题到底是什么。但是,如果管理员的需求可能会改变,我们已经进行了数学计算;-)
Ogier Schelvis

朋友,在这里也一样,但这全都是关于学习的,不是吗?
MikeiLL
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.