Czy strony trzecie powinny używać $ wp_scripts / $ wp_styles-> add_data?

31

W WP_Dependenciesklasie istnieje metoda o nazwie add_data. Ta funkcja dodaje dane do skryptów / stylów, które zostały umieszczone w kolejce podczas ładowania WordPress. Często cytowanym zastosowaniem tej funkcji jest dodanie warunkowego przy dodawaniu arkuszy stylów, które są skierowane do różnych wersji IE. Na przykład, aby kierować na IE8 i niższe:

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

Będzie to renderowane jako:

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

Kiedy przeglądam Core, widzę garść miejsc, w których ta metoda jest używana:

  • WP_Styles->add_inline_style(): dodaje styl wbudowany po arkuszu stylów, do którego się odwołuje (wykonane przez WP_Styles->print_inline_style())

  • WP_Scripts->localize(): dodaje obiekt zakodowany w formacie json (zawinięty przez bardziej „publiczną” wp_localize_script()funkcję)

  • wp_plupload_default_settings() : dodaje obiekt zakodowany w formacie json (utworzony z tablicy wielowymiarowej) dla skryptu „wp-plupload” (zauważ, że będzie to dostępne w 3.4)

  • Podczas rejestrowania / kolejkowania skryptów i stylów Dodawanie danych dla domyślnych skryptów ( wp-includes/script-loader.php)

Po przeczytaniu zastosowania tej metody nie wydaje się, aby miała określony przypadek użycia. W wp_plupload_default_settings, wydaje się, aby umożliwić wstrzyknięcie dowolnego danych. W wp_register_scriptwydaje się być wykorzystywane do rozróżniania skrypty nagłówka i stopki. W add_inline_stylesłuży do oznaczenia stylu wbudowanego, który należy dodać po kolejkowaniu określonego arkusza stylów.

Doskonałym zastosowaniem tej funkcji byłby coś w rodzaju następującego kodu, w którym kolejkujesz zewnętrzny skrypt, ale musisz wysłać mu kilka zmiennych konfiguracyjnych, z których niektóre pochodzą z bazy danych:

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

Spowoduje to:

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

Zauważ, że nie można tego osiągnąć, wp_localize_scriptponieważ addthis_shareobiekt ma właściwości we właściwościach ( wcześniej pisałem o tym nieco pospiesznym obejściu ).

EDYCJA: Myliłem się, stwierdzając to. wp_localize_scriptdobrze sobie radzi z tablicami wielowymiarowymi.

Ta metoda wydaje się działać naprawdę dobrze z następujących powodów:

  1. Pozwala na dołączenie danych do uchwytu skryptu, dzięki czemu jest zawsze odpowiednio kolejkowane w skrypcie. Co więcej, będzie inteligentna w zakresie usuwania kolejki skryptu, kolejności i umiejscowienia skryptu.
  2. Pozwala używać PHP do wysyłania varsów do JS.
  3. Wydaje się, że jest to bardziej zorganizowane niż używanie wp_print_stylesdo drukowania dowolnego skryptu, na który działa później skrypt w kolejce.

Są pewne rzeczy, które nie działają zgodnie z oczekiwaniami, co martwi mnie o tę metodę. Jednym z takich problemów jest to, że jeśli używasz wp_localize_scriptrazem $wp_scripts->add_data, możesz uzyskać nieoczekiwane wyniki. Na przykład:

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

Produkuje:

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

Podczas gdy ten skrypt:

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

Produkuje:

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

dataKluczem, który jest ustalany przez wp_localize_scriptostatecznie zastępowane przez wywołanie $wp_scripts->add_data, natomiast jeśli zadzwonić wp_localize_scriptdwa razy w tym samym skrypcie, ciąg będzie prawidłowo łączone.

Chociaż wszystko to jest naprawdę przydatnym sposobem drukowania dowolnego skryptu do użycia z kolejkowanym skryptem, sprawia, że ​​myślę, że nie powinien być szeroko stosowany ze względu na potencjał konfliktów. Z pewnością widzę argument za użyciem tego w projektach osobistych, w których kod nie będzie używany we wtyczkach / motywach społeczności.

Spojrzałem również na Core Trac, aby sprawdzić, czy istnieją jakieś wskazówki co do celu tej funkcji. Znalazłem jeden bilet (http://core.trac.wordpress.org/ticket/11520) (epicki jeden), który badał inne sposoby dodawania dowolnego JS. Wydaje się więc, że istnieje interes w stworzeniu lepszego sposobu dodawania dowolnego JS, ale nie jestem pewien, czy add_datapowinien być częścią tego procesu.

Moje główne pytanie brzmi: czy programiści powinni korzystać z tej funkcji? W niektórych przypadkach (np. wp_register_script) Wydaje się, że jest to funkcja „prywatna”, z której nie powinny korzystać osoby trzecie; jednak w innych przypadkach (np. wp_plupload_default_settings) wydaje się to całkowicie rozsądnym sposobem wstrzyknięcia dowolnego JS przed kolejkowanym skryptem.

Nie sądzę, że istnieje „poprawna” odpowiedź na to pytanie, ale chciałbym usłyszeć, co myślą inni twórcy. Wyobrażam sobie również, że w tej układance są elementy, które całkowicie zaniedbałem i chciałbym usłyszeć, co mają do powiedzenia inni.

tollmanz
źródło

Odpowiedzi:

4

Ta funkcja dodaje dane do skryptów / stylów, które zostały umieszczone w kolejce podczas ładowania WordPress.

Nie całkiem. Dodaje dane do istniejących skryptów / stylów registered.

Ustawiony klucz danych wp_localize_scriptjest ostatecznie nadpisany przez wywołanie do $wp_scripts->add_data, natomiast jeśli wywołasz wp_localize_scriptdwukrotnie dla tego samego skryptu, łańcuch zostanie poprawnie połączony.

Dobrze. Oba wywołują podstawowy (niedostępny, wewnętrzny) interfejs API, więc zostaje on nadpisany (jak już wspomniano). Dzieje się tak, gdy dzwoni $this->get_data( $handle, 'data' );.

Pytanie

Moje główne pytanie brzmi: czy programiści powinni korzystać z tej funkcji?

Odpowiedź

Mówiąc wprost: Tak, kiedy nie masz innej szansy na zrobienie tego, czego potrzebujesz.

Kolejny przykład: sprawdź, czy skrypt został zarejestrowany (np. json2/jquery) I przenieś go do stopki (sprawdź 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 );

Uwaga: Ten ↑ działa tylko w przypadku danych zapisanych pod extra!

Dodatkowe uwagi

Kontr-pytanie: Czy kiedykolwiek próbowałeś dodać zależności do skryptów zarejestrowanych przez rdzeń? Na przykład: Spróbuj dodać JSON2zależnie od potrzeb jQuery. Nie jest to możliwe bez przechwycenia 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 );
}

Jest cała masa rzeczy, których klasa nie może zrobić. Więc przy użyciu coś jak ->add_data()to imo w pełni aktualny. Po prostu skorzystaj z tego, co masz, ponieważ wciąż jest to lepsze niż życie z brakiem podstawowych klas.

kajzer
źródło
„Poczekaj, aż rdzeń doda możliwość dodania zależności do domyślnych i wbudowanych skryptów” Czy otworzyłeś bilet w trac?
scribu
@scribu Dzięki, ale nie, nie mam i nie, nie będę. Wszystkie moje bilety po prostu tam gniją, więc wycofałem się z inwestowania w bilety trac. To bez obrazy, po prostu wniosek z tego, czego do tej pory doświadczyłem. Ale żeby nie zaczynać się z tobą kłócić, usunę go, ponieważ jest to po prostu kopia / wklej z jednej z moich wtyczek.
kaiser
Cóż, więc chyba będę musiał zapytać tutaj: jaka byłaby korzyść z załadowania JSON2 przed jQuery?
scribu
Nic, bo to abstrakcyjny przykład. Jeśli spróbujesz znaleźć bardziej szczegółowy przykład, możesz wyobrazić sobie jedną bibliotekę, która potrzebuje JSON2, ale także musi zostać załadowana wcześniej jQuery: Nazwijmy ją UberjQuery. Btw: Ponieważ dobrze sobie radzisz z zagłębianiem się w rdzeń, dlaczego nie poświęcisz czasu i nie napiszesz odpowiedzi? Myślę, że warto byłoby przeczytać.
kaiser
Dzięki za twoje przemyślenia Kaiser! Zdecydowanie szukam metod dodawania JS obsługiwanego przez „API”. Chociaż wiem, że mogę go naginać, aby robić różne rzeczy, może to prowadzić do niestabilnego kodu. Miło jest wiedzieć, do czego jest przeznaczony, a nie co może zrobić, a na pewno wiele można z tym zrobić.
tollmanz
1

W WP 3.3 odbyła się duża debata na temat obsługi danych skryptu:

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

Pamiętaj, że możesz teraz przekazywać zagnieżdżone tablice wp_localize_data():

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

Tak więc skorzystałbym, add_data()gdyby nie było interfejsu API wyższego poziomu do tego, co musiałem zrobić, przy założeniu, że jego zachowanie może się zmienić w niektórych przypadkach skrajnych, na przykład w przypadku konkatenacji.

scribu
źródło
Dziękujemy za wkład Scribu! Zabawne, że link do tego biletu! Podłączyłem do niego w swoim poście, ale działo się tak wiele, że nie zrozumiałem, że tablice wielowymiarowe są teraz obsługiwane.
tollmanz
Ha ... niezła edycja! Ten bilet nie był tak zdezorientowany, jak myślałem.
tollmanz
@tollmanz Tak, to dość mylące, szczególnie jeśli nie byłeś wtedy w IRC.
scribu
Pan @ungestaltbar pokazał mi sposób na dodanie wielowymiarowych tablic jakiś miesiąc temu. Nie wiedziałem, że to już sedno.
kaiser
@scribu - czy nie ma już obsługi tablic wielowymiarowych? - przynajmniej używam ich bez żadnych problemów ...
Stephen Harris