it-roy-ru.com

передать объект/JSON в wp_localize_script

У меня есть рабочий кусок 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 становится строковым "массивом", вот вывод:

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

Итак ... Как я могу это сделать (или мне просто нужно признать, что я должен "сплющить" свой объект в отдельные переменные типа:

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

Действительно, 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
14
Jan Fabry

Отказ от ответственности - я не в курсе вопросов безопасности 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);

Но ls и rs по-прежнему не работают, потому что метод WP_Scripts->print_scripts_l10n() не обрабатывает случай, когда переменная является массивом.

Лучше всего я мог бы придумать, чтобы исправить это следующим фильтром (как выше - не уверен, насколько безопасно было бы использовать его в производстве, но чтобы дать общее представление):

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;
}
1
Rarst