passar object / JSON para wp_localize_script

15

Eu tenho um pedaço de javascript que contém um objeto literal. Mas preciso localizá-lo e estou tentando descobrir como reescrevê-lo para que eu possa obter wp_localize_script () para acessá-lo e gerar o formato correto.

A versão não localizada (não dinâmica) fica assim:

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

Agora, para ter esses valores gerados pelo php (com base em algumas wp_settings), quero usar wp_localize_script, para que eu possa levá-lo a partir daí:

var layoyt_config = my_localized_data.layoyt_config;

E para obter esses dados nessa propriedade de objeto, pensei que poderia fazer isso, mas obviamente não:

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

Como isso causará erro de análise do PHP, tentei reescrever o json na sintaxe da matriz, pois o wp_localize_script o converterá novamente em notação de objeto, mas isso também não funciona para mim:

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

E enquanto isso ocorre sem problemas no analisador php, não recebo a saída esperada na fonte da minha página, pois my_localized_data.layout_config se torna uma String "Array", eis a saída:

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

Então .. Como posso fazer isso (ou apenas tenho que aceitar que devo 'achatar' meu objeto em vars discretos como:

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

Respostas:

15

De fato, wp_localize_script()é simples , apenas adiciona aspas em torno dos valores e escapa ao conteúdo, esperando que todos sejam strings.

No entanto, existe a l10n_print_afterchave da matriz, que será impressa sem nenhuma interferência. Pode ser usado para executar código arbitrário após a passagem das cadeias. Você pode usá-lo para passar seus dados extras.

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

Você terminará com um código como este:

var my_localized_data = {}; // What is left of your array
my_localized_data = {'layout_config': {'ls': {'sb1': 1}}}; // From l10n_print_after
Jan Fabry
fonte
Muito útil, embora eu ache que você quis dizer ponto-e-vírgula após json_encode, não vírgula, estou correto?
precisa saber é o seguinte
1
@kovshenin: Boa captura! Eu o corrigi, mas se você o tivesse proposto como uma edição, obteria +2 representantes por ele.
Jan Fabry
Não pretenda seqüestrar esta pergunta, mas recebeu essa pergunta / resposta como uma referência para procurar por wordpress.stackexchange.com/questions/53842 (caso alguém tenha alguma dica aqui). Obrigado!
Zach
1

Exoneração de responsabilidade - Não estou a par das questões de segurança sobre JS aqui.

Primeiro, para corresponder à saída desejada, desative o nível de aninhamento. O nome do objeto passa como parâmetro na chamada de localização (em vez da chave da matriz):

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

Mas lse rsainda estão quebrados porque o WP_Scripts->print_scripts_l10n()método não lida com o caso quando a variável é array.

O melhor que pude resolver foi o seguinte filtro (como acima - não tenho certeza de quão seguro seria usá-lo na produção, mas para dar uma idéia geral):

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
fonte
Eu entendo que o nome do objeto principal é o parâmetro 2dn na chamada para wp_localize_script, mas, já o faço, meu nome de objeto localizado deve ser 'my_localized_data', esse objeto terá várias propriedades, a maioria delas com valores de cadeia simples, mas preciso de uma dessas propriedades para ser um objeto multidimensional.
Mikkelbreum
Isso parece estar fora do escopo de wp_localize_script sem modificação. Ele não pode lidar com matrizes multidimensionais. Agora criei um método diferente, onde armazeno meu objeto multidimensional localizado como um valor html data- *. Isso funciona bem, mas deixa perguntas adicionais: wordpress.stackexchange.com/questions/8684 #
mikkelbreum