Caricamento degli script solo se è presente un particolare shortcode o widget


17

Avevo bisogno di un modo per filtrare il contenuto di una pagina / post prima che fosse caricato in modo da poter aggiungere script all'intestazione se fosse presente uno shortcode specifico. Dopo molte ricerche mi sono imbattuto in questo su 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');

che è assolutamente geniale e ha fatto esattamente ciò di cui avevo bisogno.

Ora ho bisogno di estenderlo un po 'di più e fare lo stesso per le barre laterali. Può essere per un particolare tipo di widget, shortcode, snippet di codice o qualsiasi altra cosa che possa funzionare per identificare quando è necessario caricare lo script.

Il problema è che non riesco a capire come accedere al contenuto delle barre laterali prima che la barra laterale venga caricata (il tema in questione avrà diverse barre laterali)


Gli script nell'intestazione sono requisiti difficili per la tua situazione? Gli script alla fine della pagina sono più facili da gestire in modo condizionale e consigliato per le prestazioni.
Rarst,

L'ho provato prima in wp_footer, il che elimina la necessità di prefiltrare il contenuto, ma mentre gli script sono stati caricati correttamente, non hanno funzionato. Questi script devono essere in wp_head per fare ciò di cui hanno bisogno.
Ashley G,

Risposte:


20

È possibile utilizzare la funzione is_active_widget . Per esempio:

function check_widget() {
    if( is_active_widget( '', '', 'search' ) ) { // check if search widget is used
        wp_enqueue_script('my-script');
    }
}

add_action( 'init', 'check_widget' );

Per caricare lo script nella pagina in cui è caricato solo il widget, dovrai aggiungere il codice is_active_widget (), nella classe del widget. Ad esempio, vedere il widget dei commenti recenti predefiniti (wp-Includes / default-widgets.php, riga 602):

class WP_Widget_Recent_Comments extends WP_Widget {

    function WP_Widget_Recent_Comments() {
        $widget_ops = array('classname' => 'widget_recent_comments', 'description' => __( 'The most recent comments' ) );
        $this->WP_Widget('recent-comments', __('Recent Comments'), $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') );
    }

Può essere chiamato PRIMA che i widget vengano caricati. Per essere chiari, questo deve avvenire prima che la pagina venga caricata. Il mio codice di esempio usa the_posts per filtrare il contenuto della pagina, ma questo non ottiene le barre laterali / i widget.
Ashley G,

Sì, vedi l'esempio che ho aggiunto alla mia risposta.
sorich87,

Il tuo esempio in realtà non funziona. Mi sto perdendo qualcosa di ovvio?
Ashley G,

In realtà lo ero. wp_enqueue_script non sembra funzionare quando applicato a wp_head, ma wp_print_scripts lo fa. wp_enqueue_script funziona però se applicato a init in questo modo: add_action ('init', 'check_widget');
Ashley G,

Tuttavia carica gli script su ogni pagina del sito, anche se il widget è attivo solo in una barra laterale. ad esempio se ho una barra laterale per le pagine del blog e un'altra barra laterale per le altre pagine. Aggiungo il widget di ricerca alla barra laterale del blog e gli script vengono caricati, ma si carica anche sulle pagine che non dispongono della barra laterale del blog. Devo essere in grado di caricare lo script solo se il widget è presente su quella pagina.
Ashley G,

3

Volevo solo condividere una soluzione su cui ho lavorato che mi ha permesso di essere un po 'più versatile con la mia implementazione. Piuttosto che avere la funzione di controllo per una varietà di shortcode, l'ho modificato per cercare un singolo shortcode che fa riferimento a una funzione di script / stile che deve essere accodata. Questo funzionerà per entrambi i metodi in altre classi (come i plugin che potrebbero non farlo da soli) e le funzioni nell'ambito. Rilascia il codice seguente in Functions.php e aggiungi la sintassi seguente a qualsiasi pagina / post in cui desideri CSS e JS specifici.

Sintassi pagina / post: [loadCSSandJS function = "(class-> nome metodo / funzione)"]

codice funzioni.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;
}

Ciò ti consentirà anche di aggiungerne quanti ne vuoi su una pagina. Tieni presente che hai bisogno di un metodo / funzione per caricare.


1

Grazie per aver condiviso questo suggerimento! Mi dava un po 'di mal di testa, perché all'inizio non funzionava. Penso che ci siano un paio di errori (forse errori di battitura) nel codice sopra has_my_shortcodee ho riscritto la funzione come di seguito:

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

Penso che ci fossero due problemi principali: il breaknon rientrava nell'ambito dell'istruzione if e ciò causava l'interruzione del ciclo alla prima iterazione. L'altro problema era più sottile e difficile da scoprire. Il codice sopra non funziona se lo shortcode è la prima cosa scritta in un post. Ho dovuto usare l' ===operatore per risolvere questo.

Comunque, grazie mille per aver condiviso questa tecnica, mi ha aiutato molto.


1

con Wordpress 4.7 c'è un altro modo per raggiungere questo obiettivo nel tuo functions.phpfile,

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

per prima cosa registri la tua sceneggiatura , che in realtà non viene stampata sulla tua pagina a meno che non la accoda se viene chiamato il tuo shortcode,

add_filter( 'do_shortcode_tag','enqueue_my_script',10,3);
function enqueue_my_script($output, $tag, $attr){
  if('myShortcode' != $tag){ //make sure it is the right shortcode
    return $output;
  }
  if(!isset($attr['id'])){ //you can even check for specific attributes
    return $output;
  }
  wp_enqueue_script('my-shortcode-js'); //enqueue your script for printing
  return $output;
}

è do_shortcode_tagstato introdotto in WP 4.7 e può essere trovato nelle nuove pagine di documentazione per gli sviluppatori .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.