Scripts / styles en file d'attente en présence d'un shortcode

47

Quel est le moyen idéal pour enregistrer / mettre en file d'attente des scripts et / ou des styles à utiliser dans des plugins?

J'ai récemment créé un plugin plugin simple pour ajouter l'avatar / gravatar de l'utilisateur avec un shortcode. J'ai différentes options de style pour afficher l'avatar (carré, rond, etc.) et j'ai décidé de mettre le css directement dans le shortcode lui-même.

Cependant, je réalise maintenant que ce n’est pas une bonne approche car elle répète le css chaque fois que le shortcode est utilisé sur une page. J'ai vu plusieurs autres approches sur ce site et le codex wp en a même deux exemples. Il est donc difficile de savoir quelle approche est la plus cohérente et la plus rapide.

Voici les méthodes que je connais actuellement:

Méthode 1: inclure directement dans le shortcode - C’est ce que je suis en train de faire dans le plugin, mais cela ne semble pas bien car cela répète du code.

class My_Shortcode {
function handle_shortcode( $atts, $content="" ) {
/* simply enqueue or print the scripts/styles in the shortcode itself */
?>
<style type="text/css">

</style>
<?php
    return "$content";
     }
}
add_shortcode( 'myshortcode', array( 'My_Shortcode', 'handle_shortcode' ) );

Méthode 2: utilisez class pour la mise en file d'attente conditionnelle des scripts ou des styles

class My_Shortcode {
    static $add_script;
    static function init() {
        add_shortcode('myshortcode', array(__CLASS__, 'handle_shortcode'));
        add_action('init', array(__CLASS__, 'register_script'));
        add_action('wp_footer', array(__CLASS__, 'print_script'));
    }
    static function handle_shortcode($atts) {
        self::$add_script = true;
        // shortcode handling here
    }
    static function register_script() {
        wp_register_script('my-script', plugins_url('my-script.js', __FILE__), array('jquery'), '1.0', true);
    }
    static function print_script() {
        if ( ! self::$add_script )
            return;
        wp_print_scripts('my-script');
    }
}
My_Shortcode::init();

Méthode 3: utilisation de get_shortcode_regex();

function your_prefix_detect_shortcode() {

    global $wp_query;   
    $posts = $wp_query->posts;
    $pattern = get_shortcode_regex();

    foreach ($posts as $post){
        if (   preg_match_all( '/'. $pattern .'/s', $post->post_content, $matches )
            && array_key_exists( 2, $matches )
            && in_array( 'myshortcode', $matches[2] ) )
        {
            // css/js 
            break;  
        }    
    }
}
add_action( 'wp', 'your_prefix_detect_shortcode' );

Méthode 4: utilisation de has_shortcode();

function custom_shortcode_scripts() {
    global $post;
    if( is_a( $post, 'WP_Post' ) && has_shortcode( $post->post_content, 'myshortcode') ) {
        wp_enqueue_script( 'my-script');
    }
}
add_action( 'wp_enqueue_scripts', 'custom_shortcode_scripts');
    
posée Bryan Willis 18.10.2014 - 09:07
la source

6 réponses

34

J'ai trouvé un autre moyen qui fonctionne bien pour moi:

Voici un exemple de plug-in utilisant cette méthode qui vous permet d'utiliser get_avatar en tant que shortcode. La feuille de style n'est mise en file d'attente que lorsque le shortcode est présent.

Utilisation (id par défaut pour l'utilisateur actuel):

[get_avatar id="" size="32" default="mystery" alt="Profile Photo" class="round"]

function wpse_165754_avatar_shortcode_wp_enqueue_scripts() {
    wp_register_style( 'get-avatar-style', plugins_url( '/css/style.css', __FILE__ ), array(), '1.0.0', 'all' );
}

add_action( 'wp_enqueue_scripts', 'wpse_165754_avatar_shortcode_wp_enqueue_scripts' );
if ( function_exists( 'get_avatar' ) ) {
    function wpse_165754_user_avatar_shortcode( $attributes ) {

        global $current_user;
        get_currentuserinfo();

        extract( shortcode_atts(
                     array(
                         "id"      => $current_user->ID,
                         "size"    => 32,
                         "default" => 'mystery',
                         "alt"     => '',
                         "class"   => '',
                     ), $attributes, 'get_avatar' ) );

        $get_avatar = get_avatar( $id, $size, $default, $alt );

        wp_enqueue_style( 'get-avatar-style' );

        return '<span class="get_avatar ' . $class . '">' . $get_avatar . '</span>';
    }

    add_shortcode( 'get_avatar', wpse_165754_user_avatar_shortcode' );
}
    
réponse donnée jblanche 15.06.2015 - 14:28
la source
25

Avant de commencer à répondre, je dois dire que css et js ne sont pas identiques à ce sujet.

La raison est simple: bien que l'ajout de js au corps de la page (en pied de page) soit une solution courante et valable, css doit être placé dans la section <head> de la page: même si la majorité des navigateurs peut rendre correctement css dans le corps de la page, ce n'est pas un code HTML valide.

Quand un shortcode est rendu, la section <head> a déjà été imprimée, cela signifie que js peut être ajouté sans aucun problème sur le pied de page, mais vous devez ajouter css avant avant que le shortcode soit rendu.

Scripts

Si votre shortcode n'a besoin que de js, vous avez de la chance et pouvez simplement utiliser wp_enqueue_script dans le corps du rappel de shortcode:

add_shortcode( 'myshortcode', 'my_handle_shortcode' );

function my_handle_shortcode() {
  wp_enqueue_script( 'myshortcodejs', '/path/to/js/file.js' );
  // rest of code here...
}

Votre script est ajouté au pied de page une seule fois, même si le shortcode est utilisé plusieurs fois dans la page.

Styles

Si votre code a besoin de styles, vous devez agir avant que le shortcode ne soit réellement restitué.

Il existe différentes manières de procéder:

  1. examinez tous les articles de la requête en cours et ajoutez les styles de shortcode si nécessaire. C’est ce que vous faites dans les méthodes n ° 3 et n ° 4 dans OP. En fait, les deux méthodes font la même chose, mais has_shortcode a été ajouté dans WP 3.6, alors que get_shortcode_regex est disponible depuis la version 2.5, utilisez donc get_shortcode_regex uniquement si vous souhaitez rendre votre plugin compatible avec les versions antérieures.

  2. ajoute toujours le style shortcode dans toutes les pages

Problèmes

Le problème avec # 1 est la performance. Les regex sont des opérations assez lentes et le lancement de regex dans une boucle de toutes les publications peut ralentir la page de manière cohérente. De plus, il est assez commun dans les thèmes de ne montrer que les extraits de messages dans les archives et d'afficher le contenu complet avec des codes abrégés uniquement dans des vues uniques. Si cela se produit, lorsqu’une archive est affichée, votre plugin lancera une correspondance regex dans une boucle dans le but d’ajouter un style qui ne sera jamais utilisé: un double impact inutile sur les performances: ralentir la génération de la page + demande HTTP inutile supplémentaire

Le problème avec # 2 est la performance, encore. Ajouter du style à toutes les pages signifie ajouter une requête HTTP supplémentaire pour toutes les pages, même si elles ne sont pas nécessaires. Même si le temps de génération de page côté serveur n’est pas affecté, le temps de rendu de page total sera appliqué à toutes les pages de site.

Alors, que doit faire un développeur de plugin?

Je pense que la meilleure chose à faire est d’ajouter une page d’options au plugin, dans laquelle les utilisateurs peuvent choisir si le shortcode doit être traité en mode singulier ou même dans les archives. Dans les deux cas, il est préférable de fournir une autre option permettant de choisir les types de publication pour lesquels le code abrégé est activé.

De cette manière, il est possible d’accrocher "template_redirect" pour vérifier si la requête actuelle satisfait aux exigences et, dans ce cas, ajouter le style.

Si l’utilisateur choisit d’utiliser le shortcode uniquement dans les affichages uniques, c’est une bonne idée de vérifier si post a shortcode ou non: une fois qu’un seul regex est requis, cela ne devrait pas ralentir autant la page.

Si l’utilisateur choisit d’utiliser le shortcode même dans les archives, j’éviterai d’exécuter regex pour toutes les publications si le nombre de publications est élevé et mets simplement en file d'attente le style si les exigences de la requête sont correctes.

Ce qu'il faut considérer comme "élevé" à cet égard devrait être obtenu en utilisant des tests de performance ou, au lieu de cela, en ajoutant une autre option et en donnant le choix aux utilisateurs.

    
réponse donnée gmazzap 18.10.2014 - 10:49
la source
5

En ce qui concerne mon plug-in, j'ai constaté que les utilisateurs avaient parfois un générateur de thème dont le shortcode était stocké dans publier des métadonnées . Voici ce que j'utilise pour détecter si mon shortcode de plug-in est présent dans les publications en cours ou les métadonnées en cours :

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

       // determine whether this page contains "my_shortcode" 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' );
    
réponse donnée zdenekca 06.11.2015 - 01:18
la source
2

Je le fais:

class My_Shortcode {

    function __construct() {
        do_action('my_start_shortcode'); // call
....

et accrochez les autres fonctions (ou autres plugins):

function wpse_3232_load_script(){
    wp_enqueue_script('js-myjs');
}
add_action('my_start_shortcode','wpse_3232_load_script',10);
    
réponse donnée Wladimir Druzhaev 08.08.2017 - 11:51
la source
1

J'ai découvert pour mon propre plugin, si le shortcode est présent dans le widget texte.

function check_shortcode($text) {

  $pattern = get_shortcode_regex();

   if (   preg_match_all( '/'. $pattern .'/s', $text, $matches )
        && array_key_exists( 2, $matches )
        && in_array( 'myshortcode', $matches[2] ) )
    {
        // myshortcode is being used

        // enque my css and js
        /****** Enqueu RFNB  ******/
        wp_enqueue_style('css-mycss');
        wp_enqueue_script('js-myjs');

        // OPTIONAL ALLOW SHORTCODE TO WORK IN TEXT WIDGET
        add_filter( 'widget_text', 'shortcode_unautop');
        add_filter( 'widget_text', 'do_shortcode'); 

    }

  return $text;

}
add_filter('widget_text', 'check_shortcode');
    
réponse donnée Gino 21.12.2016 - 17:33
la source
0

WordPress possède une fonction intégrée permettant de faire quelque chose en fonction d'un statut de présentation de Shortcode spécifique. Le nom de la fonction est has_shortcode() . Vous pouvez utiliser le code suivant pour mettre en file d'attente votre style et vos scripts.

<?php
if( is_a( $post, 'WP_Post' ) && has_shortcode( $post->post_content, 'shortcode_tag') ) {
    wp_enqueue_style( 'handle', get_template_directory_uri() . '/your_file_filename.css' );
}

Ici, j'ai utilisé is_a( $post, 'WP_Post' ) pour vérifier si l'objet $post est de la classe WP_Post et j'ai utilisé $post->post_content pour vérifier le contenu de l'article.

Vous pouvez en apprendre plus à partir de ici sur la fonction has_shortcode ().

    
réponse donnée Arif Rahman 07.10.2018 - 19:04
la source