Kiedy używać add działań („init”) vs add działań („wp_enqueue_scripts”)

10

W function.php mojego motywu nazywam add działań, aby uzyskać kontrolę nad tym, gdzie ładowana jest jquery (w stopce wraz z innymi skryptami mojego motywu).

Problem, jaki mam, polega na tym, że kiedy używam add działań („wp_enqueue_scripts”), wydaje się, że jest uruchamiany tylko wtedy, gdy nie są załadowane żadne wtyczki. Jednak metoda add Działalności („init”) działa we wszystkich przypadkach.

Nie pamiętam, dlaczego, ale uważam, że w tym przypadku preferowane jest działanie dodatkowe („wp_enqueue_scripts”). Jeśli to prawda, jak mogę sprawić, by działał we wszystkich przypadkach?

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

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

}

Druga metoda, wykorzystująca add działań („wp_enqueue_scripts”) najwyraźniej nie jest wykonywana w warunkach, w których występuje wtyczka, która wypisuje zależności skryptu od motywu.

N2Mystic
źródło
5
Proszę nie rejestrować własnej kopii jquery - użyj wersji dostarczonej z WordPress, w przeciwnym razie skończysz na łamaniu wtyczek :)
Stephen Harris
Zgadzam się, faktycznie używam tego dostarczonego z jQuery. Właśnie ładuję go do pojedynczego pliku .js (mythemescripts.js) wraz z innymi plikami js, których potrzebuje mój motyw, aby zmniejszyć liczbę żądań HTTP.
N2Mystic
We wszystkich przeglądarkach, gdy skrypt zostanie pobrany z Twojej witryny raz, jest on buforowany lokalnie. Będziesz mieć tylko dodatkowe żądanie HTTP przy pierwszym ładowaniu strony. Jeśli połączysz wszystkie skrypty w jeden, będziesz zmuszony to zmienić za każdym razem, gdy WP wyda aktualizację z nową wersją jQuery. To == koszmar konserwacji.
EAMann
2
@EAMann, kiedy motyw jest instalowany po raz pierwszy i za każdym razem, gdy moja strona opcji motywu jest zapisywana, przepisuję plik mythemescripts.js, ładując do niego najnowszą kopię biblioteki jquery. Jeśli użytkownik zaktualizuje swoją wersję WP, moja procedura opcji motywu ładuje dołączoną do niej jquery. To jest zawsze aktualne.
N2Mystic
Problem nadal występuje, gdy wywołanie jquery znajduje się w treści dokumentu przed stopką. Najwyraźniej jQuery (dokument) .ready jest uruchamiany, zanim skrypt .js zostanie załadowany do stopki.
N2Mystic

Odpowiedzi:

26

Wielu programistów wtyczek nie robi rzeczy we właściwy sposób. Prawo sposobem jest hak na wp_enqueue_scriptsjak starasz się zrobić.

Oto kolejność haków uruchamianych w typowym żądaniu:

  • muplugins_loaded
  • zarejestrowana taksonomia
  • zarejestrowany_typ_postu
  • plugins_loaded
  • sanitize_comment_cookies
  • setup_theme
  • load_textdomain
  • po_setup_theme
  • auth_cookie_malformed
  • auth_cookie_valid
  • set_current_user
  • w tym
  • 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
  • szablon_redirect
  • get_header
  • wp_head
  • wp_enqueue_scripts
  • wp_print_styles
  • wp_print_scripts
  • ... dużo więcej

Chodzi o to, że kilku programistom pierwotnie powiedziano, aby przyłączyli się do initkolejkowania swoich skryptów. Wcześniej, zanim mieliśmy wp_enqueue_scripthaczyk, był to „właściwy” sposób robienia rzeczy, a samouczki podtrzymujące tę praktykę wciąż krążą w Internecie, niszcząc w przeciwnym razie dobrych programistów.

Radzę podzielić twoją funkcję na dwie części. Wykonaj wp_deregister_script/ wp_register_scriptna inithaku i użyj wp_enqueue_scriptshaka, gdy faktycznie kolejkujesz jQuery.

Dzięki temu będziesz w świecie „robienia tego dobrze” przy kolejkowaniu skryptów i pomoże chronić cię przed setkami programistów, którzy nadal „robią to źle”, zamieniając jQuery na twoją skonkatenowaną wersję, zanim dodadzą ją do kolejki .

Będziesz także chciał dodać inithak o wysokim priorytecie:

add_action( 'init', 'swap_out_jquery', 1 );
function swap_out_jquery() {
    // ...
}
EAMann
źródło
2
Chciałem to polecić, ale potem zdałem sobie sprawę, że OP faktycznie wyrejestrowuje jQuery, a następnie rejestruję całkowicie inny skrypt i nazywam go „jquery”. Nie sądzę, że jest to dobra praktyka zachęcania i uważam, że lepszym rozwiązaniem byłoby po prostu całkowite usunięcie jQuery , a następnie kolejkowanie niestandardowego skryptu za pomocą niestandardowego uchwytu .
Chip Bennett,
Wskaż notatkę o prioritydodawaniu akcji. Wszystko zależy od tego, jak widzisz priorytet. Jeśli chcesz, aby Twój „działał jako pierwszy”, lepsza jest mniejsza liczba - wyższy priorytet w kolejce wykonywania. Ale jeśli chcesz, aby efekt twojej funkcji miał pierwszeństwo przed innymi, będziesz chciał, aby działała później - więc wyższy priorytet ma „efekt”. I w tym przypadku jest to prawdopodobnie wyższa liczba, niż chcesz. Mimo że zamiana jquery w RTM jest niewielka, jak sugeruje poprzedni komentator.
Paul G.
3

Istnieje wiele problemów, które są ze sobą powiązane.

  1. Prawidłowym hakiem akcji używanym do kolejkowania skryptów jest wp_enqueue_scripts
  2. Aby drukować skrypty w stopce za pomocą wp_enqueue_script(), ustaw $footerparametr natrue
  3. Wasze add_action( $hook, $callback )rozmowy nie powinny być w nic zamknięte; niech wykonują bezpośrednio zfunctions.php
  4. Powinieneś umieścić is_admin()kontrole warunkowe w swoim callbacku
  5. Z jakiegokolwiek powodu nie powinieneś wyrejestrowywać skryptów powiązanych z rdzeniem z motywu. Nawet jeśli Twoim celem jest konkatenacja skryptu, jest to terytorium wtyczki .
  6. Jeśli musisz wyrejestrować jquery, wp_enqueue_scriptsjest już za późno . Podziel swój kod wyrejestrowania / rejestru na zaczepione połączenie zwrotne init.
  7. Nazywanie innych skryptów „jquery” również prawdopodobnie nie jest dobrą praktyką. Lepiej byłoby po prostu usunąć kolejkę z jQuery , a następnie załadować własny skrypt.
  8. Pamiętaj, aby ustawić niski priorytet na oddzwanianie, aby zastąpić wtyczki
  9. Użyj get_template_directory()raczej niżTEMPLATEPATH

Kładąc wszystko razem:

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

Ale znowu: to nie jest najlepsze podejście. Lepiej jest po prostu usunąć wywołania zwrotne add action (), które wyrejestrowują rdzeń jQuery - lub używają wtyczek, które nie robią czegoś tak lekkomyślnego, jak zastąpienie pakietu jQuery w pakiecie.

Chip Bennett
źródło
OP łączy programowo wersję jQuery rozpowszechnianą przez WP z kilkoma innymi skryptami programowo, dzięki czemu jego temat wysyła tylko jedno żądanie HTTP, aby załadować wszystkie pliki JS. Skrypty niestandardowe zawierają jQuery i niczego nie zepsują, jeśli zostaną w ten sposób załadowane. Nadpisanie zarejestrowanego uchwytu „jquery” jest konieczne, aby zapobiec dwukrotnemu załadowaniu jQuery - raz w połączonym pliku JS i ponownie przez dowolne wtyczki próbujące samodzielnie zamaskować jQuery.
EAMann
Semantycznie i praktycznie _doing_it_wrong()jest nazywanie czegoś, co nie jest po prostu jQuery, „jQuery”. Ponadto: samą aplikację jQuery można po prostu usunąć z kolejki , aby mieć pewność, że nie zostanie załadowana dwukrotnie. wp_dequeue_script()Wezwanie po prostu musi się dziać z wystarczającą priorytet, aby zapewnić, że nic go kolejkuje później.
Chip Bennett,