Wann wird add_action ('init') vs add_action ('wp_enqueue_scripts') verwendet?

10

In der functions.php meines Themas rufe ich eine add_action auf, um ein gewisses Maß an Kontrolle darüber zu erlangen, wo jquery geladen wird (in der Fußzeile zusammen mit den anderen Skripten meines Themas).

Das Problem, das ich habe, ist, dass wenn ich add_action ('wp_enqueue_scripts') verwende, es nur dann ausgelöst wird, wenn keine Plugins geladen sind. Die Methode add_action ('init') funktioniert jedoch in allen Fällen.

Ich kann mich nicht erinnern warum, aber ich glaube, dass add_action ('wp_enqueue_scripts') in diesem Fall bevorzugt wird. Wenn das stimmt, wie kann ich es in allen Fällen zum Laufen bringen?

In functions.php

//if(!is_admin()){add_action('init', 'my_theme_init');} //THIS WORKS ALL THE TIME
//add_action('wp_enqueue_scripts', 'my_theme_init'); //THIS ONLY WORKS WHEN NO PLUGINS PRESENT

if(!is_admin())
{
    require_once(TEMPLATEPATH . '/functions_public.php');   
}

In functions_public.php

function my_theme_init()
{

/* PREVENT DUPLICATE COPIES OF JQUERY FROM PLUGINS
**************************************************/
wp_deregister_script('jquery');

/* LOAD THE LOCAL WORDPRESS COPY OF JQUERY AND THEME CUSTOM SCRIPTS IN THE FOOTER
***********************************************/
wp_register_script('jquery', get_bloginfo('template_directory').'/scripts.mythemescripts.js',false,false,true);

wp_enqueue_script('jquery');

}

Die zweite Methode, die add_action ('wp_enqueue_scripts') verwendet, wird anscheinend nicht unter Bedingungen ausgeführt, unter denen ein Plugin vorhanden ist, das Skriptabhängigkeiten zum Thema schreibt.

N2Mystic
quelle
5
Bitte registrieren Sie nicht Ihre eigene Kopie von jquery - verwenden Sie die mit WordPress gelieferte Version, sonst brechen Sie Plug-Ins :)
Stephen Harris
Ich stimme zu, tatsächlich verwende ich die mit jQuery gelieferte. Ich lade es einfach in eine einzelne .js (mythemescripts.js) zusammen mit den anderen js-Dateien, die mein Thema benötigt, um http-Anfragen zu reduzieren.
N2Mystic
Sobald das Skript in allen Browsern einmal von Ihrer Site angefordert wurde, wird es lokal zwischengespeichert. Sie erhalten die zusätzliche HTTP-Anforderung nur beim Laden der ersten Seite. Wenn Sie alle Skripte zu einem einzigen kombinieren, müssen Sie dies jedes Mal ändern, wenn WP ein Update mit einer neuen Version von jQuery veröffentlicht. Dies == Wartungsalptraum.
EAMann
2
@EAMann, wenn das Thema zum ersten Mal installiert wird und jedes Mal, wenn meine Seite mit den Themenoptionen danach gespeichert wird, schreibe ich die Datei mythemescripts.js neu und lade die neueste Kopie der jquery-Bibliothek hinein. Wenn der Benutzer seine WP-Version aktualisiert, lädt meine Routine für Themenoptionen die dazugehörige Abfrage. Es ist immer auf dem neuesten Stand.
N2Mystic
Das Problem tritt immer noch auf, wenn ein JQuery-Aufruf im Hauptteil des Dokuments vor der Fußzeile enthalten ist. Anscheinend wird jQuery (Dokument) bereits ausgelöst, bevor das Skript .js in die Fußzeile geladen wird.
N2Mystic

Antworten:

26

Viele Plugin-Entwickler machen die Dinge nicht richtig. Der richtige Weg ist, sich anzuschließen, wp_enqueue_scriptswie Sie es versuchen.

Hier ist jedoch die Reihenfolge der Hooks, die in einer typischen Anforderung ausgeführt werden:

  • muplugins_loaded
  • registrierte_Taxonomie
  • register_post_type
  • plugins_loaded
  • sanitize_comment_cookies
  • setup_theme
  • load_textdomain
  • after_setup_theme
  • auth_cookie_malformed
  • auth_cookie_valid
  • set_current_user
  • drin
  • widgets_init
  • register_sidebar
  • wp_register_sidebar_widget
  • wp_default_scripts
  • wp_default_stypes
  • admin_bar_init
  • add_admin_bar_menus
  • wp_loaded
  • parse_request
  • send_headers
  • parse_query
  • pre_get_posts
  • posts_selection
  • wp
  • template_redirect
  • get_header
  • wp_head
  • wp_enqueue_scripts
  • wp_print_styles
  • wp_print_scripts
  • ... eine Menge mehr

Die Sache ist, dass ursprünglich mehreren Entwicklern gesagt wurde, sie sollten sich anschließen, initum ihre Skripte in die Warteschlange zu stellen. Bevor wir einen wp_enqueue_scriptHaken hatten, war dies die "richtige" Art, Dinge zu tun, und Tutorials, die die Praxis fortsetzen, schweben immer noch im Internet herum und korrumpieren ansonsten gute Entwickler.

Meine Empfehlung wäre, Ihre Funktion in zwei Teile aufzuteilen. Machen Sie Ihr wp_deregister_script/ wp_register_scriptam initHaken und verwenden Sie den wp_enqueue_scriptsHaken, wenn Sie jQuery tatsächlich in die Warteschlange stellen.

Dies hält Sie in der Welt des "richtigen Handelns" für das Einreihen Ihrer Skripte und schützt Sie vor den Hunderten von Entwicklern, die es immer noch "falsch machen", indem Sie jQuery gegen Ihre verkettete Version austauschen, bevor sie es der Warteschlange hinzufügen .

Sie möchten auch Ihren initHaken mit einer hohen Priorität hinzufügen :

add_action( 'init', 'swap_out_jquery', 1 );
function swap_out_jquery() {
    // ...
}
EAMann
quelle
2
Ich wollte dies empfehlen, aber dann wurde mir klar, dass das OP jQuery tatsächlich abmeldete und dann ein anderes Skript vollständig registrierte und es "jquery" nannte. Ich denke nicht, dass dies eine gute Vorgehensweise ist, um zu ermutigen, und ich denke, dass ein besserer Weg einfach darin besteht, jQuery vollständig aus der Warteschlange zu entfernen und dann das benutzerdefinierte Skript mithilfe eines benutzerdefinierten Handles in die Warteschlange zu stellen .
Chip Bennett
Beachten Sie das priorityHinzufügen von Aktionen. Es hängt alles davon ab, wie Sie die Priorität anzeigen. Wenn Sie möchten, dass Ihre "zuerst" ausgeführt wird, ist eine niedrigere Nummer besser - eine höhere Priorität in der Reihenfolge der Ausführungswarteschlangen. Wenn Sie jedoch möchten, dass der Effekt Ihrer Funktion Vorrang vor anderen hat, möchten Sie, dass er später ausgeführt wird - also eine höhere Priorität durch "Effekt". Und in diesem Fall ist es wahrscheinlich eine höhere Zahl, die Sie möchten. Obwohl es wenig sinnvoll ist, die RTM-Version von jquery auszutauschen, wie der vorherige Kommentator vorschlägt.
Paul G.
3

Hier gibt es mehrere Probleme, die miteinander zusammenhängen.

  1. Der richtige Aktions-Hook zum Einreihen von Skripten ist wp_enqueue_scripts
  2. Um Skripte in der Fußzeile über zu drucken wp_enqueue_script(), setzen Sie den $footerParameter auftrue
  3. Ihre add_action( $hook, $callback )Anrufe sollten in nichts eingewickelt sein; Lassen Sie sie direkt von ausführenfunctions.php
  4. Sie sollten Ihre is_admin()bedingten Prüfungen in Ihren Rückruf einfügen
  5. Sie sollten Core-Bundle-Skripte aus irgendeinem Grund nicht von einem Theme abmelden. Selbst wenn Ihr Zweck die Skriptverkettung ist, ist dies das Gebiet des Plugins .
  6. Wenn Sie müssen deregistrieren jquery, dann wp_enqueue_scriptsist zu spät . Teilen Sie Ihren Abmelde- / Registrierungscode in einen Rückruf auf, der angeschlossen ist init.
  7. Einig Aufruf andere Skript „jquery“ ist auch wahrscheinlich keine gute Praxis. Ihre bessere Wahl wäre einfach, jQuery aus der Warteschlange zu entfernen und dann Ihr benutzerdefiniertes Skript zu laden.
  8. Stellen Sie sicher, dass Ihr Rückruf eine niedrige Priorität hat, damit Sie Plugins überschreiben
  9. Verwenden Sie get_template_directory()eher alsTEMPLATEPATH

Alles zusammen:

<?php
function wpse55924_enqueue_scripts() {
    if ( ! is_admin() ) {

        // Dequeue jQuery
        wp_dequeue_script( 'jquery' );

        // Register/enqueue a custom script, that includes jQuery
        wp_register_script( 'mythemescripts', get_template_directory_uri() . '/scripts.mythemescripts.js', false, false,true );
        wp_enqueue_script( 'mythemescripts' ); 
    }
}
add_action( 'wp_enqueue_scripts', 'wpse55924_enqueue_scripts', 99 );

Aber nochmal: Dies ist wirklich nicht der beste Ansatz. Am besten entfernen Sie einfach die Rückrufe des Plugins add_action (), mit denen die Registrierung von Core-jQuery aufgehoben wird, oder verwenden Plugins, die nicht so rücksichtslos sind wie das Ersetzen von Core-Bundled-jQuery.

Chip Bennett
quelle
Das OP kombiniert die WP-verteilte Version von jQuery programmgesteuert mit einigen anderen Skripten, sodass sein Thema nur eine HTTP-Anforderung zum Laden aller JS-Dateien stellt. Die benutzerdefinierten Skripte enthalten also jQuery und beschädigen nichts, wenn sie auf diese Weise geladen werden. Das Überschreiben des registrierten 'jquery'-Handles ist erforderlich, um zu verhindern, dass jQuery zweimal geladen wird - einmal in der kombinierten JS-Datei und erneut durch Plugins, die versuchen, jQuery selbst in die Warteschlange zu stellen.
EAMann
Es ist semantisch und praktisch _doing_it_wrong(), etwas, das nicht nur jQuery ist, "jQuery" zu nennen. Außerdem: jQuery selbst kann einfach aus der Warteschlange entfernt werden, um sicherzustellen, dass es nicht zweimal geladen wird. Der wp_dequeue_script()Anruf muss nur mit einer ausreichenden Priorität erfolgen, um sicherzustellen, dass er danach nicht mehr in die Warteschlange gestellt wird.
Chip Bennett