web-dev-qa-db-fra.com

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

J'avais besoin d'un moyen de filtrer un contenu de page/posts avant son chargement afin de pouvoir ajouter des scripts à l'en-tête si un shortcode spécifique était présent. Après de nombreuses recherches, je suis tombé 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');

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

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

Le problème est que je ne sais pas 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).

16
Ashley G

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 devez ajouter le code is_active_widget () dans votre classe de widget. Voir par exemple le widget 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') );
    }
19
sorich87

Je voulais juste partager une solution sur laquelle j'ai travaillé et 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 codes abrégés, je l’ai modifiée pour rechercher un code abrégé unique qui fait référence à une fonction de script/style devant être mise en file d'attente. Cela fonctionnera pour les deux méthodes dans d'autres classes (telles que les plugins qui ne peuvent pas le faire eux-mêmes) et les fonctions incluses dans la portée. Déposez simplement le code ci-dessous dans le fichier functions.php et ajoutez la syntaxe suivante à toute page/publication où vous souhaitez des CSS et JS spécifiques.

Syntaxe page/publication: [loadCSSandJS function = "(class-> méthode/nom de la 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’en ajouter autant que vous le souhaitez sur une page. Gardez à l'esprit que vous avez besoin d'une méthode/fonction à charger.

3
Nick Caporin

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

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

d’abord vous enregistrez 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 do_shortcode_tag était introduit dans WP 4.7 et se trouve dans le documentation pour les nouveaux développeurs pages.

1
Aurovrata

Merci de partager cette astuce! Cela m'a donné un peu mal à la tête, car au début cela ne fonctionnait pas. Je pense qu'il y a quelques erreurs (peut-être des fautes de frappe) dans le code ci-dessus has_my_shortcode 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: la break n'était pas dans la portée de l'instruction if et a causé la rupture de la boucle à 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 message. J'ai dû utiliser l'opérateur === pour résoudre ce problème.

En tout cas, merci beaucoup d'avoir partagé cette technique, cela a beaucoup aidé.

1
jekbau