передать объект / 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...
mikkelbreum
источник

Ответы:

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;
}
Rarst
источник
Я понимаю, что имя основного объекта входит в качестве параметра 2dn при вызове wp_localize_script, но я уже делаю это, мое локализованное имя объекта должно быть «my_localized_data», этот объект будет иметь множество свойств, большинство из которых имеет простые строковые значения, но мне нужно, чтобы одно из этих свойств было многомерным объектом.
mikkelbreum
Похоже, это выходит за рамки wp_localize_script без изменений. Он не может работать с многомерными массивами. Теперь я предложил другой метод, в котором я храню свой многомерный объект с локализацией в виде значения html data- *. Это работает нормально, но оставляйте дополнительные вопросы: wordpress.stackexchange.com/questions/8684
mikkelbreum