第三方应该使用$ wp_scripts / $ wp_styles-> add_data吗?


31

内的WP_Dependencies类存在命名的方法add_data。此函数将数据添加到WordPress加载期间已排队的脚本/样式。该功能通常被引用的用途是在添加针对IE的不同版本的样式表时添加条件。例如,以IE8及更低版本为目标:

function test_wp_print_styles() {
    global $wp_styles;

    wp_enqueue_style( 'test-style', get_template_directory_uri() . '/css/test.css', array(), 1, 'all' );
    $wp_styles->add_data( 'test-style', 'conditional', 'lte ie8' );
}
add_action( 'wp_print_styles', 'test_wp_print_styles' );

这将呈现为:

<!--[if lte ie8]>
<link rel='stylesheet' id='test-style-css'  href='http://trunkosaurus.dev/wp-content/themes/twentyeleven/css/test.css?ver=1' type='text/css' media='all' />
<![endif]--> 

当我浏览Core时,会看到一些使用此方法的地方:

  • WP_Styles->add_inline_style():在引用的样式表之后添加内联样式(通过完成WP_Styles->print_inline_style()

  • WP_Scripts->localize():添加一个json编码的对象(由更多“ public” wp_localize_script()函数包装)

  • wp_plupload_default_settings() :为“ wp-plupload”脚本添加json编码的对象(从多维数组创建)(请注意,这将在3.4中推出)

  • 注册/排队脚本和样式时为默认脚本添加数据(wp-includes/script-loader.php

从通读该方法的用法来看,它似乎没有特定的用例。在中wp_plupload_default_settings,似乎允许任意数据注入。在中wp_register_script,它似乎用于区分页眉和页脚脚本。在中add_inline_style,它用于表示应在将指定的样式表加入队列后添加的内联样式。

此功能的最佳用法是类似于以下代码,在其中将外部脚本加入队列,但需要向其发送一些配置变量,其中一些来自数据库:

function zdt_enqueue_add_this() {
    global $wp_scripts;

    wp_enqueue_script( 'zdt-add-this', 'http://s7.addthis.com/js/250/addthis_widget.js#pubid=myidhere' );

    // Contrived example of database call to get a twitter handle stored in the db
    $author_twitter_handle = zdt_get_twitter_handle();

    $js = "var addthis_share = { templates : { twitter: '{{title}} {{url}} (by @" . sanitize_key( $author_twitter_handle ) . "' } };\n";
    $js .= 'var addthis_config = { ui_header_color: "#FFFFFF", ui_header_background: "#FA9628", ui_cobrand: "My Site" };';

    $wp_scripts->add_data( 'zdt-add-this', 'data', $js );
}
add_action( 'wp_enqueue_scripts', 'zdt_enqueue_add_this' );

这将导致:

<script type='text/javascript'>
/* <![CDATA[ */
var addthis_share = { templates : { twitter: '{{title}} {{url}} (by @tollmanz' } };
var addthis_config = { ui_header_color: "#FFFFFF", ui_header_background: "#FA9628", ui_cobrand: "My Site" };
/* ]]> */
</script>
<script type='text/javascript' src='http://s7.addthis.com/js/250/addthis_widget.js?ver=3.4-beta4-20731#pubid=myidhere'></script>

请注意,这不能通过对象来实现,wp_localize_script因为addthis_share对象在属性中具有属性(之前我确实写过一些有点怪异的方法)。

编辑:我说错了。wp_localize_script处理多维数组就好了。

由于以下原因,此方法似乎非常有效:

  1. 它允许您将数据附加到脚本句柄,以便始终将其与脚本正确排队。此外,将使脚本出队,脚本顺序和脚本放置变得明智。
  2. 它允许您使用PHP将vars发送到JS。
  3. 与使用wp_print_styles它打印出一些随后由排队脚本执行的任意脚本相比,它看起来更有条理。

有些事情无法正常工作,这让我担心。这样的问题之一是,如果wp_localize_script与一起使用$wp_scripts->add_data,可能会得到意想不到的结果。例如:

// Contrived example of database call to get a twitter handle stored in the db
$author_twitter_handle = zdt_get_twitter_handle();

$js = "var addthis_share = { templates : { twitter: '{{title}} {{url}} (by @" . sanitize_key( $author_twitter_handle ) . "' } };\n";
$js .= 'var addthis_config = { ui_header_color: "#FFFFFF", ui_header_background: "#FA9628", ui_cobrand: "My Site" };';

$wp_scripts->add_data( 'zdt-add-this', 'data', $js );
wp_localize_script( 'zdt-add-this', 'addthis_share', array( 'var' => 'val' ) );

产生:

<script type='text/javascript'>
/* <![CDATA[ */
var addthis_share = { templates : { twitter: '{{title}} {{url}} (by @tollmanz' } };
var addthis_config = { ui_header_color: "#FFFFFF", ui_header_background: "#FA9628", ui_cobrand: "My Site" };
var addthis_share = {"var":"val"};
/* ]]> */
</script>
<script type='text/javascript' src='http://s7.addthis.com/js/250/addthis_widget.js?ver=3.4-beta4-20731#pubid=myidhere'></script>

而此脚本:

// Contrived example of database call to get a twitter handle stored in the db
$author_twitter_handle = zdt_get_twitter_handle();

$js = "var addthis_share = { templates : { twitter: '{{title}} {{url}} (by @" . sanitize_key( $author_twitter_handle ) . "' } };\n";
$js .= 'var addthis_config = { ui_header_color: "#FFFFFF", ui_header_background: "#FA9628", ui_cobrand: "My Site" };';

wp_localize_script( 'zdt-add-this', 'addthis_share', array( 'var' => 'val' ) );
$wp_scripts->add_data( 'zdt-add-this', 'data', $js );

产生:

<script type='text/javascript'>
/* <![CDATA[ */
var addthis_share = { templates : { twitter: '{{title}} {{url}} (by @tollmanz' } };
var addthis_config = { ui_header_color: "#FFFFFF", ui_header_background: "#FA9628", ui_cobrand: "My Site" };
/* ]]> */
</script>
<script type='text/javascript' src='http://s7.addthis.com/js/250/addthis_widget.js?ver=3.4-beta4-20731#pubid=myidhere'></script>

data设置的键wp_localize_script最终会被调用覆盖$wp_scripts->add_data,而如果您wp_localize_script为同一脚本调用两次,则该字符串将被正确连接。

尽管所有这些都是打印任意脚本以与排队脚本一起使用的一种非常方便的方法,但我认为由于冲突的可能性,不应广泛使用它。我当然可以看到在个人项目中使用此参数的论点,其中代码不会在社区插件/主题中使用。

我还查看了Core Trac,以查看是否有任何有关此功能用途的线索。我发现一张票证(http://core.trac.wordpress.org/ticket/11520)(当时是史诗级票证),探讨了添加任意JS的其他方法。因此,似乎有兴趣创建一种更好的方法来添加任意JS,但不确定是否add_data应该将其包含在该过程中。

我的主要问题是:开发人员应该使用此功能吗?在某些情况下(例如wp_register_script),第三方似乎不应使用“私有”功能;但是,在其他情况下(例如wp_plupload_default_settings),这似乎是在排队的脚本之前注入任意JS的一种完全合理的方法。

我不认为对此有“正确”的答案,但很想听听其他开发人员的想法。我还认为,这个难题中有一些我完全忽略了的部分,很想听听其他人对此有何评论。

Answers:


4

此函数将数据添加到WordPress加载期间已排队的脚本/样式。

并不是的。它将数据添加到过去的脚本/样式中registered

设置的数据键wp_localize_script最终会被调用覆盖$wp_scripts->add_data,而如果您wp_localize_script为同一脚本调用两次,则该字符串将被正确连接。

对。它们都调用了底层的(不可访问的,内部的)API,因此它被覆盖(如您所述)。调用时会发生这种情况$this->get_data( $handle, 'data' );

我的主要问题是:开发人员应该使用此功能吗?

回答

简单地说:是的,当您没有其他机会去做自己需要的事情时。

另一个示例:检查脚本是否已注册(例如json2/jquery),然后将其移至页脚(选中extra['group'])。

// Move scripts to the footer - in case it isn't already there
if ( ! $wp_scripts->get_data( 'json2', 'group' ) )
    $wp_scripts->add_data( 'json2', 'group', 1 );

if ( ! $wp_scripts->get_data( 'jquery', 'group' ) )
    $wp_scripts->add_data( 'jquery', 'group', 1 );

注意:此↑仅适用于extra!下的数据。

附加条款

反问题:您是否曾经尝试过向核心注册的脚本添加依赖项?例如:尝试JSON2根据需要添加jQuery。如果不拦截,这是不可能的global $wp_scripts

global $wp_scripts;

$scripts = array( 
     'jquery'      => array( 'json2' )
    ,'jquery-form' => array( 'json2' ) 
);

foreach ( $scripts as $handle => $deps )
{
    // Ugly hack: Intercept the global to force the "natural"/needed order: JSON2 » jQuery
    $deps_default =& $wp_scripts->registered[ $handle ]->deps;
    $wp_scripts->registered[ $handle ]->deps = array_merge( $deps_default, $deps );
}

类有很多无法做的事情。因此,使用类似->add_data()IMO完全有效。只需使用您所获得的东西,因为它比缺少核心类的情况更好。


“等到core添加了向默认和内置脚本添加依赖项的可能性之后,”您是否在Trac中打开了票证?
scribu 2012年

@scribu谢谢,但是不,我没有,不,我不会。我的所有门票都只在那儿腐烂了,所以我从投入精力撤回了追踪门票。这不是冒犯,只是我到目前为止所获得的结论。但为了不与您争论,我将其删除,因为这只是从我的一个插件的简单复制/粘贴操作中获得的。
凯撒2012年

好吧,那么我想我不得不在这里问:在jQuery之前加载JSON2有什么好处?
scribu 2012年

没什么,因为这是一个抽象的例子。如果您想找到一个更详细的示例,那么您可以想象一个需要的库JSON2,但是还需要先加载jQuery:让我们命名它UberjQuery。顺便说一句:由于您在“挖掘核心”方面做得很好,所以为什么不花时间写答案呢?我想值得一读。
kaiser 2012年

感谢您的想法Kaiser!我肯定在寻找添加“ API”支持的JS的方法。虽然我知道我可以弯腰去做各种各样的事情,但这可能会导致代码不稳定。很高兴知道它的目的而不是它可以做什么,当然,可以做很多事情。
tollmanz 2012年

1

WP 3.3中有一个关于如何处理脚本数据的大争论:

http://core.trac.wordpress.org/ticket/11520

请注意,您可以将嵌套数组传递到wp_localize_data()现在:

wp_localize_script( 'jquery', 'jQueryL10n', array(
    'foo' => array(
        'bar' => array( 'apple', 'orange' )
    ),
) );

因此,add_data()如果没有更高级别的API可以满足我的需要,我会使用它,因为它的行为在某些极端情况下(例如涉及串联时)可能会发生变化。


感谢您对Scribu的投入!有趣的是,您链接到该票证!我在我的文章中链接了它,但是由于发生了太多事情,以至于我没有意识到现在支持多维数组。
tollmanz 2012年

哈...好编辑!那张票让我不像我想的那么困惑。
tollmanz 2012年

@tollmanz是的,这非常令人困惑,尤其是如果您当时不在IRC中时。
scribu 2012年

@ungestaltbar先生在一个月前向我展示了一种添加多维数组的方法。不知道,这已经是核心。
kaiser 2012年

@scribu-是否已不支持多维数组?-至少我使用它们没有任何问题...
史蒂芬·哈里斯
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.