przekaż obiekt / JSON do wp_localize_script

15

Mam działający fragment języka JavaScript, który zawiera literał obiektu. Ale muszę go zlokalizować i zastanawiam się, jak go przepisać, aby uzyskać wp_localize_script () w celu uzyskania dostępu i wypisania poprawnego formatu.

Wersja niezlokalizowana (niedynamiczna) wygląda następująco:

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

Teraz, aby mieć te wartości generowane przez php (na podstawie niektórych ustawień wp_set), chcę użyć wp_localize_script, więc mogę wziąć to stąd:

var layoyt_config = my_localized_data.layoyt_config;

Aby wprowadzić te dane do tej właściwości obiektu „pomyślałem”, że mogę to zrobić, ale oczywiście nie:

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

Ponieważ spowoduje to błąd analizy PHP Próbowałem przepisać składnię JSON na tablicę, ponieważ wp_localize_script przekonwertuje to z powrotem na notację obiektową, ale to również nie działa dla mnie:

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

I chociaż działa to płynnie przez parser php, nie otrzymuję oczekiwanego wyniku w źródle strony, ponieważ moja_lokalizowana_data.layout_config staje się ciągiem „Array”, oto dane wyjściowe:

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

Więc ... Jak mogę to zrobić (czy po prostu muszę zaakceptować, że muszę „spłaszczyć” mój obiekt w odrębne obiekty, takie jak:

lc_header = '1';
ls_ls_sb1 = '1';
etc...
mikkelbreum
źródło

Odpowiedzi:

15

Rzeczywiście, wp_localize_script()jest prosty , po prostu dodaje cudzysłowy wokół wartości i unika treści, oczekując, że wszystkie będą ciągami znaków.

Istnieje jednak l10n_print_afterklucz tablicy, który zostanie wydrukowany bez żadnych zakłóceń. Można go użyć do wykonania dowolnego kodu po przekazaniu ciągów. Możesz go użyć do przekazania dodatkowych danych.

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

Otrzymasz kod taki jak ten:

var my_localized_data = {}; // What is left of your array
my_localized_data = {'layout_config': {'ls': {'sb1': 1}}}; // From l10n_print_after
Jan Fabry
źródło
Bardzo przydatne, chociaż myślę, że miałeś na myśli średnik po json_encode, a nie przecinek, czy mam rację?
kovshenin
1
@kovshenin: Good catch! Poprawiłem to, ale gdybyś zaproponował to jako edycję, dostałbyś za to +2 powtórzenia.
Jan Fabry
Nie chcę przejmować się tym pytaniem, ale otrzymałem to pytanie / odpowiedź jako odniesienie do sprawdzenia wordpress.stackexchange.com/questions/53842 (na wypadek, gdyby ktoś miał tutaj jakieś wskazówki). Dzięki!
Zach
1

Zrzeczenie się odpowiedzialności - nie jestem dogłębnie związany z kwestiami bezpieczeństwa JS.

Po pierwsze, aby dopasować pożądany wynik, wyłączasz poziom zagnieżdżenia. Nazwa obiektu idzie jako parametr w lokalizacji wywołania (zamiast klucza tablicy):

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

Ale lsi rssą nadal łamane, ponieważ WP_Scripts->print_scripts_l10n()metoda nie obsługuje przypadek, gdy zmienna jest tablicą.

Najlepsze, co mogłem wymyślić, aby naprawić następujący filtr (jak wyżej - nie jestem pewien, jak bezpieczne byłoby używanie go w produkcji, ale dać ogólny pomysł):

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
źródło
Rozumiem, że nazwa głównego obiektu wchodzi jako parametr 2dn w wywołaniu skryptu wp_localize_script, ale już to robię, moja zlokalizowana nazwa obiektu powinna być „moja_lokalizowana_data”, obiekt ten będzie miał wiele właściwości, z których większość ma wartości zwykłego ciągu, ale potrzebuję jednej z tych właściwości, aby być obiektem wielowymiarowym.
mikkelbreum
Wydaje się, że jest to poza zakresem wp_localize_script bez modyfikacji. Nie obsługuje tablic wielowymiarowych. Teraz wymyśliłem inną metodę, w której przechowuję moje zlokalizowane wielowymiarowe obejct jako wartość html data- *. Działa to dobrze, ale zostaw dodatkowe pytania: wordpress.stackexchange.com/questions/8684
mikkelbreum