Sollten Dritte $ wp_scripts / $ wp_styles-> add_data verwenden?

31

Innerhalb der WP_DependenciesKlasse existiert eine Methode namens add_data. Diese Funktion fügt Daten zu Skripten / Stilen hinzu, die beim Laden von WordPress in die Warteschlange gestellt wurden. Eine häufig verwendete Verwendung dieser Funktion ist das Hinzufügen einer Bedingung, wenn Stylesheets hinzugefügt werden, die auf verschiedene Versionen des IE abzielen. Zum Beispiel, um IE8 und niedriger anzuvisieren:

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

Dies wird dargestellt als:

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

Wenn ich durch Core schaue, sehe ich einige Stellen, an denen diese Methode angewendet wird:

  • WP_Styles->add_inline_style(): fügt nach dem referenzierten Stylesheet einen Inline-Stil hinzu (erfolgt über WP_Styles->print_inline_style())

  • WP_Scripts->localize(): fügt ein json-codiertes Objekt hinzu (umhüllt von der wp_localize_script()Funktion "public" )

  • wp_plupload_default_settings() : fügt ein json-codiertes Objekt (erstellt aus einem mehrdimensionalen Array) für das 'wp-plupload'-Skript hinzu (beachte, dass dies in 3.4 erscheinen wird)

  • Beim Registrieren / Einreihen von Skripten und Stilen Hinzufügen von Daten für Standardskripten ( wp-includes/script-loader.php)

Nach dem Lesen der Verwendungen der Methode scheint es keinen bestimmten Anwendungsfall zu geben. In wp_plupload_default_settings, scheint es für beliebige Daten Injektion zu ermöglichen. In wp_register_scriptscheint es verwendet zu werden, um zwischen Kopf- und Fußzeilenskripten zu unterscheiden. In add_inline_stylewird es verwendet, um den Inline-Stil zu kennzeichnen, der hinzugefügt werden soll, nachdem ein bestimmtes Stylesheet in die Warteschlange gestellt wurde.

Eine hervorragende Verwendung für diese Funktion wäre der folgende Code, in dem Sie ein externes Skript in die Warteschlange stellen, ihm jedoch einige Konfigurationsvariablen senden müssen, von denen einige aus der Datenbank stammen:

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

Dies führt zu:

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

Beachten Sie, dass dies nicht möglich ist, wp_localize_scriptda das addthis_shareObjekt Eigenschaften innerhalb von Eigenschaften hat ( ich habe vorher über eine etwas hackige Art und Weise darüber geschrieben ).

EDIT: Ich habe mich geirrt. wp_localize_scriptbehandelt mehrdimensionale Arrays ganz gut.

Diese Methode scheint aus folgenden Gründen sehr gut zu funktionieren:

  1. Sie können die Daten an das Skript-Handle anhängen, damit sie immer ordnungsgemäß in die Skript-Warteschlange eingereiht werden. Darüber hinaus wird es intelligent sein, das Skript, die Skriptreihenfolge und die Skriptplatzierung zu deaktivieren.
  2. Sie können PHP verwenden, um Variablen an JS zu senden.
  3. Es scheint organisierter zu sein, als wp_print_stylesein beliebiges Skript auszudrucken, das später von einem Skript in der Warteschlange bearbeitet wird.

Es gibt einige Dinge, die nicht wie erwartet funktionieren, was mich an dieser Methode beunruhigt. Ein solches Problem ist, dass Sie unerwartete Ergebnisse erzielen können , wenn Sie wp_localize_scriptzusammen mit verwenden $wp_scripts->add_data. Zum Beispiel:

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

Produziert:

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

Während dieses Skript:

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

Produziert:

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

Der von datagesetzte Schlüssel wp_localize_scriptwird letztendlich durch den Aufruf von überschrieben. $wp_scripts->add_dataWenn Sie wp_localize_scriptdasselbe Skript zweimal aufrufen , wird die Zeichenfolge ordnungsgemäß verkettet.

All dies ist eine sehr praktische Methode, um ein beliebiges Skript für ein Skript in der Warteschlange zu drucken. Ich bin jedoch der Meinung, dass es aufgrund des Konfliktpotenzials nicht häufig verwendet werden sollte. Ich kann sicherlich ein Argument dafür sehen, dass dies in persönlichen Projekten verwendet wird, in denen der Code nicht in Community-Plugins / -Themen verwendet wird.

Ich habe mir auch Core Trac angesehen, um festzustellen, ob es Hinweise auf den Zweck der Funktion gibt. Ich fand ein Ticket (http://core.trac.wordpress.org/ticket/11520) (ein episches dazu), das andere Möglichkeiten zum Hinzufügen von willkürlichem JS untersuchte. Es scheint also ein Interesse daran zu bestehen, einen besseren Weg zu finden, um willkürliche JS hinzuzufügen, aber nicht sicher, ob genau add_datadies Teil des Prozesses sein sollte.

Meine Hauptfrage ist: Sollen Entwickler diese Funktion nutzen? In einigen Fällen (z. B. wp_register_script) scheint es sich um eine "private" Funktion zu handeln, die Dritte nicht verwenden sollten. In anderen Fällen (z. B. wp_plupload_default_settings) scheint es jedoch eine durchaus vernünftige Möglichkeit zu sein, willkürlichen JS-Code vor einem Skript in der Warteschlange einzufügen.

Ich kann mir nicht vorstellen, dass es eine "richtige" Antwort darauf gibt, würde aber gerne hören, was andere Entwickler denken. Ich stelle mir auch vor, dass es Teile dieses Puzzles gibt, die ich völlig vernachlässigt habe, und würde gerne hören, was andere dazu zu sagen haben.

tollmanz
quelle

Antworten:

4

Diese Funktion fügt Daten zu Skripten / Stilen hinzu, die beim Laden von WordPress in die Warteschlange gestellt wurden.

Nicht wirklich. Es fügt Daten zu Skripten / Stilen hinzu, die bereits vorhanden waren registered.

Der von gesetzte Datenschlüssel wp_localize_scriptwird letztendlich durch den Aufruf von überschrieben. $wp_scripts->add_dataWenn Sie wp_localize_scriptdasselbe Skript zweimal aufrufen , wird die Zeichenfolge ordnungsgemäß verkettet.

Recht. Beide rufen die zugrunde liegende (nicht zugreifbare, interne) API auf, sodass sie überschrieben wird (wie Sie angegeben haben). Dies passiert, wenn es anruft $this->get_data( $handle, 'data' );.

Frage

Meine Hauptfrage ist: Sollen Entwickler diese Funktion nutzen?

Antworten

Einfach gesagt: Ja, wenn Sie keine andere Chance haben, das zu tun, was Sie brauchen.

Ein weiteres Beispiel: Prüfen Sie, ob ein Skript registriert wurde (zB json2/jquery) und verschieben Sie es in die Fußzeile (check 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 );

Hinweis: Dies ↑ funktioniert nur für Daten, die unter abgelegt wurden extra!

Zusätzliche Bemerkungen

Gegenfrage: Haben Sie jemals versucht, Abhängigkeiten zu Skripten hinzuzufügen, die von core registriert wurden? Zum Beispiel: Versuchen Sie, nach JSON2Bedarf Abhängigkeiten hinzuzufügen jQuery. Dies ist nicht möglich, ohne Folgendes abzufangen 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 );
}

Es gibt eine ganze Menge Dinge, die die Klasse nicht kann. So etwas zu benutzen ->add_data()ist imo völlig gültig. Verwenden Sie einfach das, was Sie haben, denn es ist immer noch besser, als den Mangel an Kernklassen zu leben.

Kaiser
quelle
"Warten Sie, bis der Core die Möglichkeit bietet, Abhängigkeiten zu Standard- und integrierten Skripten hinzuzufügen." Haben Sie ein Ticket in trac geöffnet?
Scribu
@scribu Danke, aber nein, habe ich nicht und nein, werde ich nicht. Alle meine Tickets verrotten einfach dort, also habe ich mich von der Investition in Trac-Tickets zurückgezogen. Das ist keine Beleidigung, einfach eine Schlussfolgerung aus dem, was ich bisher erlebt habe. Aber um nicht mit Ihnen zu streiten, werde ich es entfernen, da dies nur von einem einfachen Kopieren / Einfügen aus einem meiner Plugins übrig bleibt.
Kaiser
Nun, dann muss ich mich wohl fragen: Was würde das Laden von JSON2 vor jQuery bringen?
Scribu
Nichts, als abstraktes Beispiel. Wenn Sie versuchen würden, ein detaillierteres Beispiel zu finden, könnten Sie sich eine Bibliothek vorstellen, die benötigt wird JSON2, aber auch zuvor geladen werden muss jQuery: Nennen wir sie UberjQuery. Btw: Da Sie mit Diggin 'in Core ziemlich gut zurechtkommen, warum nehmen Sie sich nicht die Zeit und schreiben eine Antwort? Ich denke, es wäre die Zeit wert, gelesen zu werden.
Kaiser
Danke für deine Gedanken Kaiser! Ich bin auf jeden Fall auf der Suche nach Methoden zum Hinzufügen von JS, die von der "API" unterstützt wird. Obwohl ich weiß, dass ich es biegen kann, um alle möglichen Dinge zu tun, kann dies zu instabilem Code führen. Es ist schön zu wissen, wofür es gedacht ist, anstatt zu wissen, was es kann, und mit ihm kann sicherlich viel getan werden.
tollmanz
1

In WP 3.3 gab es eine große Debatte über den Umgang mit Skriptdaten:

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

Beachten Sie, dass Sie können verschachtelte Arrays zu übergeben wp_localize_data()jetzt:

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

Ich würde also verwenden, add_data()wenn es keine API auf höherer Ebene für das geben würde, was ich tun müsste , mit dem Verständnis, dass sich das Verhalten in einigen Randfällen ändern könnte, z. B. wenn Verkettung involviert ist.

scribu
quelle
Vielen Dank für Ihre Eingabe Scribu! Komisch, dass Sie auf dieses Ticket verlinken! Ich habe in meinem Post darauf verlinkt, aber es war so viel los, dass ich nicht begriffen habe, dass jetzt mehrdimensionale Arrays unterstützt werden.
tollmanz
Ha ... schön bearbeitet! Ich war von diesem Ticket nicht so verwirrt, wie ich dachte.
tollmanz
@tollmanz Ja, es ist ziemlich verwirrend, besonders wenn Sie zu der Zeit nicht im IRC waren.
Scribu
Herr @ungestaltbar hat mir vor einigen Monaten einen Weg gezeigt, mehrdimensionale Arrays hinzuzufügen. Wusste nicht, dass das schon im Kern ist.
Kaiser
@scribu - Gibt es keine Unterstützung für mehrdimensionale Arrays? - Zumindest benutze ich sie ohne Probleme ...
Stephen Harris