Чи повинні треті сторони використовувати $ 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 об'єкт (завершений функцією "public" 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об’єкт має властивості в межах властивостей ( я раніше писав про дещо хиткі способи цього ).

EDIT: Я неправильно заявив це. wp_localize_scriptпросто обробляє багатовимірні масиви.

Цей метод, здається, працює дуже добре з наступних причин:

  1. Це дозволяє прикріпити дані до ручки сценарію, щоб вона завжди була належним чином закріплена сценарієм. Крім того, вона буде розумною щодо деінвентуалізації сценарію, порядку і розміщення сценарію.
  2. Це дозволяє використовувати PHP для надсилання vars в 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!

Додаткові нотатки

Counter-Question: Ви коли-небудь намагалися додати залежності до скриптів, зареєстрованих ядром? Наприклад: Спробуйте додати 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. Btw: Оскільки ви дуже добре справляєтеся з копанням в ядро, чому б вам не витратити час і написати відповідь? Я думаю, варто було б прочитати час.
кайзер

Дякуємо за ваші думки, кайзер! Я напевно шукаю способи додати 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 API вищого рівня не був для того, що мені потрібно зробити, з розумінням того, що його поведінка може змінитися в деяких крайових випадках, наприклад, коли відбувається конкатенація.


Дякую за Ваш внесок Scribu! Смішно, що ви посилаєтесь на цей квиток! Я пов’язав це з цим у своєму дописі, але там було так багато, що я не зрозумів, що багатовимірні масиви зараз підтримуються.
tollmanz

Ха ... приємно редагувати! Я не був збентежений таким квитком, як я думав.
толманз

@tollmanz Так, це досить заплутано, особливо якщо ви тоді не були в IRC.
scribu

Містер @ungestaltbar показав мені спосіб додати багатовимірні масиви якийсь місяць тому. Не знав, що це вже в основі.
кайзер

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