Jak kolejkować style / skrypty na niektórych stronach / wp-admin?

53

Mam dwie proste funkcje, które ładują rzeczy za pomocą wp_enqueue_style()i wp_enqueue_script(), coś takiego:

function admin_custom_css()
{ wp_enqueue_style( 'stylesheet_name', 'stylesheet.css') }; 

function admin_custom_js 
{ wp_enqueue_script( 'javascript_file', 'script.js') };

... i kilka stron administracyjnych utworzonych przy pomocy add_menu_page()iadd_submenu_page()

function my_menu() {
   add_menu_page('Page 1', 'bar', 'something', 'else', 'foo');
   add_submenu_page( 'theme_menu', 'Subpage 1', 'Subpage', 'something', 'else', 'foo'); 
}
add_action('admin_menu', 'my_menu'); 

Jak załadować moje dwie funkcje tylko na tych stronach?

Obecnie używam:

add_action('admin_init', 'admin_custom_css' ); 
add_action('admin_init', 'admin_custom_js' );  

Ale ładuje moje pliki na każdej stronie administratora, co wcale nie jest przyjemne.

Czy mogę to zrobić za pomocą jednego prostego wiersza functions.phplub osobno umieszczać je w kolejce (wolę pierwszą opcję, ponieważ musiałbym edytować wiele funkcji tworzenia stron administracyjnych).

Dzięki!

Wordpressor
źródło

Odpowiedzi:

33

add_menu_pagei add_submenu_pageoba zwracają „przyrostek haka” strony, którego można użyć do identyfikacji strony za pomocą określonych haków. Jako taki, możesz użyć tego sufiksu w połączeniu ze zmiennymi zaczepami admin_print_styles-{$hook_suffix}i admin_print_scripts-{$hook_suffix}specjalnie ukierunkować te strony.

function my_menu() {
   $menu = add_menu_page( 'Page 1', 'bar', 'something', 'else', 'foo' );
   $submenu = add_submenu_page( 'theme_menu', 'Subpage 1', 'Subpage', 'something', 'else', 'foo' );

   add_action( 'admin_print_styles-' . $menu, 'admin_custom_css' );
   add_action( 'admin_print_styles-' . $submenu, 'admin_custom_css' );

   add_action( 'admin_print_scripts-' . $menu, 'admin_custom_js' );
   add_action( 'admin_print_scripts-' . $submenu, 'admin_custom_js' );
}

Uważam, że jest to czysta metoda dodawania tego wszystkiego, ponieważ wszystko jest obsługiwane w ramach jednej funkcji. Jeśli zdecydujesz się usunąć tę funkcję, po prostu usuń połączenie z jedną funkcją.

tollmanz
źródło
5
Ta odpowiedź nie jest poprawna technicznie. Codex dlaadmin_print_scripts() państw „ admin_print_scripts nie powinny być wykorzystywane do enqueue stylów i skryptów .” Odpowiedź @TomAuger jest w rzeczywistości poprawna, choć nie optymalna. Byłoby dobrze, gdyby zespół WP dodał admin_enqueue_scripts-(hookname)haczyk ...
David Gard
Znalezienie odpowiedzi, która była dla mnie bardzo pomocna, zajęło mi 3 dni :) Dzięki :)
Asfandyar Khan
@DavidGard, prawdopodobnie powinieneś spojrzeć na te developer.wordpress.org/reference/hooks/… , developer.wordpress.org/reference/hooks/…
hkchakladar
1
@hkchakladar Mój komentarz ma prawie cztery lata ... Jeśli nie ma już znaczenia, dodaj bardziej aktualny komentarz wyjaśniający dlaczego.
David Gard
61

Problem z odpowiedzią @tollmanz polega na tym, że ponieważ wyłapujesz haczyki -print-styles i -print-scripts, musisz wygenerować HTML, aby ręcznie załadować skrypty. Nie jest to optymalne, ponieważ nie dostajesz ładnej zależności i wersji, które są dostarczane z wp_enqueue_script()i wp_enqueue_style(). Nie pozwala także na umieszczenie rzeczy w stopce, jeśli jest to dla nich lepsze miejsce.

Wróćmy więc do pytania PO: jaki jest najlepszy sposób, aby zapewnić kolejkowanie JS / CSS tylko na określonych stronach administracyjnych?

  1. Wykonaj akcję „load - {$ my_admin_page}”, aby robić rzeczy tylko wtedy, gdy załadowana jest strona administratora konkretnej wtyczki, a następnie

  2. Odłącz akcję „admin_enqueue_scripts”, aby poprawnie dodać swoje wp_enqueue_scriptpołączenia.

Wydaje się to trochę uciążliwe, ale w rzeczywistości jest bardzo łatwe do wdrożenia. Z góry:

    add_action( 'admin_menu', 'add_my_admin_menus' ); // hook so we can add menus to our admin left-hand menu

    /**
     * Create the administration menus in the left-hand nav and load the JavaScript conditionally only on that page
     */
    function add_my_admin_menus(){
        $my_page = add_menu_page( 'Page Title', 'Menu Title', MY_ADMIN_CAPABILITY, 'menu-slug', 'show_page_content' );

        // Load the JS conditionally
        add_action( 'load-' . $my_page, 'load_admin_js' );
    }

    // This function is only called when our plugin's page loads!
    function load_admin_js(){
        // Unfortunately we can't just enqueue our scripts here - it's too early. So register against the proper action hook to do it
        add_action( 'admin_enqueue_scripts', 'enqueue_admin_js' );
    }

    function enqueue_admin_js(){
        // Isn't it nice to use dependencies and the already registered core js files?
        wp_enqueue_script( 'my-script', INCLUDES_URI . '/js/my_script.js', array( 'jquery-ui-core', 'jquery-ui-tabs' ) );
    }
}
Tom Auger
źródło
4
+1 - To jest droga do IMO. Indywidualne haki w przestrzeni nazw (someaction- $ hook) są przydatne dla 1 lub 2 akcji, ale jeśli tworzysz wtyczkę, może być konieczne wykonanie wielu różnych czynności tylko na stronach z opcjami, co sprawia, że ​​ta metoda jest naprawdę wygodna. Zazwyczaj po prostu dodaję 1 akcję do load-$hookhaka, która uruchamia moją option_page_actionsfunkcję, do której mogę dodać wiele innych haków / filtrów itp. Ponieważ te akcje są wywoływane tylko na wybranej stronie, haki poza tym punktem nie muszą używać haków z przestrzenią nazw (jak pokazano), który jest znacznie bardziej wydajny i intuicyjny.
Evan Mattson
Cześć, czy ten sposób jest nadal obsługiwany? load_admin_js nigdy nie dzwoni
IAmJulianAcosta
Jasne, że nadal jest obsługiwany. Wiersz 206 admin.php. Byłem tam od 2.6 i raczej nie odejdzie w najbliższym czasie (kiedykolwiek).
Tom Auger
Patrząc teraz na moją odpowiedź, uważam, że jawne porządkowanie jquery-ui-core i jquery-ui-tab jest całkowicie zbyteczne, ponieważ skrypty te są już zarejestrowane. Musisz tylko wywołać je w zależności. Zaktualizuję odpowiednio swoją odpowiedź.
Tom Auger,
Doskonale współpracuje z WordPress 4.9.6
ethmz
13

Jeśli używasz get_current_screen(), możesz wykryć, na jakiej stronie jesteś. Jest to przykład w artykule Codex że połączonego który pokazuje, jak korzystać get_current_screen()z add_options_page()ta metoda będzie działać na każdej stronie administratora.

mor7ifer
źródło
3

Możesz wziąć odpowiedź i nieco ją rozwinąć, co pozwoli również na warunkowe użycie ...@tollmanz

Przykład:

/* Add admin pages */   
function my_admin_pages(){
    $menu = array();
    $menu['main_page'] = add_menu_page('Page 1', 'bar', 'something', 'else', 'foo');
    $menu['sub_page'] = add_submenu_page('theme_menu', 'Subpage 1', 'Subpage', 'something', 'else', 'foo');
    foreach($menu as $key => $value){
        if($key == 'main_page'){
            /* Print styles on only the main page. */
            add_action('admin_print_styles-'.$value, 'print_styles');
        }
        /* Print scripts on all of our admin pages. */
        add_action('admin_print_scripts-'.$value, 'print_scripts');
    }
}
add_action('admin_menu', 'my_admin_pages');
Michael Ecklund
źródło
3

Jak wspomniano powyżej @ mor7ifer, możesz użyć natywnej funkcji WordPress get_current_screen () . Jeśli przejdziesz przez wyjście tej funkcji, np .:

$current_screen = get_current_screen();
foreach($current_screen as $key => $value) {
    error_log(print_r($key,1));
}

... zauważysz klucz o nazwie baza . Używam tego wykrywania, na której stronie się znajduję i kolejkuję, usuwam kolejkę tak:

add_action('admin_enqueue_scripts', 'some_hook_function')* ):

public function some_hook_function(){

    // # only register and queue scripts & styles on POST edit screen of admin
    $current_page = get_current_screen()->base;
    if($current_page == 'post' || $current_page == 'page') {

        wp_enqueue_script('datetimepicker', plugins_url('assets/jquery-ui-timepicker-addon.min.js', __FILE__), array('jquery', 'jquery-ui-datepicker', 'jquery-ui-slider'), '1.9.1', true);

        wp_enqueue_style( 'jquery-ui-datepicker', plugins_url('assets/jquery-ui.min.css', __FILE__), array(), '1.11.2', 'all');


    } else { // # if not on post page, deregister and dequeue styles & scripts

        wp_dequeue_script('datetimepicker');
        wp_dequeue_style('jquery-ui-datepicker');

    }
}
powrócić
źródło
2

Zastanawiałem się nad tym samym. Istnieje nowoczesna wersja, która wykorzystuje admin_enqueue_scripts:

add_action('admin_menu', function () {
  $settingsPage = add_options_page('Settings', 'Mortgage Calculator', 'manage_options', 'mortgagecalculator', function () {
    echo "<div id='app'></div>";
  });
  /**
   * Include the ember admin scripts only on pages where it's needed.
   */
  add_action("admin_enqueue_scripts", function ($hook) use ($settingsPage){
    if($hook !== $settingsPage){
      return;
    }
    // Remove default jQuery since Ember provides its own.
    wp_dequeue_script('jquery');
    wp_enqueue_script('ember-vendor', plugins_url("admin/assets/vendor.js", __FILE__));
    wp_enqueue_script('ember-project', plugins_url("admin/assets/mortgage-plugin-ember-admin.js", __FILE__), ['ember-vendor']);
    wp_enqueue_script('ember-live-reload', "http://localhost:4200/ember-cli-live-reload.js");
  });
});
Kit Sunde
źródło
0
add_action( 'admin_menu', 'add_my_admin_menus' ); 

function add_my_admin_menus() {
    $GLOBALS['my_page'] = add_menu_page( 'Page Title', 'Menu Title', MY_ADMIN_CAPABILITY, 'menu-slug', 'show_page_content');
    add_action( 'admin_enqueue_scripts', 'enqueue_admin_js');
}

function enqueue_admin_js($hook) {
    if($GLOBALS['my_page'] === $hook) {
        wp_enqueue_script( 'jquery-ui-core' );
        wp_enqueue_script( 'jquery-ui-tabs' );
        // Isn't it nice to use dependencies and the already registered core js files?
        wp_enqueue_script( 'my-script', INCLUDES_URI . '/js/my_script.js', array( 'jquery-ui-core', 'jquery-ui-tabs' ) );
    }
}
Jashwant
źródło
0

Aby to zrobić, musisz najpierw znaleźć nazwę strony administratora. Dodaj za admin_enqueue_scriptspomocą wp_die($hook)i przejdź do konkretnej strony wtyczki, zobaczysz nazwę strony.

function my_plugin_scripts($hook) {
    wp_die($hook);
}
add_action( 'admin_enqueue_scripts', 'my_plugin_scripts' );

info_page_plugging_info

Teraz skopiuj nazwę strony i użyj jej pod warunkiem, aby załadować skrypty na określoną stronę.

function my_plugin_scripts($hook) {
    if ( 'settings_page_plugging_info' != $hook ) {
        return;
    }

    wp_enqueue_script( 'my_custom_script', plugins_url('js/file.js', __FILE__));
}
add_action( 'admin_enqueue_scripts', 'my_plugin_scripts' );
IqbalBary
źródło