pasar objeto / JSON a wp_localize_script

15

Tengo una pieza de trabajo de javascript que contiene un objeto literal. Pero necesito localizarlo, y estoy tratando de descubrir cómo reescribirlo para poder obtener wp_localize_script () para acceder a él, y generar el formato correcto.

La versión no localizada (no dinámica) se ve así:

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

Ahora, para tener esos valores generados por php (basado en algunas configuraciones de wp) quiero usar wp_localize_script, para poder tomarlo desde allí:

var layoyt_config = my_localized_data.layoyt_config;

Y para obtener esos datos en esa propiedad de objeto 'pensé' que podría hacer esto, pero obviamente no:

$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 esto causará un error de análisis de PHP, he intentado reescribir la sintaxis de json a array, ya que wp_localize_script lo convertirá de nuevo en notación de objeto, pero esto tampoco funciona para mí:

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

Y aunque esto se ejecuta sin problemas a través del analizador de php, no obtengo el resultado esperado en el origen de mi página, ya que my_localized_data.layout_config se convierte en una "matriz" de cadenas, aquí está el resultado:

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

Entonces ... ¿Cómo puedo hacer esto (o solo tengo que aceptar que debo 'aplanar' mi objeto en variables discretas como:

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

Respuestas:

15

De hecho, wp_localize_script()es simple , solo agrega citas alrededor de los valores y escapa al contenido, esperando que todos sean cadenas.

Sin embargo, existe la l10n_print_afterclave de la matriz, que se imprimirá sin ninguna interferencia. Se puede usar para ejecutar código arbitrario después de pasar las cadenas. Puede usarlo para pasar sus datos adicionales.

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

Terminarás con un 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
fuente
Muy útil, aunque creo que quisiste decir un punto y coma después de json_encode, no una coma, ¿estoy en lo cierto?
kovshenin
1
@kovshenin: ¡Buena captura! Lo corregí, pero si lo hubieras propuesto como una edición, habrías obtenido +2 rep para ello.
Jan Fabry
No pretendo secuestrar esta pregunta, pero se me dio esta pregunta / respuesta como referencia para buscar wordpress.stackexchange.com/questions/53842 (en caso de que alguien tenga algún indicador aquí). ¡Gracias!
Zach
1

Descargo de responsabilidad: estoy fuera de mi alcance en materia de seguridad de JS aquí.

Primero, para que coincida con la salida deseada, está desactivado por nivel de anidación. El nombre del objeto va como parámetro en la llamada de localización (en lugar de la clave de 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);

Sin embargo, lsy rsaún se rompen porque WP_Scripts->print_scripts_l10n()el método no maneja el caso cuando la variable es matriz.

Lo mejor que se me ocurre es solucionar el siguiente filtro (como se indicó anteriormente; no estoy seguro de qué tan seguro sería usarlo en producción, pero para dar una idea general):

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
fuente
Entiendo que el nombre del objeto principal entra como el parámetro 2dn en la llamada a wp_localize_script, pero, ya lo hago, se supone que mi nombre de objeto localizado es 'my_localized_data', ese objeto tendrá una variedad de propiedades que la mayoría de ellas tendrán valores de cadena simples, pero necesito una de estas propiedades para ser un objeto multidimensional.
mikkelbreum
Esto parece estar fuera del alcance de wp_localize_script sin modificación. No puede manejar matrices multidimensionales. Ahora se me ocurrió un método diferente, donde almaceno mi objeto multidimensional localizado como un valor html data- *. Esto funciona bien, pero deje preguntas adicionales: wordpress.stackexchange.com/questions/8684
mikkelbreum