Cargar scripts externos en el admin SOLO para un tipo de publicación específico

31 ago 2010, 10:31:20
Vistas: 18.1K
Votos: 16

Sigo encontrándome con este problema y estoy buscando la mejor y más simple solución para resolverlo.

He estado utilizando tipos de publicaciones personalizados en muchos proyectos diferentes y los he extendido con metaboxes personalizados, que a su vez he mejorado añadiendo scripts como selectores de calendario jQuery... Todo esto funciona genial excepto por un problema clave... No quiero que estos scripts jQuery personalizados se carguen en todas las páginas del admin.

Básicamente, estoy buscando una manera de que estos campos jQuery personalizados se carguen solo cuando estoy en la página de "editar publicación" para un tipo de publicación ESPECÍFICO.

¿Cuál es la mejor solución aquí?


ACTUALIZACIÓN 1

Primero que nada, muchas gracias.

Realmente me sorprende que los desarrolladores de plugins no se aseguren de cosas como esta porque, como estoy descubriendo, esta es una de las principales razones por las que existen problemas con diferentes plugins.

Sin embargo, estoy teniendo algunos problemas adicionales con esto. Por ejemplo...

He modificado el script para llamar a la declaración if así:

if (is_admin() && $pagenow=='post-new.php' OR $pagenow=='post.php' && $typenow=='events')

Como puedes ver, estoy intentando configurar las cosas para que mis scripts SOLO se carguen cuando estoy añadiendo o editando una publicación dentro del tipo de publicación "events".

No quiero que el script se cargue en ninguna otra página y tampoco quiero que se ejecute en la lista de páginas dentro del tipo de publicación "events", así que creo que la declaración if es correcta.

El problema, sin embargo, parece ser que el script solo se carga cuando creo una nueva publicación dentro de este tipo de publicación, pero no parece funcionar cuando estoy editando una publicación existente.

¿Podrías probar esto y tal vez decirme qué podría estar haciendo mal?

Aquí está el código exacto que estoy usando... ¿tal vez hay una forma mejor o más simple de hacer esto?

<?php
// INCLUIR JQUERY DATEPICKER PERSONALIZADO PARA METABOX 2
add_action('admin_init','load_admin_datapicker_script');
function load_admin_datapicker_script() {
  global $pagenow, $typenow;
  if (is_admin() && $pagenow=='post-new.php' OR $pagenow=='post.php' && $typenow=='events') {
    $ss_url = get_bloginfo('stylesheet_directory');
    wp_enqueue_script('jquery');
    wp_enqueue_script('custom_js_jquery_ui',"{$ss_url}/admin-metabox/js/jquery-ui-1.7.1.custom.min.js",array('jquery'));
    wp_enqueue_script('custom_js_daterangepicker',"{$ss_url}/admin-metabox/js/daterangepicker.jQuery.js",array('jquery'));
    wp_enqueue_script('custom_js_custom',"{$ss_url}/admin-metabox/js/custom.js",array('jquery'),NULL,TRUE);
    wp_enqueue_style('custom_css_daterangepicker',"{$ss_url}/admin-metabox/css/ui.daterangepicker.css");
    wp_enqueue_style('custom_css_jquery_ui',"{$ss_url}/admin-metabox/css/redmond/jquery-ui-1.7.1.custom.css");
  }
}

Además... si quisiera añadir tres tipos de publicación y cargar diferentes scripts JS para cada tipo de publicación, ¿simplemente duplicaría el código anterior tres veces o no es una buena forma de hacerlo? Por ejemplo... ¿sería mejor llamar: global $pagenow, $typenow; Al principio de mi archivo functions.php o no importa o complica las cosas cuando lo duplico más de una vez?

En un problema diferente pero relacionado... por ejemplo, estoy utilizando el plugin "gravity forms" pero he notado que sus scripts se ejecutan en todas las páginas del admin, lo que está causando problemas con otros plugins. ¿Cómo podría modificar su script para asegurarme de que los scripts solo se carguen cuando los necesito?


ACTUALIZACIÓN 2

He modificado mi archivo functions.php con el código proporcionado por Mike (abajo), sin embargo parece que el javascript aplicable todavía se está incluyendo cuando creas una NUEVA publicación o página. Esto significa que cuando intentas crear una NUEVA publicación o página, ya sea creando una nueva publicación/página predeterminada de WordPress o cuando creas una NUEVA publicación/página basada en uno de tus tipos de publicación personalizados. El código propuesto por Mike SÍ funciona en todas las demás páginas del admin y SÍ funciona cuando "EDITAS" una publicación/página existente o un tipo de publicación personalizado. ¿Alguna modificación sugerida para que esto funcione correctamente?

Aquí está mi código actual:

<?php
   add_action('admin_init','load_admin_datapicker_script');
   function load_admin_datapicker_script() {
    global $pagenow, $typenow;
    if (empty($typenow) && !empty($_GET['post'])) {
        $post = get_post($_GET['post']);
        $typenow = $post->post_type;
    }
    if (is_admin() && $pagenow=='post-new.php' OR $pagenow=='post.php' && $typenow=='events') {
        $ss_url = get_bloginfo('stylesheet_directory');
        wp_enqueue_script('jquery');
        wp_enqueue_script('custom_js_jquery_ui',"{$ss_url}/admin-metabox/js/jquery-ui-1.7.1.custom.min.js",array('jquery'));
        wp_enqueue_script('custom_js_daterangepicker',"{$ss_url}/admin-metabox/js/daterangepicker.jQuery.js",array('jquery'));
        wp_enqueue_script('custom_js_custom',"{$ss_url}/admin-metabox/js/custom.js",array('jquery'),NULL,TRUE);
        wp_enqueue_style('custom_css_daterangepicker',"{$ss_url}/admin-metabox/css/ui.daterangepicker.css");
        wp_enqueue_style('custom_css_jquery_ui',"{$ss_url}/admin-metabox/css/redmond/jquery-ui-1.7.1.custom.css");
    }
   }
?> 
1
Comentarios

@NetConstuctor.com: No te asustes, muchas personas que escriben plugins aprendieron a programar precisamente para poder escribir el plugin y, por lo tanto, tienen muy poca formación en programación. Están resolviendo una necesidad personal, no siguiendo las mejores prácticas.

MikeSchinkel MikeSchinkel
4 sept 2010 03:45:18
Todas las respuestas a la pregunta 7
13
14

Primero, asumo que estás usando wp_enqueue_script() para cargar tus scripts, ¿correcto?

Dicho esto, si entiendo tu pregunta, lo que necesitas es algo como lo siguiente. Tendrás que editarlo con tus detalles, por supuesto, pero te da el marco general.

Estamos enganchando admin_init con la función load_my_script() para probar la variable global $pagenow y ver si coincide con la página de administración edit.php, y la variable global $typenow para ver si el tipo de publicación es el que deseas.

El resto son solo detalles que puedes leer aquí si necesitas aprender más:

<?php
add_action('admin_init','load_my_script');
function load_my_script() {
  global $pagenow, $typenow;
  if ($pagenow=='edit.php' && $typenow=='my-custom-type') {
    $ss_url = get_bloginfo('stylesheet_directory');
    wp_enqueue_script('jquery');
    wp_enqueue_script('my-custom-script',"{$ss_url}/js/my-custom-script.js",array('jquery'));
  }
}

ACTUALIZACIÓN

Estoy respondiendo a tu actualización. Desafortunadamente (por cualquier razón), $typenow no tiene un valor durante admin_init, por lo que necesitarás obtener el post_type cargando la publicación basada en el parámetro de URL 'post' como ves en el siguiente ejemplo (he copiado la línea superior e inferior de tu ejemplo para que veas dónde colocarlo):

<?php
global $pagenow, $typenow;
if (empty($typenow) && !empty($_GET['post'])) {
  $post = get_post($_GET['post']);
  $typenow = $post->post_type;
}
if (is_admin() && $pagenow=='post-new.php' OR $pagenow=='post.php' && $typenow=='events') {

P.D. En cuanto a tus otras preguntas, por favor publícalas como nuevas preguntas en el sitio para que yo u otros podamos responder. Ya que estamos trabajando arduamente para ayudarte, por favor ten mucho cuidado de darle a tu título el mejor título posible y también escribe tus preguntas de la manera más clara y sucinta posible, con buen formato y un inglés adecuado. Si haces esto, ayudará a que otros con problemas similares reconozcan tu pregunta como algo similar a lo que necesitan y será más fácil para nosotros responder tus preguntas.

Te pido esto (y a todos los que hacen preguntas en WordPress Answers) como un favor a cambio de tomar el tiempo y esfuerzo para responder tus preguntas, porque yo y los otros moderadores queremos hacer de WordPress Answers un recurso tremendo para la comunidad en lugar de otro foro descuidado que es difícil de leer y encontrar respuestas, como muchos otros sitios en la web.

ACTUALIZACIÓN #2

Pensé que podrías tener un problema de precedencia de operadores en tu declaración if, pero cuando lo probé antes no me encontré con eso. Si se comporta como dices, casi seguro que lo tienes, así que prueba esto en su lugar (lo siento, no tengo tiempo para probarlo ahora mismo para asegurarme de que funcione):

<?php
add_action('admin_init','load_my_script');
function load_my_script() {
  global $pagenow, $typenow;
  if (empty($typenow) && !empty($_GET['post'])) {
    $post = get_post($_GET['post']);
    $typenow = $post->post_type;
  }
  if (is_admin() && $typenow=='events') {
    if ($pagenow=='post-new.php' OR $pagenow=='post.php') { 
      $ss_url = get_bloginfo('stylesheet_directory');
      wp_enqueue_script('jquery');
      wp_enqueue_script('my-custom-script',"{$ss_url}/js/my-custom-script.js",array('jquery'));
    }
  }
}
31 ago 2010 13:07:15
Comentarios

hola mike... mira mi comentario abajo... lo siento, lo publiqué en el cuadro equivocado

NetConstructor.com NetConstructor.com
4 sept 2010 01:15:23

@NetConstuctor.com: Por favor no proporciones aclaraciones a tu pregunta en el espacio diseñado para respuestas. He movido el contenido que pusiste en una respuesta a tu pregunta y votaré para cerrar esa respuesta.

MikeSchinkel MikeSchinkel
4 sept 2010 03:43:05

Hola Mike... tu código funciona perfectamente excepto por un problema... Cuando estás en la página de administración donde puedes añadir una nueva entrada o nueva página (estoy hablando de la entrada/página por defecto) el código javascript que sólo debería cargarse para el tipo de contenido personalizado SÍ se carga. Aparte de este problema, parece funcionar perfectamente y sólo carga el javascript en los tipos de contenido especificados. ¿Tienes alguna modificación que puedas sugerir?

NetConstructor.com NetConstructor.com
6 sept 2010 03:17:33

Lo siento Mike - Mi suposición inicial era incorrecta. Parece que el código que proporcionaste SÍ incluye el javascript en otros tipos de entradas que también tengo. He incluido el script exactamente como sugeriste. ¿Podrías revisarlo una vez más?

NetConstructor.com NetConstructor.com
6 sept 2010 03:22:13

OK... Después de revisar esto aún más, descubrí que el código de Mike realmente funciona correctamente en todas partes excepto cuando creas una publicación "NUEVA". Por lo que estoy viendo aquí, el javascript se incluye incorrectamente cuando creas una NUEVA PÁGINA, NUEVA ENTRADA para las páginas/entradas predeterminadas de WordPress, así como para cualquier tipo de entrada personalizada que puedas tener. El código SÍ funciona (es decir, el javascript no se incluye) cuando EDITAS una entrada o página existente, ya sea una entrada o página predeterminada de WordPress o un tipo de entrada personalizada. ¿Alguien puede proporcionar una modificación sugerida para solucionar este problema?

NetConstructor.com NetConstructor.com
6 sept 2010 03:38:25

@NetConstuctor.com: Ver ACTUALIZACIÓN #2.

MikeSchinkel MikeSchinkel
6 sept 2010 08:43:22

Amigo mío... ¡¡¡eso parece haberlo resuelto por completo!!! A++

NetConstructor.com NetConstructor.com
6 sept 2010 11:19:30

@NetConstuctor.com: De nada, y gracias por el voto positivo y por seleccionar mi respuesta como solución a tu pregunta.

MikeSchinkel MikeSchinkel
6 sept 2010 13:18:42

¡Material increíble! Luché durante 2 días intentando crear mi propia solución solo para encontrar esta mucho mejor aquí.

Lemon Bacon Lemon Bacon
22 sept 2010 09:51:42

Actualización: Modifiqué el código de la siguiente manera:

if ( is_admin() && ( ( $typenow == 'page') || ( $typenow == 'post') ) ){

if ( $pagenow == 'post-new.php' OR $pagenow == 'post.php' ) { wp_enqueue_script( 'imp_jquerytools' ); wp_enqueue_style( 'rpanel-css' ); }

para incluir mis scripts solo cuando esté en la página o post. Funciona bien EXCEPTO en la pantalla de Nuevo Post donde no se carga por alguna razón. Editar Posts o Páginas y crear nuevas páginas funciona bien, crear nuevos posts, no.

Lemon Bacon Lemon Bacon
22 sept 2010 10:06:40

Actualización: mira mi respuesta para una solución funcional (no sé si es la mejor solución, pero funciona)

Lemon Bacon Lemon Bacon
22 sept 2010 10:32:37

Aunque esta pregunta ya tiene respuesta, solo quiero agregar una pequeña mejora: podemos usar la función get_current_screen() para obtener toda la información sobre la pantalla actual. No se recomienda usar esas variables globales.

Anh Tran Anh Tran
5 sept 2012 20:06:58

@Rilwis Para ser claro, en el momento de escribir el código anterior, la pantalla actual no tenía de manera confiable todo lo necesario.

MikeSchinkel MikeSchinkel
6 sept 2012 00:23:04
Mostrar los 8 comentarios restantes
0

Pensé en agregar aquí un código que resolvió un problema relacionado que tuve. En mi caso, estoy intentando que JavaScript y CSS se carguen solo en Páginas y Entradas (tanto en edición como en creación) y en ningún otro lugar.

Había encontrado una solución funcional usando basename( $_SERVER[ 'SCRIPT_FILENAME' ] ) para determinar en qué parte del backend me encontraba. Sin embargo, me preocupaba que la disponibilidad de $_SERVER[ 'SCRIPT_FILENAME' ] pudiera variar de servidor a servidor (¿alguien sabe qué tan probable es que $_SERVER[ 'SCRIPT_FILENAME' ] no esté disponible en un servidor?).

Luego encontré esta pregunta y la respuesta de MikeSchinkel. Con una pequeña modificación, logré que funcionara para mí, excepto por una cosa. Por alguna razón, cuando se crea una nueva entrada mediante "Añadir nueva", no funciona.

Con los siguientes ajustes, logré que funcionara y lo comparto aquí con la esperanza de ayudar a otros y de mejorarlo.

add_action( 'admin_init','imp_add_admin_scripts' );

function imp_add_admin_scripts() {

 $urljs = get_bloginfo( 'template_directory' ).IMP_JS;
 $urlcss =get_bloginfo( 'template_directory' ).IMP_STYLES;

 // Registrar nuestros scripts
 wp_register_script('imp_jquerytools', $urljs.'jquery/imp_tabs_jquery.tools.min.js' );
 wp_register_style( 'rpanel-css', $urlcss.'impoweradmin.css' );


 global $pagenow, $typenow;
 if ( empty( $typenow ) && !empty( $_GET['post'] ) ) {
  $post = get_post( $_GET['post'] );
  $typenow = $post->post_type;
 } elseif ( empty( $typenow ) && ( $pagenow == 'post-new.php' ) ){ 
  $typenow = 'post';
 }

 if ( is_admin() && ( ( $typenow == 'page') || ( $typenow == 'post') ) ){

  if ( $pagenow == 'post-new.php' OR $pagenow == 'post.php' ) {

   wp_enqueue_script( 'imp_jquerytools' );
   wp_enqueue_style( 'rpanel-css' );

  }
 }
}

Ahora estoy intentando limitar algunos scripts a mi página de opciones del tema, lo cual no se puede hacer basado en $pagenow ya que la URL que aparece es admin.php?page=themeoptions y no quiero los scripts en todas las páginas admin.php, solo en esa página específica (mi página de opciones del tema).

¿Alguien sabe cómo se podría hacer esto de la mejor manera?

Y para responder a mi propia pregunta:

if( is_admin() && ( $_GET['page'] == 'themeoptions' ) ){
  wp_enqueue_script( 'my-script' );

 }
22 sept 2010 10:31:57
0

Según Justin Tadlock, deberías utilizar el hook admin_enqueue_scripts en lugar de wp_enqueue_scripts para plugins o scripts exclusivos del área de administración:

http://justintadlock.com/archives/2011/07/12/how-to-load-javascript-in-the-wordpress-admin

add_action('admin_enqueue_scripts','load_admin_datapicker_script');
5 sept 2012 19:36:36
0

Ya sé que la pregunta ha sido respondida. Creo que esta es una solución más simple.

<?php
add_action( 'admin_enqueue_scripts', 'load_admin_datapicker_script' );

function load_admin_datapicker_script() {

    $current_screen = get_current_screen();

    if ( $current_screen->post_type === 'events' )  {
        $ss_url = get_bloginfo('stylesheet_directory');
        wp_enqueue_script('jquery');
        wp_enqueue_script('custom_js_jquery_ui',"{$ss_url}/admin-metabox/js/jquery-ui-1.7.1.custom.min.js",array('jquery'));
        wp_enqueue_script('custom_js_daterangepicker',"{$ss_url}/admin-metabox/js/daterangepicker.jQuery.js",array('jquery'));
        wp_enqueue_script('custom_js_custom',"{$ss_url}/admin-metabox/js/custom.js",array('jquery'),NULL,TRUE);
        wp_enqueue_style('custom_css_daterangepicker',"{$ss_url}/admin-metabox/css/ui.daterangepicker.css");
        wp_enqueue_style('custom_css_jquery_ui',"{$ss_url}/admin-metabox/css/redmond/jquery-ui-1.7.1.custom.css");
    }

}
?> 
24 jul 2013 21:40:44
1

Creé una versión que no utiliza la variable $typenow:

function isPostEditPage($strCheckType="")
{
    //Esta función verificará un tipo de entrada y devolverá verdadero si es la página de edición para este tipo
    //un valor vacío significa verificar el tipo de entrada nativo (original, no personalizado)
    $strCheckType=$strCheckType==""?"post":$strCheckType;
    $blnReturn=false;
    if(is_Admin())  
    {
        $strPage=basename($_SERVER['SCRIPT_FILENAME']);
        switch($strPage)
        {
            case "post.php":
                if(isset($_GET["post"]))
                {
                    $intPostID=$_GET["post"];
                    $strThisPostType=get_post_type($intPostID);
                    if($strCheckType==$strThisPostType)
                    {
                        $blnReturn=true;
                    }
                }
            break;
            case "post-new.php":
                $strThisPostType="post";
                if(isset($_GET["post_type"]))
                {
                    $strThisPostType=$_GET["post_type"];
                }
                if($strCheckType==$strThisPostType)
                {
                    $blnReturn=true;
                }

            break;
        }
    }
    return $blnReturn;
}
17 feb 2012 02:30:23
Comentarios

Las variables globales no cambiarán, por lo que es seguro usarlas. Además, hay hooks específicos para esas páginas, así que no necesitas esa función ni ese esfuerzo. Por último, pero no menos importante: estás verificando cadenas de forma no estricta y tampoco en estilo Yoda, por lo que podrían fallar. También confiar únicamente en $_GET podría fallar. De cualquier manera: Bienvenido/a a WPSE.

kaiser kaiser
20 feb 2012 17:29:20
0

¿Qué tal esto?:

add_action( 'admin_init', 'scripts_admin' );

function scripts_admin($hook){

    global $typenow;
    if (empty($typenow) && !empty($_GET['post'])) {
         $post = get_post($_GET['post']);
             $typenow = $post->post_type;
     }
     if( 'post.php' != $hook && 'CUSTOMPOSTTYPE' != $typenow)
        return;

        wp_enqueue_script( 'google-api','http://maps.googleapis.com/maps/api/js?key=AIzaSyCD5TwT3vXLfYEv9WD-kOcEg7YQLcncsls&sensor=true', array( 'jquery' ) );


}
14 jul 2012 02:03:56
0

Esto

$typenow no tiene un valor durante admin_init

no es del todo correcto. Sí tiene un valor establecido en admin_init en la mayoría de las pantallas de tipos de contenido como Añadir Nuevo, lista de taxonomías, edición de taxonomía y lista de entradas, pero no lo tiene en la pantalla "Editar TuTipoDeContenido".

Además, como otros han señalado, el hook correcto para añadir hojas de estilo y scripts al Administrador de WordPress es admin_enqueue_scripts. Si usas este hook no necesitas comprobar is_admin() ya que solo se ejecuta en el Administrador de WordPress y recibes como parámetro la pantalla actual. http://codex.wordpress.org/Plugin_API/Action_Reference/admin_enqueue_scripts

28 ene 2015 18:33:36