Cum să încarci scripturi doar dacă un anumit shortcode sau widget este prezent

28 sept. 2010, 08:21:48
Vizualizări: 16.1K
Voturi: 17

Am avut nevoie de o metodă pentru a filtra conținutul unei pagini/articole înainte de încărcare, pentru a putea adăuga scripturi în header dacă un anumit shortcode era prezent. După multă căutare, am dat peste această soluție pe http://wpengineer.com

function has_my_shortcode($posts) {
    if ( empty($posts) )
        return $posts;

    $found = false;

    foreach ($posts as $post) {
        if ( stripos($post->post_content, '[my_shortcode') )
            $found = true;
            break;
        }

    if ($found){
        $urljs = get_bloginfo( 'template_directory' ).IMP_JS;

    wp_register_script('my_script', $urljs.'myscript.js' );

    wp_print_scripts('my_script');
}
    return $posts;
}
add_action('the_posts', 'has_my_shortcode');

care este absolut genială și a făcut exact ce aveam nevoie.

Acum trebuie să extind funcționalitatea pentru a face același lucru și pentru bara laterală. Poate fi prin detectarea unui anumit tip de widget, shortcode, fragment de cod sau orice altceva care ar putea identifica momentul în care scriptul trebuie încărcat.

Problema este că nu pot să găsesc cum să accesez conținutul barelor laterale înainte ca acestea să fie încărcate (tema în cauză are mai multe bare laterale).

2
Comentarii

Sunt scripturile din header o cerință absolută pentru situația ta? Scripturile plasate la sfârșitul paginii sunt mai ușor de gestionat condiționat și sunt o practică recomandată pentru performanță.

Rarst Rarst
28 sept. 2010 08:36:31

Am încercat inițial în wp_footer, ceea ce elimină frumos necesitatea de a pre-filtra conținutul, dar deși scripturile s-au încărcat corect, nu au funcționat. Aceste scripturi trebuie să fie în wp_head pentru a face ceea ce trebuie.

Lemon Bacon Lemon Bacon
28 sept. 2010 09:12:31
Toate răspunsurile la întrebare 4
9
20

Puteți utiliza funcția is_active_widget. De exemplu:

function check_widget() {
    if( is_active_widget( '', '', 'search' ) ) { // verifică dacă widget-ul de căutare este utilizat
        wp_enqueue_script('my-script');
    }
}

add_action( 'init', 'check_widget' );

Pentru a încărca scriptul doar în pagina unde este încărcat widget-ul, va trebui să adăugați codul is_active_widget() în clasa widget-ului dumneavoastră. De exemplu, vedeți widget-ul implicit pentru comentarii recente (wp-includes/default-widgets.php, linia 602):

class WP_Widget_Recent_Comments extends WP_Widget {

    function WP_Widget_Recent_Comments() {
        $widget_ops = array('classname' => 'widget_recent_comments', 'description' => __( 'Cele mai recente comentarii' ) );
        $this->WP_Widget('recent-comments', __('Comentarii Recente'), $widget_ops);
        $this->alt_option_name = 'widget_recent_comments';

        if ( is_active_widget(false, false, $this->id_base) )
            add_action( 'wp_head', array(&$this, 'recent_comments_style') );

        add_action( 'comment_post', array(&$this, 'flush_widget_cache') );
        add_action( 'transition_comment_status', array(&$this, 'flush_widget_cache') );
    }
28 sept. 2010 09:03:27
Comentarii

Poate fi apelat ÎNAINTE de încărcarea widget-urilor. Pentru a fi clar, acest lucru trebuie să aibă loc chiar înainte de încărcarea paginii. Codul meu exemplu folosește the_posts pentru a filtra conținutul de pe pagină, dar asta nu include sidebarele/widget-urile.

Lemon Bacon Lemon Bacon
28 sept. 2010 09:14:01

Da, vezi exemplul pe care l-am adăugat la răspunsul meu.

sorich87 sorich87
28 sept. 2010 09:24:42

Exemplul tău nu funcționează de fapt. Omiteam eu ceva evident?

Lemon Bacon Lemon Bacon
29 sept. 2010 04:10:18

De fapt, așa era. wp_enqueue_script nu pare să funcționeze atunci când este aplicat la wp_head, dar wp_print_scripts funcționează. Totuși, wp_enqueue_script funcționează dacă este aplicat la init astfel: add_action( 'init', 'check_widget' );

Lemon Bacon Lemon Bacon
29 sept. 2010 04:25:57

Cu toate acestea, încarcă scripturile pe fiecare pagină a site-ului, chiar dacă widget-ul este activ doar într-o singură bară laterală. De exemplu, dacă am o bară laterală pentru paginile de blog și o altă bară laterală pentru alte pagini. Adaug widget-ul de căutare în bara laterală a blogului și scripturile se încarcă, dar se încarcă și pe paginile care nu au bara laterală a blogului. Trebuie să pot încărca scriptul doar dacă widget-ul este prezent pe acea pagină.

Lemon Bacon Lemon Bacon
29 sept. 2010 04:49:34

Am editat răspunsul meu

sorich87 sorich87
29 sept. 2010 06:11:11

Ești tare! Noroc!

Lemon Bacon Lemon Bacon
29 sept. 2010 13:52:53

Soluție foarte frumoasă :)

Anh Tran Anh Tran
25 dec. 2011 06:51:48

Mai bine folosești wp_enqueue_scripts în loc de wp_head. răspuns excelent, mulțumesc.

wesamly wesamly
6 mar. 2017 07:38:35
Arată celelalte 4 comentarii
0

Am vrut să împărtășesc o soluție la care am lucrat, care mi-a oferit mai multă versatilitate în implementare. În loc să am o funcție care să verifice o varietate de shortcode-uri, am modificat-o să caute un singur shortcode care face referire la o funcție de script/stil care trebuie încărcată. Aceasta va funcționa atât pentru metode din alte clase (cum ar fi plugin-uri care nu fac asta în mod automat), cât și pentru funcții în scopul curent. Pur și simplu adăugați codul de mai jos în functions.php și folosiți următoarea sintaxă în orice pagină/post unde doriți CSS și JS specific.

Sintaxă pentru Pagină/Post: [loadCSSandJS function="(nume_clasă->metodă/nume_funcție)"]

Cod pentru functions.php:

function page_specific_CSSandJS( $posts ) {
  if ( empty( $posts ) )
    return $posts;

  foreach ($posts as $post) {

    $returnValue = preg_match_all('#\[loadCSSandJS function="([A-z\-\>]+)"\]#i', $post->post_content, $types);

    foreach($types[1] as $type) {
      $items = explode("->",$type);
      if (count($items) == 2) {
        global $$items[0];      
        if( method_exists( $$items[0], $items[1] ))
          add_action( 'wp_enqueue_scripts', array(&$$items[0], $items[1]) );
      }
      else if( !empty( $type ) && function_exists( $type ))
        add_action( 'wp_enqueue_scripts', $type );
    }
  }

  return $posts;
}

Această soluție vă permite, de asemenea, să adăugați câte funcții doriți pe o pagină. Rețineți că aveți nevoie de o metodă/funcție care să facă încărcarea.

25 sept. 2012 22:14:40
0

cu WordPress 4.7 există o altă modalitate de a realiza acest lucru în fișierul tău functions.php,

add_action( 'wp_enqueue_scripts', 'register_my_script');
function register_my_script(){
  wp_register_script('my-shortcode-js',$src, $dependency, $version, $inFooter);
}

mai întâi îți înregistrezi scriptul, care nu va fi afișat efectiv pe pagină decât dacă îl adaugi în coadă atunci când shortcode-ul tău este apelat,

add_filter( 'do_shortcode_tag','enqueue_my_script',10,3);
function enqueue_my_script($output, $tag, $attr){
  if('myShortcode' != $tag){ //verifică dacă este shortcode-ul corect
    return $output;
  }
  if(!isset($attr['id'])){ //poți verifica chiar și pentru atribute specifice
    return $output;
  }
  wp_enqueue_script('my-shortcode-js'); //adaugă scriptul în coadă pentru afișare
  return $output;
}

filtrul do_shortcode_tag a fost introdus în WP 4.7 și poate fi găsit în noile pagini de documentație pentru dezvoltatori.

31 ian. 2017 05:33:03
0

Mulțumesc pentru acest pont! Mi-a cauzat puțină migrenă, deoarece la început nu funcționa. Cred că sunt câteva greșeli (poate tipografice) în codul de mai sus has_my_shortcode și am rescris funcția astfel:

function has_my_shortcode( $posts ) {

        if ( empty($posts) )
            return $posts;

        $shortcode_found = false;

        foreach ($posts as $post) {

            if ( !( stripos($post->post_content, '[my-shortcode') === false ) ) {
                $shortcode_found = true;
                break;
            }
        }

        if ( $shortcode_found ) {
            $this->add_scripts();
            $this->add_styles();
        }
        return $posts;
    }

Cred că au fost două probleme principale: break nu se afla în sfera instrucțiunii if, iar acest lucru a făcut ca bucla să se întrerupă întotdeauna la prima iterație. Cealaltă problemă a fost mai subtilă și mai greu de descoperit. Codul de mai sus nu funcționează dacă shortcode-ul este chiar primul lucru scris într-un articol. A trebuit să folosesc operatorul === pentru a rezolva acest lucru.

Oricum, mulțumesc mult pentru împărtășirea acestei tehnici, a fost de mare ajutor.

22 dec. 2011 09:48:39