¿Los terceros deben usar $ wp_scripts / $ wp_styles-> add_data?


31

Dentro de la WP_Dependenciesclase existe un método llamado add_data. Esta función agrega datos a los scripts / estilos que se han puesto en cola durante la carga de WordPress. Un uso comúnmente citado para esta función es agregar un condicional al agregar hojas de estilo que están dirigidas a diferentes versiones de IE. Por ejemplo, para apuntar a IE8 y versiones inferiores:

function test_wp_print_styles() {
    global $wp_styles;

    wp_enqueue_style( 'test-style', get_template_directory_uri() . '/css/test.css', array(), 1, 'all' );
    $wp_styles->add_data( 'test-style', 'conditional', 'lte ie8' );
}
add_action( 'wp_print_styles', 'test_wp_print_styles' );

Esto se representará como:

<!--[if lte ie8]>
<link rel='stylesheet' id='test-style-css'  href='http://trunkosaurus.dev/wp-content/themes/twentyeleven/css/test.css?ver=1' type='text/css' media='all' />
<![endif]--> 

Cuando miro a través de Core, veo un puñado de lugares donde se usa este método:

  • WP_Styles->add_inline_style(): agrega estilo en línea después de la hoja de estilo referenciada (hecho a través de WP_Styles->print_inline_style())

  • WP_Scripts->localize(): agrega un objeto codificado json (envuelto por la función más "pública" wp_localize_script())

  • wp_plupload_default_settings() : agrega el objeto codificado json (creado a partir de una matriz multidimensional) para el script 'wp-plupload' (tenga en cuenta que esto se publicará en 3.4)

  • Al registrar / poner en cola secuencias de comandos y estilos Agregar datos para secuencias de comandos predeterminadas ( wp-includes/script-loader.php)

Al leer los usos del método, no parece tener un caso de uso específico. En wp_plupload_default_settings, parece permitir la inyección arbitraria de datos. En wp_register_script, parece ser utilizado para diferenciar entre scripts de encabezado y pie de página. En add_inline_style, se usa para denotar el estilo en línea que se debe agregar después de que se encola una hoja de estilo especificada.

Un uso excelente para esta función sería algo como el siguiente código en el que está poniendo en cola un script externo pero necesita enviarle algunos valores de configuración, algunos de los cuales provienen del DB:

function zdt_enqueue_add_this() {
    global $wp_scripts;

    wp_enqueue_script( 'zdt-add-this', 'http://s7.addthis.com/js/250/addthis_widget.js#pubid=myidhere' );

    // Contrived example of database call to get a twitter handle stored in the db
    $author_twitter_handle = zdt_get_twitter_handle();

    $js = "var addthis_share = { templates : { twitter: '{{title}} {{url}} (by @" . sanitize_key( $author_twitter_handle ) . "' } };\n";
    $js .= 'var addthis_config = { ui_header_color: "#FFFFFF", ui_header_background: "#FA9628", ui_cobrand: "My Site" };';

    $wp_scripts->add_data( 'zdt-add-this', 'data', $js );
}
add_action( 'wp_enqueue_scripts', 'zdt_enqueue_add_this' );

Esto resultará en:

<script type='text/javascript'>
/* <![CDATA[ */
var addthis_share = { templates : { twitter: '{{title}} {{url}} (by @tollmanz' } };
var addthis_config = { ui_header_color: "#FFFFFF", ui_header_background: "#FA9628", ui_cobrand: "My Site" };
/* ]]> */
</script>
<script type='text/javascript' src='http://s7.addthis.com/js/250/addthis_widget.js?ver=3.4-beta4-20731#pubid=myidhere'></script>

Tenga en cuenta que esto no se puede lograr wp_localize_scriptporque el addthis_shareobjeto tiene propiedades dentro de las propiedades ( antes escribí sobre una forma un tanto extraña ).

EDITAR: Me equivoqué al afirmar esto. wp_localize_scriptmaneja arreglos multidimensionales muy bien.

Este método parece funcionar realmente bien por las siguientes razones:

  1. Le permite adjuntar los datos al identificador del script para que siempre se coloque correctamente en cola con el script. Además, será inteligente acerca de la desconexión del guión, el orden del guión y la colocación del guión.
  2. Le permite usar PHP para enviar vars a JS.
  3. Parece más organizado que usar wp_print_stylespara imprimir un guión arbitrario sobre el que actúa un guión en cola.

Hay algunas cosas que no funcionan como se esperaba que me preocupa sobre este método. Uno de esos problemas es que si usa wp_localize_scriptjunto con $wp_scripts->add_data, puede obtener resultados inesperados. Por ejemplo:

// Contrived example of database call to get a twitter handle stored in the db
$author_twitter_handle = zdt_get_twitter_handle();

$js = "var addthis_share = { templates : { twitter: '{{title}} {{url}} (by @" . sanitize_key( $author_twitter_handle ) . "' } };\n";
$js .= 'var addthis_config = { ui_header_color: "#FFFFFF", ui_header_background: "#FA9628", ui_cobrand: "My Site" };';

$wp_scripts->add_data( 'zdt-add-this', 'data', $js );
wp_localize_script( 'zdt-add-this', 'addthis_share', array( 'var' => 'val' ) );

Produce:

<script type='text/javascript'>
/* <![CDATA[ */
var addthis_share = { templates : { twitter: '{{title}} {{url}} (by @tollmanz' } };
var addthis_config = { ui_header_color: "#FFFFFF", ui_header_background: "#FA9628", ui_cobrand: "My Site" };
var addthis_share = {"var":"val"};
/* ]]> */
</script>
<script type='text/javascript' src='http://s7.addthis.com/js/250/addthis_widget.js?ver=3.4-beta4-20731#pubid=myidhere'></script>

Mientras que este script:

// Contrived example of database call to get a twitter handle stored in the db
$author_twitter_handle = zdt_get_twitter_handle();

$js = "var addthis_share = { templates : { twitter: '{{title}} {{url}} (by @" . sanitize_key( $author_twitter_handle ) . "' } };\n";
$js .= 'var addthis_config = { ui_header_color: "#FFFFFF", ui_header_background: "#FA9628", ui_cobrand: "My Site" };';

wp_localize_script( 'zdt-add-this', 'addthis_share', array( 'var' => 'val' ) );
$wp_scripts->add_data( 'zdt-add-this', 'data', $js );

Produce:

<script type='text/javascript'>
/* <![CDATA[ */
var addthis_share = { templates : { twitter: '{{title}} {{url}} (by @tollmanz' } };
var addthis_config = { ui_header_color: "#FFFFFF", ui_header_background: "#FA9628", ui_cobrand: "My Site" };
/* ]]> */
</script>
<script type='text/javascript' src='http://s7.addthis.com/js/250/addthis_widget.js?ver=3.4-beta4-20731#pubid=myidhere'></script>

La dataclave establecida por wp_localize_scriptfinalmente se sobrescribe con la llamada a $wp_scripts->add_data, mientras que si llama wp_localize_scriptdos veces para el mismo script, la cadena se concatenará correctamente.

Si bien todo esto es una forma realmente práctica de imprimir guiones arbitrarios para usar con un guión en cola, me hace pensar que no debería usarse ampliamente debido a la posibilidad de conflictos. Ciertamente puedo ver un argumento para usar esto en proyectos personales donde el código no se usará en complementos / temas de la comunidad.

También miré a Core Trac para ver si había alguna pista sobre el propósito de la función. Encontré un boleto (http://core.trac.wordpress.org/ticket/11520) (uno épico) que exploró otras formas de agregar JS arbitrario. Por lo tanto, parece que hay interés en crear una mejor manera de agregar JS arbitrario, pero no estoy seguro exactamente si add_datadebería ser parte del proceso.

Mi pregunta principal es: ¿deberían los desarrolladores usar esta función? En algunos casos (p. Ej. wp_register_script), Parece una función "privada" que terceros no deberían usar; sin embargo, en otros casos (p. ej. wp_plupload_default_settings), parece una forma perfectamente razonable de inyectar JS arbitrario antes de un script en cola.

No me imagino que haya una respuesta "correcta" a esto, pero me encantaría escuchar lo que piensan otros desarrolladores. También imagino que hay piezas en este rompecabezas que he descuidado por completo y me encantaría escuchar lo que otros tienen que decir al respecto.

Respuestas:


4

Esta función agrega datos a los scripts / estilos que se han puesto en cola durante la carga de WordPress.

Realmente no. Agrega datos a los scripts / estilos que han sido registered.

La clave de datos que establece wp_localize_scriptse sobrescribe en última instancia con la llamada a $wp_scripts->add_data, mientras que si llama wp_localize_scriptdos veces para el mismo script, la cadena se concatenará correctamente.

Correcto. Ambos llaman a la API subyacente (no accesible, interna), por lo que se sobrescribe (como usted indicó). Esto sucede cuando llama $this->get_data( $handle, 'data' );.

Pregunta

Mi pregunta principal es: ¿deberían los desarrolladores usar esta función?

Responder

Simplemente dijo: Sí, cuando no tienes otra oportunidad de hacer lo que necesitas.

Otro ejemplo: Verifique si se registró un script (por ejemplo json2/jquery) y muévalo al pie de página (verifique extra['group']).

// Move scripts to the footer - in case it isn't already there
if ( ! $wp_scripts->get_data( 'json2', 'group' ) )
    $wp_scripts->add_data( 'json2', 'group', 1 );

if ( ! $wp_scripts->get_data( 'jquery', 'group' ) )
    $wp_scripts->add_data( 'jquery', 'group', 1 );

Nota: ¡Este ↑ solo funciona para los datos archivados en extra!

Notas adicionales

Contrapregunta: ¿Alguna vez ha intentado agregar dependencias a los scripts registrados por core? Por ejemplo: Intente agregar a la JSON2medida que sea necesario jQuery. Esto no es posible sin interceptar el global $wp_scripts:

global $wp_scripts;

$scripts = array( 
     'jquery'      => array( 'json2' )
    ,'jquery-form' => array( 'json2' ) 
);

foreach ( $scripts as $handle => $deps )
{
    // Ugly hack: Intercept the global to force the "natural"/needed order: JSON2 » jQuery
    $deps_default =& $wp_scripts->registered[ $handle ]->deps;
    $wp_scripts->registered[ $handle ]->deps = array_merge( $deps_default, $deps );
}

Hay muchas cosas que la clase no puede hacer. Así que usar algo como ->add_data()es imo totalmente válida. Solo usa lo que tienes, ya que aún es mejor que vivir sin las clases básicas.


"Espere hasta que el núcleo agregue la posibilidad de agregar dependencias a los scripts predeterminados e incorporados" ¿Abrió un ticket en trac?
scribu

@scribu Gracias, pero no, no lo he hecho y no, no lo haré. Todos mis boletos simplemente se pudren allí, así que retrocedí de invertir esfuerzo en boletos de tráfico. Eso no es una ofensa, simplemente una conclusión de lo que he experimentado hasta ahora. Pero para no comenzar a discutir contigo, lo eliminaré, ya que esto solo queda de una simple copia / pegado de uno de mis complementos.
Kaiser

Bueno, entonces supongo que tendré que preguntar aquí: ¿cuál sería el beneficio de cargar JSON2 antes de jQuery?
scribu

Nada, ya que es un ejemplo abstracto. Si intenta encontrar un ejemplo más detallado, podría imaginar una biblioteca que necesita JSON2, pero que también necesita cargarse antes jQuery: vamos a nombrarla UberjQuery. Por cierto: como te va bastante bien con la excavación en el núcleo, ¿por qué no te tomas el tiempo y escribes una respuesta? Supongo que valdría la pena leerlo.
Kaiser

Gracias por tus pensamientos Kaiser! Definitivamente estoy buscando métodos para agregar JS que sea compatible con la "API". Si bien sé que puedo doblarlo para hacer todo tipo de cosas, eso puede conducir a un código inestable. Es bueno saber para qué está destinado en lugar de lo que puede hacer, y, ciertamente, se puede hacer mucho con él.
tollmanz

1

Hubo un gran debate en WP 3.3 sobre cómo manejar los datos del script:

http://core.trac.wordpress.org/ticket/11520

Tenga en cuenta que ahora puede pasar matrices anidadas wp_localize_data():

wp_localize_script( 'jquery', 'jQueryL10n', array(
    'foo' => array(
        'bar' => array( 'apple', 'orange' )
    ),
) );

Por lo tanto, lo usaría add_data()si no hubiera una API de nivel superior para lo que necesitaba hacer, con el entendimiento de que su comportamiento podría cambiar en algunos casos extremos, como cuando está involucrada la concatenación.


Gracias por tu aporte Scribu! ¡Qué gracioso que vincules a ese boleto! Me vinculé a él en mi publicación, pero sucedía tanto que no entendí que las matrices multidimensionales ahora son compatibles.
tollmanz

Ja ... buena edición! No estaba tan confundido por ese boleto como pensaba.
tollmanz

@tollmanz Sí, es bastante confuso, especialmente si no estabas en IRC en ese momento.
scribu

El Sr. @ungestaltbar me mostró una forma de agregar matrices multidimensionales hace un mes. No sabía, que esto ya está en el núcleo.
Kaiser

@scribu: ¿no hay ya soporte para matrices multidimensionales? - al menos los uso sin ningún problema ...
Stephen Harris
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.