Chargement de scripts uniquement si un shortcode ou un widget particulier est présent

17

J'avais besoin d'un moyen de filtrer le contenu d'une page / messages avant qu'il ne soit chargé afin que je puisse ajouter des scripts à l'en-tête si un shortcode spécifique était présent. Après de nombreuses recherches, je suis tombé sur ceci sur 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');

ce qui est absolument génial et a fait exactement ce dont j'avais besoin.

Maintenant, je dois l'étendre un peu plus et faire de même pour les barres latérales. Il peut s'agir d'un type de widget particulier, d'un shortcode, d'un extrait de code ou de tout autre élément qui pourrait identifier le moment où le script doit être chargé.

Le problème est que je ne peux pas comprendre comment accéder au contenu des barres latérales avant que la barre latérale ne soit chargée (le thème en question aura plusieurs barres latérales)

Ashley G
la source
Les scripts dans l'en-tête sont-ils des exigences strictes pour votre situation? Les scripts à la fin de la page sont plus faciles à gérer sous condition et recommandent la performance
Rarst
Je l'ai d'abord essayé dans wp_footer, ce qui élimine bien le besoin de préfiltrer le contenu, mais bien que les scripts se soient bien chargés, ils n'ont pas fonctionné. Ces scripts doivent être dans wp_head pour faire ce dont ils ont besoin.
Ashley G

Réponses:

20

Vous pouvez utiliser la fonction is_active_widget . Par exemple:

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

add_action( 'init', 'check_widget' );

Pour charger le script dans la page où le widget est chargé uniquement, vous devrez ajouter le code is_active_widget (), dans votre classe de widget. Par exemple, consultez le widget de commentaires récents par défaut (wp-includes / default-widgets.php, ligne 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') );
    }
sorich87
la source
Peut-on appeler cela AVANT que les widgets ne soient chargés. Pour être clair, cela doit avoir lieu avant même que la page ne se charge. Mon exemple de code utilise the_posts pour filtrer le contenu de la page, mais cela n'obtient pas les barres latérales / widgets.
Ashley G
Oui, voir l'exemple que j'ai ajouté à ma réponse.
sorich87
Votre exemple ne fonctionne pas vraiment. Suis-je en train de manquer quelque chose d'évident?
Ashley G
En fait, je l'étais. wp_enqueue_script ne semble pas fonctionner lorsqu'il est appliqué à wp_head, mais wp_print_scripts le fait. wp_enqueue_script fonctionne bien si appliqué à init comme ceci: add_action ('init', 'check_widget');
Ashley G
Cependant, il charge les scripts sur chaque page du site, même si le widget n'est actif que dans une seule barre latérale. par exemple, si j'ai une barre latérale pour les pages de blog et une autre barre latérale pour les autres pages. J'ajoute le widget de recherche à la barre latérale du blog et les scripts se chargent, mais il se charge également sur les pages qui n'ont pas la barre latérale du blog. J'ai besoin de pouvoir charger le script uniquement si le widget est présent sur cette page.
Ashley G
3

Je voulais juste partager une solution sur laquelle j'ai travaillé qui m'a permis d'être un peu plus polyvalent avec mon implémentation. Plutôt que de faire vérifier la fonction pour une variété de shortcodes, je l'ai modifiée pour rechercher un shortcode unique qui référence une fonction de script / style qui doit être mise en file d'attente. Cela fonctionnera pour les deux méthodes dans d'autres classes (comme les plugins qui ne peuvent pas le faire eux-mêmes) et les fonctions dans la portée. Déposez simplement le code ci-dessous dans functions.php et ajoutez la syntaxe suivante à n'importe quelle page / publication où vous souhaitez CSS et JS spécifiques.

Page / Post Syntaxe: [loadCSSandJS function = "(classe-> méthode / nom de fonction)"]

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

Cela vous permettra également d'ajouter autant que vous le souhaitez sur une page. Gardez à l'esprit que vous avez besoin d'une méthode / fonction pour charger.

Nick Caporin
la source
1

Merci d'avoir partagé cette astuce! Cela m'a donné un petit mal de tête, car au début ça ne fonctionnait pas. Je pense qu'il y a quelques erreurs (peut-être des fautes de frappe) dans le code ci has_my_shortcode- dessus et j'ai réécrit la fonction comme ci-dessous:

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

Je pense qu'il y avait deux problèmes principaux: le breakn'était pas dans la portée de l'instruction if, et cela faisait que la boucle se cassait toujours à la première itération. L'autre problème était plus subtil et difficile à découvrir. Le code ci-dessus ne fonctionne pas si le shortcode est la toute première chose écrite dans un article. J'ai dû utiliser l' ===opérateur pour résoudre ce problème.

Quoi qu'il en soit, merci beaucoup d'avoir partagé cette technique, cela a beaucoup aidé.

jekbau
la source
1

avec Wordpress 4.7, il existe un autre moyen d'y parvenir dans votre functions.phpfichier,

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

vous enregistrez d'abord votre script , qui n'est pas réellement imprimé sur votre page, sauf si vous le mettez en file d'attente si votre shortcode est appelé,

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

le a do_shortcode_tagété introduit dans WP 4.7 et peut être trouvé dans les nouvelles pages de documentation des développeurs .

Aurovrata
la source