Caricare Script Esterni nell'Admin Solo per un Tipo di Post Specifico?
Continuo a imbattermi in questo problema e sto cercando la soluzione migliore e più semplice per risolverlo.
Utilizzo spesso tipi di post personalizzati in diversi progetti e li estendo con metabox personalizzati, a cui aggiungo script jQuery come selettori di calendario... Tutto funziona perfettamente tranne per un problema chiave: non voglio che questi script jQuery personalizzati vengano caricati su ogni pagina dell'area di amministrazione.
Sto cercando un modo per caricare questi script jQuery solo quando sono nella pagina di modifica di un tipo di post SPECIFICO.
Qual è la soluzione migliore?
AGGIORNAMENTO 1
Innanzitutto, grazie mille.
Sono davvero sorpreso che gli sviluppatori di plugin non utilizzino soluzioni come questa, perché sto scoprendo che è una delle principali cause di problemi tra diversi plugin.
Sto però riscontrando ulteriori problemi. Ad esempio...
Ho modificato lo script per includere un'istruzione if in questo modo:
if (is_admin() && $pagenow=='post-new.php' OR $pagenow=='post.php' && $typenow=='events')
Come puoi vedere, sto cercando di impostare il caricamento degli script SOLO quando aggiungo o modifico un post del tipo "events".
Non voglio che lo script venga caricato su altre pagine né sulla lista dei post del tipo "events", quindi penso che l'istruzione if sia corretta.
Il problema è che lo script viene caricato solo quando creo un nuovo post di questo tipo, ma non funziona quando modifico un post esistente.
Potresti testarlo e farmi sapere cosa potrei sbagliare?
Ecco il codice esatto che sto usando... forse esiste un modo migliore o più semplice?
<?php
// INCLUDE METABOX CUSTOM JQUERY DATEPICKER 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");
}
}
Inoltre... se volessi aggiungere tre tipi di post e caricare script JS diversi per ognuno, dovrei semplicemente duplicare il codice sopra tre volte o non è un buon modo di procedere? Ad esempio... sarebbe meglio dichiarare: global $pagenow, $typenow; all'inizio del mio file functions.php o complica le cose se lo ripeto più volte?
Su un problema diverso ma correlato... sto usando il plugin "gravity forms" ma ho notato che i loro script vengono eseguiti su ogni pagina dell'admin, causando conflitti con altri plugin. Come potrei modificare il loro script per caricarlo solo quando necessario?
AGGIORNAMENTO 2
Ho modificato il mio file functions.php con il codice fornito da Mike (qui sotto) ma sembra che gli script vengano ancora inclusi quando crei un NUOVO Post o Pagina. Ciò significa che quando tenti di creare un NUOVO Post/Pagina standard o basato su uno dei tuoi tipi di post personalizzati, il codice proposto da Mike funziona su tutte le altre pagine admin e quando "MODIFICHI" un post/pagina esistente, ma non per la creazione. Quali modifiche suggerisci per risolvere?
Ecco il codice attuale:
<?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");
}
}
?>

Innanzitutto, presumo che tu stia usando wp_enqueue_script()
per caricare i tuoi script, giusto?
Detto questo, se ho capito bene la tua domanda, ciò di cui hai bisogno è qualcosa di simile al seguente codice. Dovrai adattarlo ai tuoi dettagli, ovviamente, ma ti fornisce la struttura generale.
Stiamo agganciando admin_init
con la funzione load_my_script()
per verificare la variabile globale $pagenow
e vedere se corrisponde alla pagina di amministrazione edit.php
, e la variabile globale $typenow
per controllare se il post type è quello desiderato.
Il resto sono solo dettagli su cui puoi approfondire qui se hai bisogno di maggiori informazioni:
<?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'));
}
}
AGGIORNAMENTO
Rispondo al tuo aggiornamento. Sfortunatamente (per qualche motivo) $typenow
non ha un valore durante admin_init
, quindi dovrai ottenere il post_type
caricando il post basandoti sul parametro URL 'post'
come vedi nel seguente esempio (ho copiato la riga sopra e sotto dal tuo esempio per mostrarti dove posizionarlo):
<?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.S. Per le altre tue domande, per favore pubblicale come nuove domande sul sito in modo che io o altri possiamo rispondere. Dato che stiamo lavorando duramente per aiutarti, per favore fai attenzione a dare alla tua domanda il miglior titolo possibile e scrivila in modo chiaro, conciso, con una buona formattazione e un inglese corretto. Questo aiuterà altri con problemi simili a riconoscere la tua domanda e renderà più facile per noi rispondere.
Te lo chiedo (e a tutti coloro che fanno domande su WordPress Answers) come favore in cambio del tempo e dello sforzo dedicati a rispondere alle tue domande, perché io e gli altri moderatori vogliamo che WordPress Answers sia una risorsa fantastica per la community, invece di un altro forum disordinato e difficile da leggere come molti altri siti web.
AGGIORNAMENTO #2
Pensavo potessi avere un problema di precedenza degli operatori nella tua istruzione if, ma quando ho testato prima non l'ho riscontrato. Se si comporta come dici, quasi certamente è così, quindi prova invece questo (scusa, non ho tempo per testarlo ora per assicurarmi che funzioni):
<?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'));
}
}
}

ciao Mike... vedi il mio commento qui sotto... scusa, ho postato nella casella sbagliata

@NetConstuctor.com: Per favore non fornire chiarimenti alla tua domanda nello spazio destinato alle risposte. Ho spostato il contenuto che hai inserito come risposta nella tua domanda e voterò per chiudere quella risposta.

Ciao Mike... il tuo codice funziona perfettamente tranne per un problema... Quando sei nella pagina di amministrazione dove puoi aggiungere un nuovo post o una nuova pagina (parlo del post/pagina predefinito) il codice javascript che dovrebbe essere caricato solo per il custom post type VIENE caricato comunque. A parte questo problema sembra funzionare perfettamente e carica lo javascript solo sui post type specificati. Hai qualche modifica da suggerire?

Scusa Mike - La mia ipotesi iniziale era in realtà errata. Sembra che il codice che hai fornito includa lo javascript anche su altri tipi di post che ho. Ho incluso lo script esattamente come hai suggerito. Potresti per favore rivederlo ancora una volta?

OK... Dopo aver esaminato ulteriormente questa cosa, ho scoperto che il codice di Mike funziona correttamente ovunque tranne quando si crea un post "NUOVO". Da quello che vedo qui, lo javascript viene incluso in modo errato quando crei una NUOVA PAGINA, un NUOVO POST per le pagine/post predefiniti di WordPress così come per qualsiasi custom post type che potresti avere. Il codice FUNZIONA (cioè lo javascript non viene incluso) quando MODIFICHI un post o una pagina esistente, che sia un post o una pagina predefinita di WordPress o un custom post type. Qualcuno può suggerire una modifica per risolvere questo problema?

Amico mio... sembra proprio che abbia risolto il problema!!! Ottimo lavoro A++

@NetConstuctor.com: Prego, e grazie per il voto positivo e per aver selezionato la mia risposta come soluzione al tuo problema.

Fantastico! Ho lottato per 2 giorni cercando di trovare una soluzione da solo, per poi scoprire qui una soluzione molto migliore!

Aggiornamento: ho modificato il codice in questo modo:
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' ); }
per includere i miei script solo quando sono nella pagina o nel post. Funziona bene TRANNE che nella schermata di Nuovo Post dove per qualche motivo non si carica. Modifica di Post o Pagine e creazione di nuove pagine funziona bene, creazione di nuovi post, No.

aggiornamento: vedi la mia risposta per una soluzione funzionante (non so se sia la migliore soluzione, ma funziona)

Sebbene questa domanda sia già risposta, vorrei solo aggiungere un piccolo miglioramento: possiamo usare la funzione get_current_screen()
per ottenere tutte le informazioni sullo schermo corrente. L'uso di quelle variabili globali non è raccomandato.

Pensavo di aggiungere qui del codice che ha risolto un mio problema correlato. Nel mio caso sto cercando di fare in modo che JavaScript e CSS vengano caricati solo su Pagine e Articoli (sia in modifica che in creazione) e in nessun altro posto.
Avevo trovato una soluzione funzionante usando basename( $_SERVER[ 'SCRIPT_FILENAME' ] )
per determinare dove mi trovavo nel backend. Tuttavia, ero preoccupato perché la disponibilità di $_SERVER[ 'SCRIPT_FILENAME' ]
potrebbe variare da server a server (qualcuno sa quanto è probabile che $_SERVER[ 'SCRIPT_FILENAME' ]
non sia disponibile su un server?).
Poi mi sono imbattuto in questa domanda e nella risposta di MikeSchinkel. Con qualche modifica sono riuscito a farlo funzionare per me, tranne per una cosa. Sembra che per qualche motivo quando un nuovo articolo viene creato tramite "Aggiungi nuovo" non funzioni.
Con i seguenti aggiustamenti sono riuscito a farlo funzionare e lo condivido qui nella speranza di aiutare altri e di migliorarlo.
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;
// Registra i nostri script
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' );
}
}
}
Ora sto cercando di limitare alcuni script alla pagina delle opzioni del tema, cosa che non può essere fatta basandosi su $pagenow poiché l'URL che appare è admin.php?page=themeoptions e non voglio che gli script vengano caricati su tutte le pagine admin.php, solo su quella specifica pagina (la mia pagina delle opzioni del tema).
Qualcuno sa come si potrebbe fare al meglio?
E per rispondere alla mia stessa domanda:
if( is_admin() && ( $_GET['page'] == 'themeoptions' ) ){
wp_enqueue_script( 'my-script' );
}

Secondo Justin Tadlock, dovresti utilizzare il hook admin_enqueue_scripts invece di wp_enqueue_scripts per i plugin o gli script esclusivamente per l'admin:
http://justintadlock.com/archives/2011/07/12/how-to-load-javascript-in-the-wordpress-admin
add_action('admin_enqueue_scripts','load_admin_datapicker_script');

So che la domanda è già stata risposta. Penso che questa sia una soluzione più semplice.
<?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");
}
}
?>

Ho creato una versione che non utilizza la variabile $typenow:
function isPostEditPage($strCheckType="")
{
//Questa funzione verifica un tipo di post e restituisce true se è la pagina di modifica per questo tipo
//un valore vuoto significa verificare il tipo di post nativo (originale, non personalizzato)
$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;
}

Le variabili globali non cambieranno, quindi è sicuro utilizzarle. Inoltre, ci sono hook specifici per quelle pagine, quindi non hai bisogno di quella funzione e di quello sforzo. Ultimo ma non meno importante: stai verificando le stringhe in modo non stretto e anche non in stile yoda, quindi potrebbero fallire. Inoltre, fare affidamento solo su $_GET
potrebbe fallire. Comunque: benvenuto su WPSE.

Cosa ne pensi di:
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' ) );
}

Questo
$typenow non ha un valore durante admin_init
non è del tutto corretto. In realtà ha un valore impostato su admin_init nella maggior parte delle schermate dei post type come Aggiungi Nuovo, lista tassonomie, modifica tassonomia e lista voci, ma non ne ha uno nella schermata "Modifica IlTuoPostType".
Inoltre, come altri hanno sottolineato, l'hook corretto da usare per aggiungere fogli di stile e script alla WP Admin è admin_enqueue_scripts
. Se usi questo hook non hai bisogno di verificare is_admin()
dato che viene attivato solo in WP Admin e ricevi come parametro la schermata corrente.
http://codex.wordpress.org/Plugin_API/Action_Reference/admin_enqueue_scripts
