Caricamento Condizionale di JavaScript/CSS per Shortcode

23 giu 2011, 18:07:29
Visualizzazioni: 17.8K
Voti: 41

Ho rilasciato un plugin che crea uno shortcode e richiede il caricamento di un file JavaScript e un file CSS su qualsiasi pagina che contenga quello shortcode. Potrei semplicemente far caricare lo script/stile su tutte le pagine, ma non è la migliore pratica. Voglio caricare i file solo sulle pagine che chiamano lo shortcode. Ho trovato due metodi per farlo, ma entrambi presentano problemi.

Metodo 1 imposta un flag a true all'interno della funzione handler dello shortcode, e poi controlla quel valore all'interno di un callback wp_footer. Se è true, utilizza wp_print_scripts() per caricare il JavaScript. Il problema con questo metodo è che funziona solo per JavaScript e non per CSS, perché il CSS dovrebbe essere dichiarato all'interno di <head>, cosa che puoi fare solo durante un hook precoce come init o wp_head.

Metodo 2 viene eseguito presto e "sbircia in avanti" per vedere se lo shortcode esiste nel contenuto della pagina corrente. Questo metodo mi piace molto più del primo, ma il problema è che non rileva se il template chiama do_shortcode().

Quindi, sono propenso a usare il secondo metodo e poi cercare di rilevare se è assegnato un template e, in tal caso, analizzarlo per lo shortcode. Prima di farlo, però, volevo verificare se qualcuno conosce un metodo migliore.

Aggiornamento: Ho integrato la soluzione nel mio plugin. Se qualcuno è curioso di vederlo sviluppato in un ambiente live, puoi scaricarlo o visualizzarlo.

Aggiornamento 2: A partire da WordPress 3.3, è ora possibile chiamare wp_enqueue_script() direttamente all'interno di un callback di shortcode, e il file JavaScript verrà chiamato nel footer del documento. Tecnicamente è possibile anche per i file CSS, ma dovrebbe essere considerata una cattiva pratica perché l'output del CSS al di fuori del tag <head> viola le specifiche W3C, può causare FOUC (Flash of Unstyled Content) e può forzare il browser a ri-renderizzare la pagina.

10
Commenti

In passato ho utilizzato una variante del Metodo 1. Caricare il JS per lo shortcode nel footer, caricare il CSS per lo shortcode in-line. Funziona, ma è un po' un hack. Non vedo l'ora di trovare una soluzione migliore.

EAMann EAMann
23 giu 2011 18:14:52

I principali problemi con il CSS in-line sono che è difficile sovrascriverlo con altri stili e non utilizza il metodo wp_enqueue_styles().

Ian Dunn Ian Dunn
23 giu 2011 19:05:16

Quanto CSS hai?

mfields mfields
23 giu 2011 19:35:32

Quante linee di JavaScript?

mfields mfields
23 giu 2011 19:36:42

Sono circa 30 linee di CSS e 100 linee di JavaScript, ma questo è irrilevante. Devono essere inclusi nel MODO GIUSTO, indipendentemente dalla dimensione. Vedi i commenti sulle risposte per i motivi.

Ian Dunn Ian Dunn
23 giu 2011 19:45:43

Il JavaScript è la parte facile. Il modo migliore per farlo è sotto "Jedi" qui: http://scribu.net/wordpress/optimal-script-loading.html

mfields mfields
23 giu 2011 19:55:27

30 righe non sono molte, le minimizzerei e le stamperei nell'head in un tag style in tutte le viste. Fornisci un filtro e/o un'impostazione che permetta all'utente di disabilitare gli stili se lo desidera.

mfields mfields
23 giu 2011 19:59:12

@mfields, conosco già quel metodo, l'ho linkato nella domanda... Per favore leggi RTFQ prima di commentare ;)

Ian Dunn Ian Dunn
23 giu 2011 21:02:10

Allora conosci già il MIGLIOR modo per gestire il javascript ;) Il MIGLIOR modo imho per gestire il css è "30 righe non sono molte, le minimizzerei e le stamperei nell'head in un tag style in tutte le viste. Fornisci un filtro e/o un'impostazione che permetta all'utente di disabilitare gli stili se lo desidera." Se hai bisogno di usare wp_enqueue_script() vai pure avanti, non penso che sia necessario comunque visto che aggiunge un'altra richiesta HTTP. Minimizza -> stampa in wp_head() -> permetto ad altre estensioni di filtrare l'output.

mfields mfields
23 giu 2011 21:14:52

Penso che file separati siano più puliti e offrano una migliore organizzazione. La minificazione può essere eseguita dal server in runtime.

Ian Dunn Ian Dunn
23 giu 2011 21:40:56
Mostra i restanti 5 commenti
Tutte le risposte alla domanda 7
9
11

Basandomi sulla mia esperienza personale, ho utilizzato una combinazione dei metodi 1 e 2 - l'architettura e gli script del footer del primo, e la tecnica 'look-ahead' del secondo.

Per quanto riguarda il 'look-ahead', però, utilizzo le regex al posto di stripos; preferenza personale, più veloce e può verificare la presenza di shortcode 'malformati';

preg_match( '#\[ *shortcode([^\]])*\]#i', $content );

Se sei preoccupato che gli autori utilizzino manualmente do_shortcode, opterei per istruirli a utilizzare una chiamata ad un'azione accodare manualmente il tuo stile pre-registrato.

AGGIORNAMENTO: Per l'autore pigro che non legge mai il manuale, mostra un messaggio per evidenziare l'errore commesso ;)

function my_shortcode()
{
    static $enqueued;
    if ( ! isset( $enqueued ) )
        $enqueued = wp_style_is( 'my_style', 'done' ); // memorizza in cache così non si ripete se chiamato più volte

    // esegui lo shortcode
    $output = '';

    if ( ! $enqueued )
        // puoi mostrare il messaggio solo alla prima occorrenza racchiudendolo nel precedente if
        $output .= <<<HTML
<p>Attenzione! Devi accodare manualmente il foglio di stile dello shortcode se chiami direttamente <code>do_shortcode()</code>!</p>
<p>Usa <code>wp_enqueue_style( 'my_style' );</code> prima della tua chiamata a <code>get_header()</code> nel tuo template.</p>
HTML;

    return $output;
}
23 giu 2011 21:23:00
Commenti

È un punto valido. Idealmente, vorrei che funzionasse senza che debbano fare nulla di extra – perché la metà delle volte probabilmente non leggeranno prima le FAQ, quindi penseranno semplicemente che sia rotto – ma potrei finire per farlo. Potrei registrare gli script su ogni pagina, ma caricarli solo se rilevo uno shortcode. Quindi, gli utenti potrebbero agganciarsi a init e chiamare le funzioni di enqueue in template specifici dove necessario, assumendo che non sia già troppo tardi nell'esecuzione a quel punto. Inoltre, WP ha già integrato get_shortcode_regex().

Ian Dunn Ian Dunn
23 giu 2011 21:54:54

Se gli utenti sono capaci di implementare do_shortcode(), non è ragionevole assumere che siano altrettanto capaci di seguire le istruzioni per il caricamento dello stile dello shortcode?

Chip Bennett Chip Bennett
23 giu 2011 22:16:03

Vero, ma otterrà la regex per tutti gli shortcode, non solo i tuoi ;) "Potrei registrare gli script su ogni pagina" Probabilmente anche il metodo migliore! Nota che non devono agganciarsi a init, basta ovunque prima di wp_head. Per lo sviluppatore pigro, controlla wp_style_is( 'my_style_handle', 'done' ) dentro il tuo shortcode. Se è falso, stampa un errore visibile che li istruisca su cosa fare.

TheDeadMedic TheDeadMedic
23 giu 2011 22:17:52

@Chip - Non sono preoccupato che non siano in grado di seguire le istruzioni, solo che non sappiano che dovrebbero farlo, dato che il 99% delle volte non c'è bisogno di fare nulla di extra.

Ian Dunn Ian Dunn
24 giu 2011 01:05:05

@Ian il mio pensiero era che aggiungere do_shortcode() al template è già "fare qualcosa di extra" - e gli utenti che farebbero quel qualcosa in più o saprebbero già della necessità di accodare lo stile, oppure sarebbero più disposti/propensi a seguire istruzioni speciali.

Chip Bennett Chip Bennett
24 giu 2011 02:03:16

@TheDeadMedic - L'ho integrato con il mio codice e ho aggiornato la domanda con i link nel caso qualcuno volesse vederlo sviluppato. Grazie ancora per l'aiuto :)

Ian Dunn Ian Dunn
26 giu 2011 08:27:34

@Ian Bello! Grazie per essere tornato con un aggiornamento, sia per noi che per i googler che ci atterreranno in seguito ;)

TheDeadMedic TheDeadMedic
26 giu 2011 08:41:34

Bello ma non sono d'accordo sul fatto che preg_match sia più veloce di strpos http://lzone.de/articles/php-string-search.htm

Bainternet Bainternet
5 feb 2012 19:57:30

@Bainternet Non necessariamente - preg_match vs stripos (case-insensitive) - in ogni caso stiamo parlando di tempistiche irrisorie. Col senno di poi, penso che avrei dovuto evitare il termine "più veloce" - in realtà intendevo che era più efficiente per il compito in questione (invece di usare più stripos per gestire vari formati di shortcode).

TheDeadMedic TheDeadMedic
9 feb 2012 20:35:16
Mostra i restanti 4 commenti
6

Rispondo in ritardo a questa domanda ma dato che Ian ha avviato questa discussione sulla mailing list wp-hackers oggi, mi ha fatto pensare che valesse la pena rispondere, soprattutto considerando che stavo pianificando di aggiungere una funzionalità simile ad alcuni plugin su cui sto lavorando.

Un approccio da considerare è verificare al primo caricamento della pagina se lo shortcode è effettivamente utilizzato e poi salvare lo stato di utilizzo dello shortcode in una meta chiave del post. Ecco come fare:

Procedura Passo-Passo

  1. Imposta un flag $shortcode_used a 'no'.
  2. Nella funzione dello shortcode stesso, imposta il flag $shortcode_used a 'yes'.
  3. Imposta un hook 'the_content' con priorità 12 (dopo che WordPress ha processato gli shortcode) e controlla i meta del post per un valore vuoto '' usando la chiave "_has_{$shortcode_name}_shortcode". (Un valore '' viene restituito quando una meta chiave non esiste per l'ID del post.)
  4. Usa un hook 'save_post' per eliminare la meta del post, cancellando il flag persistente per quel post nel caso l'utente modifichi l'utilizzo dello shortcode.
  5. Anche nell'hook 'save_post' usa wp_remote_request() per inviare una richiesta HTTP GET non bloccante al permalink del post stesso, per attivare il primo caricamento della pagina e l'impostazione del flag persistente.
  6. Infine imposta un hook 'wp_print_styles' e controlla i meta del post per un valore 'yes', 'no' o '' usando la chiave "_has_{$shortcode_name}_shortcode". Se il valore è 'no', non servire il file esterno. Se il valore è 'yes' o '', procedi a servire il file esterno.

E questo dovrebbe essere tutto. Ho scritto e testato un plugin di esempio per mostrare come funziona.

Codice del Plugin di Esempio

Il plugin si attiva con uno shortcode [trigger-css] che imposta gli elementi <h2> della pagina con testo bianco su sfondo rosso, così puoi vedere facilmente che funziona. Assume una sottodirectory css contenente un file style.css con questo CSS:

/*
 * Nome file: css/style.css
 */
h2 {
  color: white;
  background: red;
}

Ecco il codice funzionante del plugin:

<?php
/**
 * Plugin Name: CSS on Shortcode
 * Description: Mostra come caricare condizionalmente uno shortcode
 * Author: Mike Schinkel <mike@newclarity.net>
 */
class CSS_On_Shortcode {

  /**
   * @var CSS_On_Shortcode
   */
  private static $_this;

  /**
   * @var string 'yes'/'no' invece di true/false poiché get_post_meta() restituisce '' per false o chiave non trovata.
   */
  var $shortcode_used = 'no';

  /**
   * @var string
   */
  var $HAS_SHORTCODE_KEY = '_has_trigger-css_shortcode';
  /**
   *
   */
  function __construct() {
    self::$_this = $this;
    add_shortcode( 'trigger-css', array( $this, 'do_shortcode' ) );
    add_filter( 'the_content', array( $this, 'the_content' ), 12 ); // DOPO il do_shortcode() di WordPress
    add_action( 'save_post', array( $this, 'save_post' ) );
    add_action( 'wp_print_styles', array( $this, 'wp_print_styles' ) );
  }

  /**
   * @return CSS_On_Shortcode
   */
  function this() {
    return self::$_this;
  }

  /**
   * @param array $arguments
   * @param string $content
   * @return string
   */
  function do_shortcode( $arguments, $content ) {
    /**
     * Se questo shortcode è utilizzato, cattura il valore così possiamo salvarlo nei post_meta nel filtro 'the_content'.
     */
    $this->shortcode_used = 'yes';
    return '<h2>QUESTO POST AGGIUNGERÀ CSS PER RENDERE I TAG H2 BIANCO SU ROSSO</h2>';
  }

  /**
   * Elimina il meta 'has_shortcode' così che possa essere rigenerato
   * al primo caricamento della pagina nel caso l'uso dello shortcode sia cambiato.
   *
   * @param int $post_id
   */
  function save_post( $post_id ) {
    delete_post_meta( $post_id, $this->HAS_SHORTCODE_KEY );
    /**
     * Ora carica il post in modo asincrono via HTTP per preimpostare il meta value per $this->HAS_SHORTCODE_KEY.
     */
    wp_remote_request( get_permalink( $post_id ), array( 'blocking' => false ) );
  }

  /**
   * @param array $args
   *
   * @return array
   */
  function wp_print_styles( $args ) {
    global $post;
    if ( 'no' != get_post_meta( $post->ID, $this->HAS_SHORTCODE_KEY, true ) ) {
      /**
       * Salta solo se impostato su 'no' poiché '' è sconosciuto.
       */
      wp_enqueue_style( 'css-on-shortcode', plugins_url( 'css/style.css', __FILE__ ) );
    }
   }

  /**
   * @param string $content
   * @return string
   */
  function the_content( $content ) {
    global $post;
    if ( '' === get_post_meta( $post->ID, $this->HAS_SHORTCODE_KEY, true ) ) {
      /**
       * Questa è la prima volta che questo shortcode viene visto per questo post.
       * Salva una meta chiave così che la prossima volta sapremo che questo post usa questo shortcode
       */
      update_post_meta( $post->ID, $this->HAS_SHORTCODE_KEY, $this->shortcode_used );
    }
    /**
     * Rimuovi questo filtro ora. Non ci serve più per questo post.
     */
    remove_filter( 'the_content', array( $this, 'the_content' ), 12 );
    return $content;
  }

}
new CSS_On_Shortcode();

Screenshot di Esempio

Ecco una serie di screenshot

Editor di Post Base, Senza Contenuto

Editor di post WordPress vuoto

Visualizzazione Post, Senza Contenuto

Pagina del post vuota

Editor di Post Base con Shortcode [trigger-css]

Editor di post con shortcode [trigger-css]

Visualizzazione Post con Shortcode [trigger-css]

Pagina del post con stile CSS attivato dallo shortcode

Non Sono Sicuro al 100%

Credo che quanto sopra dovrebbe funzionare in quasi tutti i casi, ma avendo appena scritto questo codice non posso esserne certo al 100%. Se trovi situazioni in cui non funziona, mi piacerebbe saperlo così posso correggere il codice in alcuni plugin a cui ho appena aggiunto questa funzionalità. Grazie in anticipo.

2 gen 2013 08:57:23
Commenti

Quindi cinque plugin che utilizzano il tuo approccio genereranno cinque richieste remote ogni volta che un articolo viene salvato? Preferirei usare una regex su post_content. E per quanto riguarda gli shortcode nei widget?

fuxia fuxia
2 gen 2013 09:02:29

@toscho In realtà il caricamento del post è opzionale; serve solo per assicurarsi che un utente non debba vedere il primo caricamento della pagina con gli elementi esterni. È anche una chiamata non bloccante, quindi in teoria non dovresti accorgertene. Nel nostro codice lo facciamo in una classe base in modo che la classe base possa gestire il fatto che avvenga solo una volta. Potremmo agganciarci all'hook 'pre_http_request' e disabilitare chiamate multiple allo stesso URL mentre l'hook 'save_post' è attivo, ma vorrei aspettare finché non vedremo una reale necessità, no? Per quanto riguarda i Widget, potrebbe essere migliorato per gestirli ma non è un caso d'uso che ho ancora esaminato.

MikeSchinkel MikeSchinkel
2 gen 2013 09:59:16

@toscho - Inoltre non puoi essere sicuro che lo shortcode sia presente poiché un altro hook potrebbe rimuoverlo. L'unico modo per esserne certi è se la funzione dello shortcode viene effettivamente eseguita. Quindi l'approccio con regex non è affidabile al 100%.

MikeSchinkel MikeSchinkel
2 gen 2013 10:03:28

Lo so. Non esiste un modo sicuro al 100% per iniettare CSS per gli shortcode (tranne usando <style>).

fuxia fuxia
2 gen 2013 10:05:39

Sto lavorando con un'implementazione basata su questa soluzione e volevo solo far notare che questo metodo non verrà accodato per l'anteprima di un articolo/pagina.

mor7ifer mor7ifer
2 ago 2015 17:45:38

La mia soluzione per il problema dell'anteprima: https://gist.github.com/mor7ifer/e50a9864a372a05b4a3b

mor7ifer mor7ifer
2 ago 2015 18:42:24
Mostra i restanti 1 commenti
11

Cercando su Google ho trovato una potenziale risposta. Dico "potenziale" perché sembra valida, dovrebbe funzionare, ma non sono sicuro al 100% che sia il modo migliore per farlo:

add_action( 'wp_print_styles', 'yourplugin_include_css' );
function yourplugin_include_css() {
    // Verifica se lo shortcode è presente nel contenuto della pagina o del post
    global $post;

    // Ho rimosso la chiusura ' ] '... così può accettare argomenti.
    if ( strstr( $post->post_content, '[yourshortcode ' ) ) {
        echo $csslink;
    }
}

Questo codice dovrebbe verificare se il post corrente utilizza uno shortcode e aggiungere un foglio di stile all'elemento <head> in modo appropriato. Tuttavia, non credo che funzioni per una pagina indice (ad esempio, più post nel loop)... Inoltre, proviene da un post di blog di 2 anni fa, quindi non sono nemmeno sicuro che funzioni con WP 3.1.X.

23 giu 2011 18:34:45
Commenti

Questo non funzionerà se lo shortcode ha argomenti. Se vuoi davvero procedere in questo modo, che è lento, usa get_shortcode_regex() di WP per la ricerca.

onetrickpony onetrickpony
23 giu 2011 18:39:14

Come ho detto, risposta "potenziale" che non ho ancora testato... :-)

EAMann EAMann
23 giu 2011 18:39:56

Questo è fondamentalmente lo stesso del metodo 2, ma non controlla ancora il template per le chiamate a do_shortcode().

Ian Dunn Ian Dunn
23 giu 2011 18:45:17

Perché dovrebbe farlo? Se chiami do_shortcode() manualmente nel template, sai già che eseguirai lo shortcode

onetrickpony onetrickpony
23 giu 2011 18:50:08

Non sono io a chiamare lo shortcode, ma l'utente. Questo è per un plugin distribuito, non privato.

Ian Dunn Ian Dunn
23 giu 2011 19:06:51

ok, quindi è per questo che vuoi un markup valido :) Stai dicendo che il tuo plugin istruisce l'utente a modificare i file template e chiamare quella funzione? Allora, a meno che non crei il tuo parser PHP, non c'è modo di sapere dove e quando quella funzione viene chiamata...

onetrickpony onetrickpony
23 giu 2011 19:12:24

Voglio sempre un markup valido, indipendentemente dalle circostanze... Il plugin non dice all'utente di chiamare la funzione, ma è sempre un'opzione. Un utente può sempre chiamare qualsiasi shortcode digitandolo nell'area di contenuto di un post/pagina o semplicemente chiamando do_shortcode() in un template, quindi entrambe le situazioni devono essere gestite. E non credo di dover scrivere il mio parser PHP, ho solo bisogno di analizzare il file template assegnato alla pagina corrente (se ce n'è uno) per vedere se lo shortcode è al suo interno.

Ian Dunn Ian Dunn
23 giu 2011 19:38:02

Supponendo che tu possa scoprire quale file template viene utilizzato dalla pagina corrente (cosa di cui dubito), come lo analizzeresti senza un parser? regex? E se la riga con il codice è commentata? Ci sono dozzine di modi per commentare il codice PHP

onetrickpony onetrickpony
23 giu 2011 19:59:30

Il template assegnato è semplicemente memorizzato nella tabella post_meta, cosa c'è di così difficile da scoprire? Puoi agganciarti a the_posts per ottenere accesso al $post corrente prima che venga emesso qualsiasi output. Con 'parser PHP' intendevo l'intero motore, non solo una funzione strpos o regex. Le righe commentate sono un caso limite di cui non sono veramente preoccupato.

Ian Dunn Ian Dunn
23 giu 2011 21:06:22

stai confondendo i template delle pagine (come nel post-type page) con i file del tema utilizzati come template

onetrickpony onetrickpony
23 giu 2011 21:20:18

Ah, stai parlando dei template predefiniti (ad esempio single.php, home.php) in contrapposizione a un template personalizzato creato specificamente per una pagina (ad esempio map.php), giusto? È un buon punto. Scommetto che esiste un modo per capire quale viene utilizzato, ma al momento non lo ricordo.

Ian Dunn Ian Dunn
23 giu 2011 21:44:48
Mostra i restanti 6 commenti
0

Utilizzando una combinazione della risposta di TheDeadMedic e della documentazione di get_shortcode_regex() (documentazione) (che in realtà non trovava i miei shortcode), ho creato una semplice funzione per caricare gli script per più shortcode. Dato che wp_enqueue_script() negli shortcode aggiunge solo nel footer, questo può essere utile perché gestisce sia gli script per l'header che per il footer.


function add_shortcode_scripts() {
    global $wp_query;   
    $posts = $wp_query->posts;
    $scripts = array(
        array(
            'handle' => 'map',
            'src' => 'http://maps.googleapis.com/maps/api/js?sensor=false',
            'deps' => '',
            'ver' => '3.0',
            'footer' => false
        ),
        array(
            'handle' => 'contact-form',
            'src' => get_template_directory_uri() . '/library/js/jquery.validate.min.js',
            'deps' => array( 'jquery' ),
            'ver' => '1.11.1',
            'footer' => true
        )   
    );

    foreach ( $posts as $post ) {
        foreach ( $scripts as $script ) {
            if ( preg_match( '#\[ *' . $script['handle'] . '([^\]])*\]#i', $post->post_content ) ) {
                // carica css e/o js
                if ( wp_script_is( $script['handle'], 'registered' ) ) {
                    return;
                } else {
                    wp_register_script( $script['handle'], $script['src'], $script['deps'], $script['ver'], $script['footer'] );
                    wp_enqueue_script( $script['handle'] );
                }
            }
        }
    }
}
add_action( 'wp', 'add_shortcode_scripts' );
30 nov 2013 21:52:06
1

Finalmente ho trovato anche una soluzione per il caricamento condizionale del CSS che funziona per il mio plugin www.mapsmarker.com e vorrei condividerla con voi. Controlla se il mio shortcode è utilizzato all'interno del file template corrente e in header.php/footer.php e, in caso affermativo, carica il foglio di stile necessario nell'header:

  function prefix_template_check_shortcode( $template ) {
    $searchterm = '[mapsmarker';
    $files = array( $template, get_stylesheet_directory() . DIRECTORY_SEPARATOR . 'header.php', get_stylesheet_directory() . DIRECTORY_SEPARATOR . 'footer.php' );
    foreach( $files as $file ) {
        if( file_exists($file) ) {
            $contents = file_get_contents($file);
            if( strpos( $contents, $searchterm )  ) {
                wp_enqueue_style('
leafletmapsmarker', LEAFLET_PLUGIN_URL . 'leaflet-dist/leaflet.css');
                  break; 
            }
        }
    }
  return $template;
  }  
  add_action('template_include','prefix_template_check_shortcode' );
12 dic 2012 23:29:42
Commenti

un po' fuori tema, ma questo non presuppone che le persone stiano usando header.php e footer.php? E i metodi di wrapping dei temi come quelli descritti da http://scribu.net/wordpress/theme-wrappers.html? O temi come Roots che mantengono le loro parti di template altrove?

orionrush orionrush
3 mar 2013 14:32:51
0

Per il mio plugin ho scoperto che a volte gli utenti hanno un theme builder che memorizza gli shortcode nei metadati del post. Ecco cosa sto usando per rilevare se lo shortcode del mio plugin è presente nell'attuale post o nei metadati del post:

function abcd_load_my_shorcode_resources() {
       global $post, $wpdb;

       // determina se questa pagina contiene lo shortcode "my_shortcode"
       $shortcode_found = false;
       if ( has_shortcode($post->post_content, 'my_shortcode') ) {
          $shortcode_found = true;
       } else if ( isset($post->ID) ) {
          $result = $wpdb->get_var( $wpdb->prepare(
            "SELECT count(*) FROM $wpdb->postmeta " .
            "WHERE post_id = %d and meta_value LIKE '%%my_shortcode%%'", $post->ID ) );
          $shortcode_found = ! empty( $result );
       }

       if ( $shortcode_found ) {
          wp_enqueue_script(...);
          wp_enqueue_style(...);
       }
}
add_action( 'wp_enqueue_scripts', 'abcd_load_my_shorcode_resources' );
6 nov 2015 02:24:01
14

perché il CSS dovrebbe essere dichiarato all'interno di <head>

Per i file CSS puoi caricarli all'interno dell'output del tuo shortcode:

<style type="text/css">
  @import "percorso/del/tuo.css"; 
</style>

Imposta una costante o qualcosa di simile dopo questo, come MY_CSS_LOADED (includi il CSS solo se la costante non è impostata).

Entrambi i tuoi metodi sono più lenti rispetto a questo approccio.

Per i file JS puoi fare lo stesso se lo script che stai caricando è unico e non ha dipendenze esterne. Se non è questo il caso, caricalo nel footer, ma usa la costante per determinare se deve essere caricato o meno...

23 giu 2011 18:22:16
Commenti

Caricare CSS al di fuori dell'elemento <head> non è un markup corretto. Vero, la validazione è solo una linea guida, ma se stiamo cercando di seguirla, rende l'idea di caricare il foglio di stile all'interno dell'output dello shortcode una cattiva idea.

EAMann EAMann
23 giu 2011 18:29:09

I blocchi CSS inline sono markup validi, anche in XHTML da quello che ricordo. Non c'è motivo di non usarli quando non hai altre alternative accettabili.

onetrickpony onetrickpony
23 giu 2011 18:32:37

Secondo lo strumento di validazione W3C: <style type="text/css"> L'elemento menzionato sopra è stato trovato in un contesto dove non è consentito. Questo potrebbe significare che hai annidato gli elementi in modo errato -- come un elemento "style" nella sezione "body" invece che all'interno di "head". Quindi gli stili inline (<element style="..."></element>) sono validi, ma gli elementi <style> inline non lo sono.

EAMann EAMann
23 giu 2011 18:36:59

Sì, so che è una possibilità, ma è considerata una cattiva pratica. Potrebbe causare FOUC, costringere il browser a ri-renderizzare la pagina e far fallire il validatore W3C. Inoltre non funzionerebbe con wp_enqueue_style(), rendendo impossibile per altri sviluppatori di temi/plugin sostituire facilmente i propri script/stili.

Ian Dunn Ian Dunn
23 giu 2011 18:41:04

@EAMann. Vero, errore mio, pensavo che sarebbe stato valido. Comunque, la validazione W3C non significa nulla...

onetrickpony onetrickpony
23 giu 2011 18:43:17

@One Trick Pony Ehm... Significa qualcosa per me. E significa qualcosa per ogni altro sviluppatore che rispetto. Non la seguo ciecamente, ma sarebbe raro che consideri accettabile qualsiasi cosa che violi gli standard.

Ian Dunn Ian Dunn
23 giu 2011 18:49:06

Se non lo segui ciecamente, puoi fornire delle ragioni per cui questa pratica è sbagliata?

onetrickpony onetrickpony
23 giu 2011 18:51:00

Ho dato 4 motivi nel mio commento qui sopra...

Ian Dunn Ian Dunn
23 giu 2011 19:11:02

È considerata una cattiva pratica ma questo è esattamente quello che fa lo shortcode della galleria nel core di WordPress: stampa un blocco CSS inline. È un po' meglio che usare l'attributo style e funziona. Il mio plugin che ha uno shortcode stampa semplicemente il CSS nell'head in ogni visualizzazione. Non ce n'è molto :)

mfields mfields
23 giu 2011 19:42:13

@mfields, se faccio così allora altri sviluppatori di temi/plugin non possono sostituire i file con i propri. Non importa se il core lo fa, rimane comunque una cattiva pratica.

Ian Dunn Ian Dunn
23 giu 2011 19:47:29

rendilo filtrabile e qualsiasi altro plugin o tema può fare come preferisce con esso. Se configurano il filtro per restituire una stringa vuota - non verrà stampato nulla.

mfields mfields
23 giu 2011 19:51:50

Non hai menzionato alcuna ragione oggettiva contro questa pratica. Comunque non importa; vedo solo due opzioni qui: Caricare sempre CSS/script (ottimizzandoli per dimensione), o stili inline condizionali

onetrickpony onetrickpony
23 giu 2011 20:01:08

@mfields, è un buon punto, ma preferisco l'approccio enqueue_style.

Ian Dunn Ian Dunn
23 giu 2011 21:09:49

@One Trick Pony, penso che tu abbia torto, ma sono stanco di discutere al riguardo.

Ian Dunn Ian Dunn
23 giu 2011 21:10:02
Mostra i restanti 9 commenti