Cargar scripts externos en el admin SOLO para un tipo de publicación específico
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");
}
}
?>

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

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

@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.

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?

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?

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?

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

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

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

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.

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

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.

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

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

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

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

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.

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

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
