将对象/ JSON传递给wp_localize_script


15

我有一个包含对象文字的javascript工作片段。但是我需要对其进行本地化,并且我正尝试找出如何重写它,以便可以获取wp_localize_script()以接受它,并输出正确的格式。

非本地化(非动态)版本如下所示:

var layoyt_config = {
    'header'        : 1 
,   'footer'        : 1
,   'ls'            : {'sb1':1}
,   'rs'            : {'sb1':1,'sb2':1}
,   'align'         : 'center'
};  

现在,要让php生成这些值(基于某些wp_settings),我想使用wp_localize_script,因此可以从那里获取:

var layoyt_config = my_localized_data.layoyt_config;

为了使数据进入该对象属性,我“想”可以做到这一点,但是显然不能:

$data = array(
    'layout_config' => {
        'header' : 1
    ,   'footer' : 1
    ,   'ls' : {'sb1': 1}
    ,    'rs' : {'sb1': 1,'sb2': 1}
    ,    'align' : 'center'
    }
);
wp_localize_script('my-script-handle', 'my_localized_data', $data);

由于这将导致PHP解析错误,因此我尝试将json重写为数组语法,因为wp_localize_script会将其转换回对象符号,但这对我也不起作用:

$data = array(
    'layout_config' => array(
        'header' => 1
    ,   'footer' => 1
    ,   'ls' => array('sb1'=>1)
    ,    'rs' => array('sb1'=>1,'sb2'=>1)
    ,    'align' => 'center'
    )
);
wp_localize_script('my-script-handle', 'my_localized_data', $data);

并且尽管通过php解析器可以顺利运行,但是由于my_localized_data.layout_config变成了字符串“ Array”,因此在页面源中没有得到预期的输出,以下是输出:

<script type='text/javascript'>
    /* <![CDATA[ */
    var wpkit_localized_data = {
    layout_config: "Array"
    };
    /* ]]> */
</script>

所以..我该怎么做(或者我只需要接受必须将对象“展平”为离散变量,例如:

lc_header = '1';
ls_ls_sb1 = '1';
etc...

Answers:


15

实际上,wp_localize_script()很简单,它只是在值周围添加引号并转义内容,并期望它们都是字符串。

但是,有l10n_print_after阵列的键,该键将被打印而不会产生任何干扰。传递字符串后,可用于执行任意代码。您可以使用它来传递额外的数据。

$data = array(
    'layout_config' => {
      'ls' : {'sb1': 1}
    }
);
$reshuffled_data = array(
    'l10n_print_after' => 'my_localized_data = ' . json_encode( $data ) . ';'
);
wp_localize_script('my-script-handle', 'my_localized_data', $reshuffled_data);

您将得到如下代码:

var my_localized_data = {}; // What is left of your array
my_localized_data = {'layout_config': {'ls': {'sb1': 1}}}; // From l10n_print_after

非常有用,尽管我认为您的意思是在json_encode后使用分号而不是逗号,对吗?
kovshenin 2011年

1
@kovshenin:好收获!我已对其进行了更正,但如果您将其作为编辑建议,那么它会获得+2代表。
1

并不是要劫持这个问题,而是给这个问题/答案作为参考,以供您查询wordpress.stackexchange.com/questions/53842(以防万一有人在这里有任何指针)。谢谢!
扎克2012年

1

免责声明-在这里,我对JS安全性知识不甚了解。

首先,要匹配所需的输出,请按嵌套级别关闭。对象名称用作本地化调用中的参数(而不是数组键):

$data = array(
        'header' => 1
    ,   'footer' => 1
    ,   'ls' => array('sb1'=>1)
    ,    'rs' => array('sb1'=>1,'sb2'=>1)
    ,    'align' => 'center'
);
wp_localize_script('my-script-handle', 'layout_config', $data);

但是lsand rs仍然被破坏,因为WP_Scripts->print_scripts_l10n()当变量为array时方法无法处理这种情况。

最好的办法是修复过滤器之后的问题(如上所述-不确定在生产中使用它的安全性,但可以提供一般的想法):

add_filter('js_escape','js_escape_nested', 10, 2);

function js_escape_nested($safe_text, $text) {

     if(is_array($text) )
         return str_replace( '"', "'", json_encode ($text) );

     return $safe_text;
}

我知道主对象名称在wp_localize_script调用中作为2dn参数进入,但是,我已经做到了,我的本地化对象名称应该是“ my_localized_data”,该对象将具有多种属性,其中大多数具有纯字符串值,但我需要这些属性之一才能成为多维对象。
mikkelbreum 2011年

未经修改,这似乎超出了wp_localize_script的范围。它不能处理多维数组。现在,我想出了另一种方法,将本地化的多维对象存储为html data- *值。这工作得很好,但留下额外的问题:wordpress.stackexchange.com/questions/8684
mikkelbreum
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.