Os terceiros devem usar $ wp_scripts / $ wp_styles-add_data?

30

Dentro da classe WP_Dependencies existe um método chamado add_data . Essa função adiciona dados a scripts / estilos que foram enfileirados durante o carregamento do WordPress. Um uso comumente citado para essa função é adicionar uma condicional ao adicionar folhas de estilo direcionadas a diferentes versões do IE. Por exemplo, para segmentar o IE8 e mais abaixo:

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

Isso será renderizado 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]--> 

Quando olho no Core, vejo alguns lugares onde esse método é usado:

  • WP_Styles->add_inline_style() : adiciona o estilo inline após o folha de estilo referenciada (feita via WP_Styles->print_inline_style() )

  • WP_Scripts->localize() : adiciona um objeto codificado json (envolto pelo mais "public" função wp_localize_script() )

  • wp_plupload_default_settings() : adiciona o objeto codificado json (criado a partir de uma matriz multidimensional) para o script 'wp-plupload' (note que isso está por vir em 3.4)

  • Ao registrar / enfileirar scripts e estilos Adicionando dados para scripts padrão ( wp-includes/script-loader.php )

Da leitura até os usos do método, ele não parece ter um caso de uso específico. Em wp_plupload_default_settings , parece permitir a injeção arbitrária de dados. Em wp_register_script , parece ser usado para diferenciar scripts de cabeçalho e rodapé. Em add_inline_style , é usado para indicar o estilo in-line que deve ser adicionado depois que uma folha de estilo especificada for enfileirada.

Um uso excelente para essa função seria algo como o código a seguir, no qual você está enfileirando um script externo, mas precisa enviar algumas vars de configuração, algumas das quais vêm do 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' );

Isso resultará em:

<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>

Observe que isso não pode ser realizado com wp_localize_script porque o objeto addthis_share tem propriedades dentro das propriedades ( Eu escrevi sobre um jeito um tanto quanto hacky antes .

EDIT: Eu estava errado em afirmar isso. wp_localize_script lida bem com as matrizes multidimensionais.

Este método parece funcionar muito bem pelos seguintes motivos:

  1. Ele permite que você anexe os dados ao identificador de script para que seja sempre corretamente enfileirado com o script. Além disso, ele será inteligente em desqualificar o script, a ordem do script e o posicionamento do script.
  2. Permite que você use PHP para enviar vars para JS.
  3. Parece mais organizado do que usar wp_print_styles para imprimir alguns scripts arbitrários que são executados posteriormente por um script em fila.

Existem algumas coisas que não funcionam como esperado, o que me preocupa com esse método. Um desses problemas é que, se você usar wp_localize_script junto com $wp_scripts->add_data , poderá obter resultados inesperados. Por exemplo:

// 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' ) );

Produz:

<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>

Considerando este roteiro:

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

Produz:

<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>

A chave data definida por wp_localize_script é finalmente substituída pela chamada para $wp_scripts->add_data , enquanto se você chamar wp_localize_script duas vezes para o mesmo script, a sequência será concatenada adequadamente.

Embora tudo isso seja uma maneira realmente prática de imprimir scripts arbitrários para uso com um script enfileirado, isso me faz pensar que ele não deve ser amplamente usado devido ao potencial de conflitos. Eu certamente posso ver um argumento para usar isso em projetos pessoais, onde o código não será usado em plugins / temas da comunidade.

Eu também olhei para o Core Trac para ver se havia alguma pista sobre o propósito da função. Eu encontrei um ticket (http://core.trac.wordpress.org/ticket/11520) (um épico) que explorou outras formas de adicionar JS arbitrário. Assim, parece que há interesse em criar uma maneira melhor de adicionar JS arbitrário, mas não tenho certeza se add_data deve fazer parte do processo.

Minha principal questão é: os desenvolvedores devem estar usando essa função? Em alguns casos (por exemplo, wp_register_script ), parece uma função "privada" que terceiros não devem usar; no entanto, em outros casos (por exemplo, wp_plupload_default_settings ), parece ser uma maneira perfeitamente razoável de injetar JS arbitrário antes de um script enfileirado.

Eu não imagino que haja uma resposta "correta" para isso, mas gostaria de ouvir o que outros desenvolvedores pensam. Eu também imagino que há peças nesse quebra-cabeça que eu negligenciei completamente e adoraria ouvir o que os outros têm a dizer sobre isso.

    
por tollmanz 10.05.2012 / 05:25

2 respostas

4
  

Esta função adiciona dados a scripts / estilos que foram enfileirados durante o carregamento do WordPress.

Não realmente. Adiciona dados a scripts / estilos que foram registered .

  

A chave de dados que é definida por wp_localize_script é finalmente sobrescrita pela chamada para $wp_scripts->add_data , enquanto se você chamar wp_localize_script duas vezes para o mesmo script, a string será concatenada adequadamente.

Ambos chamam a API subjacente (não acessível, interna), portanto ela é sobrescrita (como você afirmou). Isso acontece quando chama $this->get_data( $handle, 'data' ); .

Pergunta

  

Minha principal questão é: os desenvolvedores devem usar essa função?

Resposta

Simplesmente disse: Sim, quando você não tem outra chance de fazer o que precisa.

Outro exemplo: verifique se um script foi registrado (por exemplo, json2/jquery ) e mova-o para o rodapé (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 ↑ só funciona para dados arquivados em extra !

Notas adicionais

Contra-pergunta: Você já tentou adicionar dependências a scripts registrados pelo core? Por exemplo: tente adicionar JSON2 conforme necessário aos jQuery . Isso não é possível sem interceptar o 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 );
}

Há toda uma carga de coisas que a classe não pode fazer. Então, usar algo como ->add_data() é imo totalmente válido. Apenas use o que você tem, pois ainda é melhor do que viver as carências das classes principais.

    
por kaiser 17.05.2012 / 13:23
1

Houve um grande debate no WP 3.3 sobre como lidar com dados de script:

enlace

Note que você pode passar matrizes aninhadas para wp_localize_data() agora:

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

Então, eu usaria add_data() se não houvesse uma API de nível mais alto para o que eu precisava fazer, com o entendimento de que o comportamento pode mudar em alguns casos extremos, como quando a concatenação está envolvida.

    
por scribu 18.05.2012 / 04:46