Încărcarea condiționată a JavaScript/CSS pentru shortcode-uri

23 iun. 2011, 18:07:29
Vizualizări: 17.8K
Voturi: 41

Am lansat un plugin care creează un shortcode și necesită încărcarea unui fișier JavaScript și a unui fișier CSS pe orice pagină care conține acel shortcode. Aș putea pur și simplu să fac ca scriptul/stilul să se încarce pe toate paginile, dar asta nu este cea mai bună practică. Vreau să încarc fișierele doar pe paginile care folosesc shortcode-ul. Am găsit două metode de a face acest lucru, dar ambele au probleme.

Metoda 1 setează un flag la true în interiorul funcției de gestionare a shortcode-ului și apoi verifică această valoare într-un callback wp_footer. Dacă este true, folosește wp_print_scripts() pentru a încărca JavaScript-ul. Problema cu această metodă este că funcționează doar pentru JavaScript și nu pentru CSS, deoarece CSS-ul ar trebui declarat în <head>, ceea ce poți face doar în timpul unui hook timpuriu precum init sau wp_head.

Metoda 2 se execută mai devreme și "se uită înainte" pentru a verifica dacă shortcode-ul există în conținutul paginii curente. Îmi place această metodă mult mai mult decât prima, dar problema este că nu va detecta dacă șablonul apelează do_shortcode().

Așadar, mă orientez spre utilizarea celei de-a doua metode și apoi încerc să detectez dacă este atribuit un șablon și, dacă da, să-l analizez pentru shortcode. Înainte de a face acest lucru, însă, am vrut să verific dacă cineva cunoaște o metodă mai bună.

Actualizare: Am integrat soluția în plugin-ul meu. Dacă cineva este curios să o vadă implementată într-un mediu real, puteți descărca plugin-ul sau răsfoi codul.

Actualizare 2: Începând cu WordPress 3.3, este posibil să apelezi wp_enqueue_script() direct în interiorul unui callback de shortcode, iar fișierul JavaScript va fi încărcat în footer-ul documentului. Acest lucru este tehnic posibil și pentru fișierele CSS, dar ar trebui considerată o practică proastă deoarece afișarea CSS-ului în afara tag-ului <head> încalcă specificațiile W3C, poate cauza FOUC (Flash of Unstyled Content) și poate forța browserul să re-randeze pagina.

10
Comentarii

Am folosit o variație a Metodei 1 în trecut. Încărcați JS pentru shortcode în subsol, încărcați CSS pentru shortcode inline. Funcționează, dar este cam improvizat. Aștept cu nerăbdare o soluție mai bună.

EAMann EAMann
23 iun. 2011 18:14:52

Principalele probleme cu CSS-ul inline sunt că este greu de suprascris cu alte stiluri și nu folosește metoda wp_enqueue_styles().

Ian Dunn Ian Dunn
23 iun. 2011 19:05:16

Cât CSS ai?

mfields mfields
23 iun. 2011 19:35:32

Câte linii de cod JavaScript?

mfields mfields
23 iun. 2011 19:36:42

Sunt aproximativ 30 de linii de CSS și 100 de linii de JavaScript, dar asta nu este relevant. Ele trebuie incluse în modul CORECT, indiferent de dimensiune. Vezi comentariile de la răspunsuri pentru motivele din spate.

Ian Dunn Ian Dunn
23 iun. 2011 19:45:43

Partea cu JavaScript este cea ușoară. Cea mai bună metodă de a face asta este sub "Jedi" aici: http://scribu.net/wordpress/optimal-script-loading.html

mfields mfields
23 iun. 2011 19:55:27

30 de linii nu este foarte mult, aș minifica codul și l-aș afișa în head într-un tag style în toate view-urile. Să se ofere un filtru și/sau o setare care să permită utilizatorului să dezactiveze stilurile dacă dorește.

mfields mfields
23 iun. 2011 19:59:12

@mfields, deja știu despre acea metodă, am menționat-o în întrebare... Te rog să citești RTFQ înainte de a comenta ;)

Ian Dunn Ian Dunn
23 iun. 2011 21:02:10

Atunci deja știi CEA mai bună metodă de a gestiona javascriptul ;) CEA mai bună metodă, în opinia mea, de a gestiona CSS-ul este "30 de linii nu este foarte mult, aș minifica codul și l-aș afișa în head într-un tag style în toate view-urile. Să se ofere un filtru și/sau o setare care să permită utilizatorului să dezactiveze stilurile dacă dorește." Dacă trebuie să folosești wp_enqueue_script(), nu ezita, dar nu cred că este necesar deoarece adaugă încă o cerere HTTP. Minifică -> afișează în wp_head() -> permite altor extensii să filtreze output-ul.

mfields mfields
23 iun. 2011 21:14:52

Cred că fișierele separate sunt mai curate și oferă o organizare mai bună. Minificarea poate fi făcută de server în timp real.

Ian Dunn Ian Dunn
23 iun. 2011 21:40:56
Arată celelalte 5 comentarii
Toate răspunsurile la întrebare 7
9
11

Bazat pe experiența mea personală, am folosit o combinație dintre metodele 1 și 2 - arhitectura și scripturile din footer ale metodei 1 și tehnica de "look-ahead" din metoda 2.

Totuși, pentru "look-ahead" folosesc regex în loc de stripos; preferință personală, mai rapid și poate verifica shortcode-uri 'malformate':

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

Dacă ești îngrijorat de autorii care folosesc manual do_shortcode, aș recomanda să le instruiești să folosească un apel de acțiune încarce manual stilul pre-înregistrat.

ACTUALIZARE: Pentru autorul leneș care nu citește niciodată manualul, afișează un mesaj care să sublinieze greșeala lor ;)

function my_shortcode()
{
    static $enqueued;
    if ( ! isset( $enqueued ) )
        $enqueued = wp_style_is( 'my_style', 'done' ); // cache pentru a nu repeta dacă e apelat de mai multe ori

    // procesează shortcode-ul
    $output = '';

    if ( ! $enqueued )
        // poți afișa mesajul doar la prima apariție încadrându-l în condiția anterioară
        $output .= <<<HTML
<p>Atenție! Trebuie să încarci manual fișierul de stiluri pentru shortcode dacă folosești <code>do_shortcode()</code> direct!</p>
<p>Folosește <code>wp_enqueue_style( 'my_style' );</code> înainte de apelul <code>get_header()</code> în template-ul tău.</p>
HTML;

    return $output;
}
23 iun. 2011 21:23:00
Comentarii

Acesta este un punct bun. În mod ideal, aș dori să funcționeze fără ca ei să facă ceva în plus - pentru că în jumătate din cazuri probabil nu vor citi mai întâi FAQ-ul, așa că vor presupune pur și simplu că nu funcționează - dar s-ar putea să ajung să fac asta. Aș putea înregistra scripturile pe fiecare pagină, dar să le încarc doar dacă detectez un shortcode. Atunci, utilizatorii ar putea să se conecteze la init și să apeleze funcțiile de încărcare în șabloane specifice unde este nevoie, presupunând că nu este deja prea târziu în execuție în acel moment. De asemenea, WP are get_shortcode_regex() încorporat.

Ian Dunn Ian Dunn
23 iun. 2011 21:54:54

Dacă utilizatorii sunt pricepuți în implementarea do_shortcode(), nu este rezonabil să presupunem că sunt la fel de pricepuți în urmărirea instrucțiunilor pentru încărcarea stilului shortcode-ului?

Chip Bennett Chip Bennett
23 iun. 2011 22:16:03

Adevărat, dar va obține regex pentru toate shortcode-urile, nu doar pentru ale tale ;) "Aș putea înregistra scripturile pe fiecare pagină" Probabil și metoda mai bună! Reține că nu trebuie să se conecteze la init, doar oriunde înainte de wp_head. Pentru dezvoltatorul leneș, verifică wp_style_is( 'my_style_handle', 'done' ) în interiorul shortcode-ului tău. Dacă este fals, afișează o eroare vizibilă care le instruiește ce să facă.

TheDeadMedic TheDeadMedic
23 iun. 2011 22:17:52

@Chip - Nu mă îngrijorează că nu sunt capabili să urmărească instrucțiunile, ci doar că nu vor ști că ar trebui să o facă, deoarece în 99% din cazuri nu este nevoie să faci nimic în plus.

Ian Dunn Ian Dunn
24 iun. 2011 01:05:05

@Ian, gândirea mea era că adăugarea lui do_shortcode() în șablon este deja "a face ceva în plus" - iar utilizatorii care ar face acel ceva-în-plus ar ști deja despre necesitatea de a încărca stilul sau ar fi mai dispuși/mai probabil să urmărească instrucțiuni speciale.

Chip Bennett Chip Bennett
24 iun. 2011 02:03:16

@TheDeadMedic - Am integrat-o în codul meu și am actualizat întrebarea cu linkuri către el în caz că cineva vrea să o vadă detaliată. Mulțumesc din nou pentru ajutor :)

Ian Dunn Ian Dunn
26 iun. 2011 08:27:34

@Ian Super! Mulțumim că ai revenit cu o actualizare, atât pentru noi cât și pentru cei care vor ajunge aici ulterior prin Google ;)

TheDeadMedic TheDeadMedic
26 iun. 2011 08:41:34

Bun punct, dar trebuie să nu fiu de acord că preg_match ar fi mai rapid decât strpos http://lzone.de/articles/php-string-search.htm

Bainternet Bainternet
5 feb. 2012 19:57:30

@Bainternet Nu neapărat - preg_match vs stripos (versiunea insensibilă la majuscule) - oricum vorbim de diferențe minuscule de timp. Privind în urmă, cred că ar fi trebuit să evit termenul "mai rapid" - voiam mai degrabă să sugerez că este mai eficient pentru sarcina respectivă (față de folosirea mai multor stripos pentru a acoperi diverse formate de shortcode).

TheDeadMedic TheDeadMedic
9 feb. 2012 20:35:16
Arată celelalte 4 comentarii
6

Răspund târziu la această întrebare, dar deoarece Ian a inițiat acest fir de discuție pe lista wp-hackers astăzi, m-am gândit că merită să răspund, mai ales având în vedere că am planificat să adaug o astfel de funcționalitate la unele pluginuri la care lucrez.

O abordare de luat în considerare este să verifici la prima încărcare a paginii dacă shortcode-ul este folosit efectiv și apoi să salvezi starea utilizării shortcode-ului într-o cheie de meta pentru post. Iată cum:

Ghid Pas cu Pas

  1. Setează un flag $shortcode_used la 'no'.
  2. În funcția shortcode-ului însuși, setează flagul $shortcode_used la 'yes'.
  3. Setează un hook 'the_content' cu prioritatea 12 (după ce WordPress a procesat shortcode-urile) și verifică meta pentru post pentru o valoare '' folosind cheia "_has_{$shortcode_name}_shortcode". (O valoare '' este returnată când o cheie de meta pentru post nu există pentru ID-ul postului.)
  4. Folosește un hook 'save_post' pentru a șterge meta-ul postului, eliminând flagul persistent pentru acel post în cazul în care utilizatorul modifică utilizarea shortcode-ului.
  5. De asemenea, în hook-ul 'save_post', folosește wp_remote_request() pentru a trimite un HTTP GET non-blocant către permalink-ul propriu al postului pentru a declanșa prima încărcare a paginii și setarea flagului persistent.
  6. În final, setează un hook 'wp_print_styles' și verifică meta-ul postului pentru o valoare de 'yes', 'no' sau '' folosind cheia "_has_{$shortcode_name}_shortcode". Dacă valoarea este 'no', nu încărca fișierul extern. Dacă valoarea este 'yes' sau '', încarcă fișierul extern.

Și asta ar trebui să fie suficient. Am scris și testat un plugin exemplu pentru a arăta cum funcționează toate acestea.

Cod Exemplu pentru Plugin

Pluginul se activează la un shortcode [trigger-css] care setează elementele <h2> ale paginii pe alb pe roșu, astfel încât să poți vedea ușor că funcționează. Se presupune un subdirector css care conține un fișier style.css cu următorul CSS:

/*
 * Nume fișier: css/style.css
 */
h2 {
  color: white;
  background: red;
}

Și mai jos este codul într-un plugin funcțional:

<?php
/**
 * Plugin Name: CSS pe Shortcode
 * Description: Arată cum să încarci condiționat un shortcode
 * Author: Mike Schinkel <mike@newclarity.net>
 */
class CSS_On_Shortcode {

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

  /**
   * @var string 'yes'/'no' vs. true/false deoarece get_post_meta() returnează '' pentru false și pentru chei inexistente.
   */
  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 ); // DUPĂ do_shortcode() din 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 ) {
    /**
     * Dacă acest shortcode este folosit, captează valoarea pentru a o salva în post_meta în filtrul 'the_content'.
     */
    $this->shortcode_used = 'yes';
    return '<h2>ACEST POST VA ADAUGA CSS PENTRU A FACE ELEMENTELE H2 ALBE PE ROȘU</h2>';
  }

  /**
   * Șterge valoarea meta 'has_shortcode' pentru a putea fi regenerată
   * la prima încărcare a paginii, în cazul în care utilizarea shortcode-ului s-a schimbat.
   *
   * @param int $post_id
   */
  function save_post( $post_id ) {
    delete_post_meta( $post_id, $this->HAS_SHORTCODE_KEY );
    /**
     * Acum încarcă postul asincron prin HTTP pentru a pre-set valoarea meta pentru $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 ) ) {
      /**
       * Doar ocolește dacă este setat la 'no', deoarece '' este necunoscut.
       */
      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 ) ) {
      /**
       * Aceasta este prima dată când shortcode-ul este văzut pentru acest post.
       * Salvează o cheie post_meta pentru ca data viitoare să știm că acest post folosește acest shortcode.
       */
      update_post_meta( $post->ID, $this->HAS_SHORTCODE_KEY, $this->shortcode_used );
    }
    /**
     * Elimină acest filtru acum. Nu avem nevoie de el pentru acest post din nou.
     */
    remove_filter( 'the_content', array( $this, 'the_content' ), 12 );
    return $content;
  }

}
new CSS_On_Shortcode();

Capturi de Ecran Exemplu

Iată o serie de capturi de ecran

Editor de Post de Bază, Fără Conținut

Editor de post gol fără conținut

Afișare Post, Fără Conținut

Post afișat fără conținut

Editor de Post de Bază cu Shortcode [trigger-css]

Editor de post cu shortcode trigger-css

Afișare Post cu Shortcode [trigger-css]

Post afișat cu efectul CSS din shortcode

Nu Sunt Sigur că e 100%

Cred că cele de mai sus ar trebui să funcționeze în aproape toate cazurile, dar cum tocmai am scris acest cod, nu pot fi 100% sigur. Dacă găsești situații în care nu funcționează, aș dori să știu pentru a putea repara codul în unele pluginuri la care tocmai am adăugat această funcționalitate. Mulțumesc anticipat.

2 ian. 2013 08:57:23
Comentarii

Deci cinci pluginuri care folosesc abordarea ta vor declanșa cinci cereri la distanță de fiecare dată când un articol este salvat? Aș prefera să folosesc o expresie regulată pe post_content. Și cum rămâne cu shortcode-urile în widget-uri?

fuxia fuxia
2 ian. 2013 09:02:29

@toscho Declanșarea încărcării postărilor este de fapt opțională; există doar pentru a se asigura că utilizatorul nu va vedea prima încărcare a paginii cu resursele externe încărcate. De asemenea, este un apel non-blocant, deci teoretic nu ar trebui să-l observi. Pentru codul nostru facem asta într-o clasă de bază, astfel încât clasa de bază poate gestiona faptul că se face o singură dată. Am putea folosi hook-ul 'pre_http_request' și să dezactivăm apelurile multiple către aceeași URL cât timp hook-ul 'save_post' este activ, dar aș aștepta până când chiar vedem nevoia pentru asta, nu? În ceea ce privește widget-urile, s-ar putea îmbunătăți pentru a le gestiona, dar nu este un caz de utilizare pe care l-am analizat încă.

MikeSchinkel MikeSchinkel
2 ian. 2013 09:59:16

@toscho - De asemenea, nu poți fi sigur că shortcode-ul este acolo, deoarece un alt hook l-ar putea șterge. Singura modalitate de a fi sigur este dacă funcția shortcode se execută efectiv. Deci abordarea cu regex nu este 100% sigură.

MikeSchinkel MikeSchinkel
2 ian. 2013 10:03:28

Știu. Nu există nicio metodă infallibilă de a injecta CSS pentru shortcode-uri (cu excepția utilizării <style>).

fuxia fuxia
2 ian. 2013 10:05:39

Lucrez cu o implementare bazată pe această soluție și voiam să subliniez că această metodă nu va încărca stilurile pentru previzualizarea unei postări/pagini.

mor7ifer mor7ifer
2 aug. 2015 17:45:38

Soluția mea pentru problema previzualizării: https://gist.github.com/mor7ifer/e50a9864a372a05b4a3b

mor7ifer mor7ifer
2 aug. 2015 18:42:24
Arată celelalte 1 comentarii
11

Căutând pe Google am găsit un posibil răspuns. Spun "posibil" pentru că pare bun, ar trebui să funcționeze, dar nu sunt 100% convins că este cea mai bună metodă:

add_action( 'wp_print_styles', 'yourplugin_include_css' );
function yourplugin_include_css() {
    // Verifică dacă shortcode-ul există în conținutul paginii sau postării
    global $post;

    // Am eliminat ' ] ' de la final... pentru a accepta argumente.
    if ( strstr( $post->post_content, '[yourshortcode ' ) ) {
        echo $csslink;
    }
}

Această soluție ar trebui să verifice dacă postarea curentă utilizează un shortcode și să adauge o foaie de stil în elementul <head> în mod corespunzător. Dar nu cred că va funcționa pentru o pagină de index (adică mai multe postări în buclă)... De asemenea, provine de la un post de blog vechi de 2 ani, așa că nu sunt sigur că va funcționa cu WP 3.1.X.

23 iun. 2011 18:34:45
Comentarii

Acest lucru nu va funcționa dacă shortcode-ul are argumente. Dacă chiar vrei să mergi pe această cale, care este lentă, folosește get_shortcode_regex() din WP pentru căutare.

onetrickpony onetrickpony
23 iun. 2011 18:39:14

Cum am spus, un răspuns "potențial" pe care nu l-am testat încă ... :-)

EAMann EAMann
23 iun. 2011 18:39:56

În esență, este la fel ca metoda 2, dar tot nu verifică template-ul pentru apelurile do_shortcode().

Ian Dunn Ian Dunn
23 iun. 2011 18:45:17

De ce ar trebui să facă asta? Dacă apelezi manual do_shortcode() în template, atunci deja știi că vei rula shortcode-ul

onetrickpony onetrickpony
23 iun. 2011 18:50:08

Nu eu apelez shortcode-ul, ci utilizatorul. Acesta este un plugin distribuit, nu unul privat.

Ian Dunn Ian Dunn
23 iun. 2011 19:06:51

ok, deci de asta vrei markup valid :) Spui că plugin-ul tău instruiește utilizatorul să editeze fișierele de template și să apeleze acea funcție? Atunci, dacă nu creezi propriul tău parser PHP, nu există nicio modalitate prin care să știi unde și când este apelată acea funcție...

onetrickpony onetrickpony
23 iun. 2011 19:12:24

Întotdeauna vreau un markup valid, indiferent de circumstanțe... Pluginul nu îi spune utilizatorului să apeleze funcția, dar aceasta rămâne întotdeauna o opțiune. Un utilizator poate apela orice shortcode fie tastându-l în zona de conținut a unui post/pagină, fie prin apelarea do_shortcode() într-un template, așadar ambele situații trebuie gestionate. Și nu cred că trebuie să scriu propriul meu parser PHP, ci doar să analizez fișierul de template asociat paginii curente (dacă există unul) pentru a verifica dacă shortcode-ul se află în el.

Ian Dunn Ian Dunn
23 iun. 2011 19:38:02

Presupunând că ai putea afla care fișier de template este folosit de pagina curentă (ceea ce mă îndoiesc), cum ai face parsing fără un parser? regex-uri? Dar dacă linia cu codul este comentată? Există zeci de modalități de a comenta codul PHP

onetrickpony onetrickpony
23 iun. 2011 19:59:30

Template-ul asociat este pur și simplu stocat în tabelul post_meta, ce e atât de greu în a-l identifica? Poți folosi hook-ul the_posts pentru a accesa variabila $post curentă înainte ca orice să fie afișat. Prin 'parser PHP' am presupus că te refereai la întregul motor, nu doar la o funcție strpos sau regex. Liniile comentate sunt un caz extrem de care nu sunt prea îngrijorat.

Ian Dunn Ian Dunn
23 iun. 2011 21:06:22

îți confunzi șabloanele de pagini (ca în post-type page) cu fișierele de temă folosite ca șabloane

onetrickpony onetrickpony
23 iun. 2011 21:20:18

Ah, vorbești despre șabloanele implicite (ex: single.php, home.php) în opoziție cu un șablon personalizat creat special pentru o pagină (ex: map.php), corect? E un punct bun. Sunt sigur că există o metodă de a afla care este folosit, dar nu o știu pe moment.

Ian Dunn Ian Dunn
23 iun. 2011 21:44:48
Arată celelalte 6 comentarii
0

Folosind o combinație între răspunsul lui TheDeadMedic și documentația get_shortcode_regex() (care de fapt nu a găsit shortcode-urile mele), am creat o funcție simplă folosită pentru a încărca scripturile pentru multiple shortcode-uri. Deoarece wp_enqueue_script() în shortcode-uri adaugă doar în footer, aceasta poate fi utilă deoarece poate gestiona atât scripturile din header cât și din 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 ) ) {
                // încarcă css și/sau 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

În sfârșit am găsit o soluție pentru încărcarea condiționată a CSS-ului care funcționează pentru plugin-ul meu www.mapsmarker.com și aș dori să o împărtășesc cu voi. Aceasta verifică dacă shortcode-ul meu este folosit în fișierul template curent și în header.php/footer.php, iar dacă da, încarcă fișierul de stil necesar în 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 dec. 2012 23:29:42
Comentarii

un pic pe lângă subiect, dar nu presupune asta că oamenii folosesc header.php și footer.php? Dar despre metodele de înfășurare a temelor, cum ar fi cele descrise de http://scribu.net/wordpress/theme-wrappers.html? Sau teme precum roots care își păstrează părțile de șablon în altă parte?

orionrush orionrush
3 mar. 2013 14:32:51
0

Pentru plugin-ul meu am descoperit că uneori utilizatorii au un constructor de teme care stochează shortcode-uri în metadatele postării. Iată ce folosesc pentru a detecta dacă shortcode-ul meu este prezent în postarea curentă sau în metadatele postării:

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

       // determină dacă această pagină conține shortcode-ul "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

deoarece CSS ar trebui declarat în interiorul <head>

Pentru fișierele CSS le puteți încărca în interiorul output-ului shortcode-ului:

<style type="text/css">
  @import "calea/către/fișierul-tău.css"; 
</style>

Setați o constantă sau ceva similar după aceasta, cum ar fi MY_CSS_LOADED (includeți CSS-ul doar dacă constanta nu este setată).

Ambele metode propuse de tine sunt mai lente decât această abordare.

Pentru fișierele JS puteți face la fel dacă scriptul pe care îl încărcați este unic și nu are dependințe externe. Dacă acesta nu este cazul, încărcați-l în footer, dar folosiți constanta pentru a determina dacă trebuie încărcat sau nu...

23 iun. 2011 18:22:16
Comentarii

Încărcarea CSS în afara elementului <head> nu este un markup corect. Este adevărat că validarea este doar o linie directoare, dar dacă încercăm să respectăm această linie directoare, atunci încărcarea fișierului de stiluri în output-ul shortcode-ului este o idee proastă.

EAMann EAMann
23 iun. 2011 18:29:09

Blocurile CSS inline sunt markup valid, chiar și în XHTML din câte îmi amintesc. Nu există niciun motiv să nu le folosești atunci când nu ai altă alternativă acceptabilă.

onetrickpony onetrickpony
23 iun. 2011 18:32:37

Conform instrumentului de validare W3C: <style type="text/css"> Elementul menționat mai sus a fost găsit într-un context în care nu este permis. Aceasta poate însemna că ai imbricat incorect elementele -- cum ar fi un element "style" în secțiunea "body" în loc să fie în interiorul "head". Deci stilurile inline (<element style="..."></element>) sunt valide, dar elementele <style> inline nu sunt.

EAMann EAMann
23 iun. 2011 18:36:59

Da, știu că asta este o posibilitate, dar este considerată o practică proastă. Ar putea cauza FOUC, forța browserul să re-randeze pagina și să eșueze validarea W3C. De asemenea, nu va funcționa cu wp_enqueue_style(), făcând imposibil pentru alți dezvoltatori de teme/pluginuri să înlocuiască ușor propriile scripturi/stiluri.

Ian Dunn Ian Dunn
23 iun. 2011 18:41:04

@EAMann. Corect, greșeala mea, am crezut că va valida. Totuși, validarea W3C nu înseamnă nimic...

onetrickpony onetrickpony
23 iun. 2011 18:43:17

@One Trick Pony Um... Înseamnă ceva pentru mine. Și înseamnă ceva pentru fiecare alt dezvoltator pe care îl respect. Nu o urmez orbeste, dar ar fi rar pentru mine să consider orice ce încalcă standardele ca fiind un răspuns acceptabil.

Ian Dunn Ian Dunn
23 iun. 2011 18:49:06

Dacă nu o urmezi orbește, atunci poți să oferi motive pentru care această practică este rea?

onetrickpony onetrickpony
23 iun. 2011 18:51:00

Am dat 4 motive în comentariul meu de mai sus...

Ian Dunn Ian Dunn
23 iun. 2011 19:11:02

Este considerată o practică rea, dar exact asta face shortcode-ul de galerie din WordPress core: Afișează un bloc CSS inline. E puțin mai bine decât să folosești atributul style și funcționează. Plugin-ul meu care are un shortcode doar afișează CSS-ul în head la fiecare încărcare. Nu e mult :)

mfields mfields
23 iun. 2011 19:42:13

@mfields, dacă fac asta, alți dezvoltatori de teme/plugin-uri nu vor putea înlocui fișierele cu cele proprii. Nu contează dacă miezul face acest lucru, rămâne o practică proastă.

Ian Dunn Ian Dunn
23 iun. 2011 19:47:29

fă-l filtrabil și orice alt plugin sau temă poate face ce dorește cu el. Dacă configurează filtrul să returneze un șir gol - nu se va afișa nimic.

mfields mfields
23 iun. 2011 19:51:50

Nu ai menționat motive obiective împotriva acestei practici. Oricum nu contează; văd doar două opțiuni aici: Încarcă mereu CSS/scripturi (optimizate pentru dimensiune), sau stiluri inline condiționate

onetrickpony onetrickpony
23 iun. 2011 20:01:08

@mfields, e un punct bun, dar prefer abordarea cu enqueue_style.

Ian Dunn Ian Dunn
23 iun. 2011 21:09:49

@One Trick Pony, cred că greșești, dar m-am săturat să mai discut despre asta.

Ian Dunn Ian Dunn
23 iun. 2011 21:10:02
Arată celelalte 9 comentarii