Должны ли третьи стороны использовать $ wp_scripts / $ wp_styles-> add_data?


31

Внутри WP_Dependenciesкласса существует метод с именем add_data. Эта функция добавляет данные в скрипты / стили, которые были поставлены в очередь во время загрузки WordPress. Обычно эта функция используется для добавления условия при добавлении таблиц стилей, предназначенных для разных версий IE. Например, для целевой IE8 и ниже:

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

Это будет отображаться как:

<!--[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]--> 

Когда я просматриваю Core, я вижу несколько мест, где используется этот метод:

  • WP_Styles->add_inline_style(): добавляет встроенный стиль после ссылочной таблицы стилей (выполняется через WP_Styles->print_inline_style())

  • WP_Scripts->localize(): добавляет json-кодированный объект (обёрнутый более «публичной» wp_localize_script()функцией)

  • wp_plupload_default_settings() : добавляет закодированный в json объект (созданный из многомерного массива) для сценария 'wp-plupload' (обратите внимание, что это ожидается в 3.4)

  • При регистрации / постановке в очередь скриптов и стилей Добавление данных для скриптов по умолчанию ( wp-includes/script-loader.php)

Из прочтения использования метода, похоже, нет особого варианта использования. В wp_plupload_default_settings, кажется, допускает произвольное внедрение данных. В wp_register_script, кажется, он используется для различения скриптов верхнего и нижнего колонтитула. В add_inline_style, это используется, чтобы обозначить встроенный стиль, который должен быть добавлен после того, как указанная таблица стилей помещена в очередь.

Превосходное использование этой функции - что-то вроде следующего кода, в котором вы ставите в очередь внешний скрипт, но вам нужно отправить ему несколько конфигурационных переменных, некоторые из которых поступают из БД:

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

Это приведет к:

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

Обратите внимание, что это не может быть выполнено, wp_localize_scriptпотому что addthis_shareобъект имеет свойства в свойствах ( я уже писал об этом несколько раньше ).

РЕДАКТИРОВАТЬ: я был неправ, заявив об этом. wp_localize_scriptотлично справляется с многомерными массивами.

Этот метод, кажется, работает очень хорошо по следующим причинам:

  1. Это позволяет вам прикреплять данные к дескриптору сценария, чтобы он всегда был правильно помещен в сценарий. Кроме того, будет разумно удалить сценарий из очереди, порядок и размещение сценария.
  2. Это позволяет использовать PHP для отправки переменных в JS.
  3. Это кажется более организованным, чем использование wp_print_stylesдля распечатки некоторого произвольного сценария, который затем обрабатывается сценарием в очереди.

Есть некоторые вещи, которые не работают, как ожидалось, что беспокоит меня об этом методе. Одна из таких проблем заключается в том, что если вы используете wp_localize_scriptвместе $wp_scripts->add_data, вы можете получить неожиданные результаты. Например:

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

Производит:

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

Тогда как этот скрипт:

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

Производит:

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

dataКлюч , который устанавливается wp_localize_scriptв конечном счете перезаписаны вызова $wp_scripts->add_data, в то время как если вы звоните в wp_localize_scriptдва раза за тот же сценарий, строка будет правильно сцеплены.

Хотя все это является действительно удобным способом печати произвольного сценария для использования со сценарием в очереди, он заставляет меня думать, что он не должен широко использоваться из-за потенциальных конфликтов. Я, конечно, вижу аргумент в пользу использования этого в личных проектах, где код не будет использоваться в плагинах / темах сообщества.

Я также посмотрел на Core Trac, чтобы увидеть, есть ли какие-либо подсказки относительно цели функции. Я нашел один билет (http://core.trac.wordpress.org/ticket/11520) (эпический на тот момент), который исследовал другие способы добавления произвольного JS. Таким образом, кажется, что есть интерес к созданию лучшего способа добавить произвольный JS, но не совсем точно, add_dataдолжен ли он быть частью процесса.

Мой главный вопрос: должны ли разработчики использовать эту функцию? В некоторых случаях (например, wp_register_script) кажется «частной» функцией, которую не следует использовать третьим лицам; однако, в других случаях (например, wp_plupload_default_settings) кажется вполне разумным способом ввести произвольный JS перед сценарием в очереди.

Я не думаю, что есть «правильный» ответ на этот вопрос, но хотел бы услышать, что думают другие разработчики. Я также представляю, что в этой головоломке есть кусочки, которыми я полностью пренебрегал и хотел бы услышать, что другие скажут об этом.

Ответы:


4

Эта функция добавляет данные в скрипты / стили, которые были поставлены в очередь во время загрузки WordPress.

На самом деле, нет. Он добавляет данные в сценарии / стили, которые были registered.

Ключ данных, который устанавливается, wp_localize_scriptв конечном итоге перезаписывается вызовом $wp_scripts->add_data, тогда как если вы wp_localize_scriptдважды вызываете один и тот же сценарий, строка будет правильно объединена.

Правильно. Они оба вызывают базовый (недоступный, внутренний) API, поэтому он перезаписывается (как вы заявили). Это происходит, когда он звонит $this->get_data( $handle, 'data' );.

Вопрос

Мой главный вопрос: должны ли разработчики использовать эту функцию?

Ответ

Проще говоря: да, когда у тебя нет другого шанса сделать то, что тебе нужно.

Другой пример: проверьте, был ли зарегистрирован скрипт (например, json2/jquery) и переместите его в нижний колонтитул (проверьте 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 );

Примечание: это ↑ работает только для данных, поданных в extra!

Дополнительные замечания

Встречный вопрос: Вы когда-нибудь пытались добавить зависимости в скрипты, зарегистрированные ядром? Например: попробуйте добавить JSON2при необходимости deps в jQuery. Это невозможно без перехвата 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 );
}

Есть целый ряд вещей, которые класс не может сделать. Таким образом , используя что - то вроде ->add_data()это имо полноценными. Просто используйте то, что у вас есть, потому что это все же лучше, чем жить без базовых классов.


«Подождите, пока ядро ​​не добавит возможность добавлять зависимости в стандартные и встроенные скрипты». Вы открывали тикет в trac?
— scribu

@scribu Спасибо, но нет, нет и не буду. Все мои билеты там просто гниют, поэтому я отступил от усилий, направленных на приобретение билетов. Это не оскорбление, просто вывод из того, что я испытал до сих пор. Но чтобы не начинать спорить с вами, я удалю его, так как это просто осталось от простого копирования / вставки из одного из моих плагинов.
— Кайзер

Ну, тогда, я думаю, мне придется спросить здесь: какая польза от загрузки JSON2 перед jQuery?
— scribu

Ничего, так как это абстрактный пример. Если вы попытаетесь найти более подробный пример, вы можете представить одну библиотеку, которая нуждается JSON2, но также должна быть загружена раньше jQuery: давайте назовем ее UberjQuery. Кстати: поскольку вы хорошо справляетесь с diggin 'в ядро, почему бы вам не выделить время и написать ответ? Я думаю, это стоило бы времени на чтение.
— Кайзер

Спасибо за ваши мысли, Кайзер! Я определенно ищу методы для добавления JS, который поддерживается "API". Хотя я знаю, что могу согнуть его, чтобы делать все что угодно, это может привести к нестабильному коду. Приятно знать, для чего он предназначен, а не что он может сделать, и, конечно, с этим можно многое сделать.
— Tollmanz

1

В WP 3.3 было много споров о том, как обрабатывать данные скрипта:

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

Обратите внимание, что теперь вы можете передавать вложенные массивы wp_localize_data():

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

Итак, я бы использовал, add_data()если бы не было высокоуровневого API для того, что мне нужно было сделать, с пониманием того, что его поведение может измениться в некоторых крайних случаях, например, когда используется конкатенация.


Спасибо за ваш вклад Scribu! Забавно, что вы ссылаетесь на этот билет! Я ссылался на это в своем посте, но в нем так много всего происходило, что я не понял, что теперь поддерживаются многомерные массивы.
— Tollmanz

Ха ... приятно редактировать! Этот билет меня не смутил так, как я думал.
— Tollmanz

@ tollmanz Да, это довольно странно, особенно если вы не были в IRC в то время.
— scribu

Мистер @ungestaltbar показал мне способ добавления многомерных массивов несколько месяцев назад. Не знал, что это уже в ядре.
— Кайзер

@scribu - разве нет поддержки многомерных массивов? - по крайней мере, я использую их без проблем ...
— Стивен Харрис
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.