¿Cómo pongo en cola estilos / scripts en ciertas páginas / wp-admin?

53

Tengo dos funciones simples que cargan cosas usando wp_enqueue_style()y wp_enqueue_script(), algo así:

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

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

... y algunas páginas de administración, creadas con add_menu_page()yadd_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'); 

¿Cómo cargo mis dos funciones solo en estas páginas?

En este momento estoy usando:

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

Pero carga mis archivos en cada página de administración, lo cual no es nada agradable.

¿Puedo hacer esto a través de una línea simple functions.phpo tener que ponerlos en cola dentro de mis páginas por separado (prefiero la primera opción, ya que tendría que editar muchas funciones de creación de páginas de administrador).

¡Gracias!

Wordpressor
fuente

Respuestas:

33

add_menu_pagey add_submenu_pageambos devuelven el "sufijo de gancho" de la página, que puede usarse para identificar la página con ciertos ganchos. Como tal, puede usar ese sufijo en combinación con los ganchos variables admin_print_styles-{$hook_suffix}y admin_print_scripts-{$hook_suffix}dirigirse específicamente a estas páginas.

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

Creo que este es un método limpio para agregar todo esto porque todo se maneja dentro de una función. Si decide eliminar esta funcionalidad, simplemente elimine la llamada a la única función.

tollmanz
fuente
55
Esta respuesta no es técnicamente correcta. el Codex paraadmin_print_scripts() estados " admin_print_scripts no debe usarse para poner en cola estilos o scripts ". La respuesta de @TomAuger es en realidad la correcta, aunque no óptima. Sin embargo, sería beneficioso si el equipo de WP agregara un admin_enqueue_scripts-(hookname)gancho ...
David Gard
Me tomó 3 días encontrar esta respuesta, lo cual fue realmente útil para mí :) Gracias :)
Asfandyar Khan
@DavidGard, probablemente deberías mirar estos developer.wordpress.org/reference/hooks/… , developer.wordpress.org/reference/hooks/…
hkchakladar
1
@hkchakladar Mi comentario tiene casi cuatro años ... Si ya no es relevante, agregue un comentario más actualizado que explique por qué.
David Gard
61

El problema con la respuesta de @tollmanz es que, dado que estás desconectando los enlaces -print-styles y -print-scripts, debes generar el HTML para cargar tus scripts manualmente. Esto no es óptimo, ya que no obtienes la buena dependencia y las versiones que vienen con wp_enqueue_script()y wp_enqueue_style(). Tampoco te permite poner cosas en el pie de página si ese es un lugar mejor para ellos.

Entonces, volviendo a la pregunta del OP: ¿cuál es la mejor manera de asegurarme de que pueda poner en cola JS / CSS solo en páginas de administración específicas?

  1. Desconecta la acción "cargar - {$ my_admin_page}" para hacer cosas solo cuando se carga la página de administración de tu complemento específico, y luego

  2. Descuelgue la acción "admin_enqueue_scripts" para agregar correctamente sus wp_enqueue_scriptllamadas.

Parece un poco molesto, pero en realidad es muy fácil de implementar. Desde la parte superior:

    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
fuente
44
+1: este es el camino a seguir en la OMI. Los ganchos individuales de espacios de nombres (someaction- $ hook) son buenos para 1 o 2 acciones, pero si está creando un complemento, es posible que deba hacer muchas cosas diferentes solo en su (s) página (s) de opciones, lo que hace que este método sea realmente conveniente. Por lo general, solo agrego 1 acción al load-$hookgancho que activa mi option_page_actionsfunción a la que puedo agregar muchos otros ganchos / filtros, etc. Debido a que esas acciones solo se invocan en la página de elección, los ganchos más allá de ese punto no necesitan usar los ganchos de espacios de nombres (como has mostrado), que es mucho más eficiente e intuitivo.
Evan Mattson
Hola, ¿sigue siendo así? load_admin_js nunca llama
IAmJulianAcosta
Claro que todavía es compatible. Línea 206 de admin.php. He estado allí desde 2.6 y es poco probable que desaparezca pronto (nunca).
Tom Auger
Mirando mi respuesta ahora, creo que poner en cola explícitamente jquery-ui-core y jquery-ui-tabs es completamente superfluo, ya que esos scripts ya están registrados. Solo necesita llamarlos en la dependencia. Actualizaré mi respuesta en consecuencia.
Tom Auger
Funciona perfectamente con WordPress 4.9.6
ethmz
13

Si lo usa get_current_screen(), puede detectar en qué página se encuentra. Hay un ejemplo en el artículo códice que he vinculado la que muestra cómo usar get_current_screen()con add_options_page(), este método funcionará para cualquier página de administración.

mor7ifer
fuente
3

Podría tomar la respuesta y ampliarla un poco, permitiendo también el uso condicional ...@tollmanz

Ejemplo:

/* 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
fuente
3

Como @ mor7ifer mencionó anteriormente, puede usar la función nativa de WordPress get_current_screen () . Si recorre la salida de esta función, por ejemplo:

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

... notará una clave llamada base . Utilizo esto para detectar en qué página estoy y poner en cola, poner en cola así:

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

    }
}
recurse
fuente
2

Me preguntaba lo mismo. Hay una versión moderna que usa 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
fuente
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
fuente
0

Para hacerlo, primero debe encontrar el nombre de la página de administración. Agregue admin_enqueue_scriptscon wp_die($hook)y vaya a su página de complemento específica, verá el nombre de la página.

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

settings_page_plugging_info

Ahora copie el nombre de la página y úselo en condiciones para cargar los scripts en la página específica.

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
fuente