передать объект / 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 становится строковым «массивом», вот вывод:

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

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

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

Ответы:


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, а не запятую, я прав?
— Ковшенин

1
@kovshenin: хороший улов! Я исправил это, но если бы вы предложили это как редактирование, вы бы получили +2 повторения за это.
— Ян Фабри

Не хочу угонять этот вопрос, но ему дали этот вопрос / ответ в качестве ссылки для поиска на wordpress.stackexchange.com/questions/53842 (в случае, если у кого-то есть какие-либо указатели здесь). Благодарность!
— Зак

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);

Но 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;
}

Я понимаю, что имя основного объекта входит в качестве параметра 2dn при вызове wp_localize_script, но я уже делаю это, мое локализованное имя объекта должно быть «my_localized_data», этот объект будет иметь множество свойств, большинство из которых имеет простые строковые значения, но мне нужно, чтобы одно из этих свойств было многомерным объектом.
— mikkelbreum

Похоже, это выходит за рамки wp_localize_script без изменений. Он не может работать с многомерными массивами. Теперь я предложил другой метод, в котором я храню свой многомерный объект с локализацией в виде значения html data- *. Это работает нормально, но оставляйте дополнительные вопросы: wordpress.stackexchange.com/questions/8684
— mikkelbreum
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.