Tout savoir sur WordPress
Tutoriel WordPress

Insérer un tweet embarqué grâce à un shortcode

Découvrez pas à pas la méthode à suivre pour utiliser un shortcode permettant d’afficher un tweet embarqué sans utiliser le code proposé par Twitter.

Le but de ce tutoriel est d’utiliser un shortcode pour afficher un tweet embarqué au lieu de copier/coller le code que twitter nous propose. De plus, on trouve dans ce code un script qui serait chargé en milieu de page.

Voici un tweet officiel provenant du compte Twitter de Boite à Web : https://twitter.com/#!/BoiteAWeb/statuses/183105092990402560

Si on clique sur “Insérer ce tweet”, on obtient la fenêtre ci-dessous :

Une fois que vous avez collé ce code dans votre article/page, vous obtenez ceci :

Pffff que de manipulations ! Pire encore, si vous regardez de plus prêt vous y verrez une balise <script type=’text/javascript’> qui insére du code javascript. Ce qui signifie que si je souhaite insérer 10 tweets dans mon article, alors je vais insérer 10 fois ce script !? Ouch … je voulais en insérer une timeline complète moi !

Je vous propose de réduire tout ceci à l’utilisation d’un shortcode nommé [itweet]. Il affichera le tweet de la même façon que Twitter le ferait. Le shortcode gère aussi le cas où la page n’a pas le javascript activé – oui on fait les choses bien ici monsieur – et n’inclus le script de Twitter qu’une seule fois par article si et seulement si le shortcode est utilisé, oui, môsieur (môdame ?).

[pastacode lang=”php” message=”” highlight=”” provider=”manual”]

function insert_tweet( $atts, $content ) {
    extract(shortcode_atts(array(
        "id" => "",
        "lang" => "fr",
        "align" => ""
        ), $atts, 'itweet'));
    $id = preg_replace( '[0-9^]', '', $id );
    $content = preg_replace( '[0-9^]', '', $content );
    $id = $id=='' && $content!='' ? $content : $id;
    if( $id=='' ) return null;
    if( !$json = get_transient( 'itweet-' . $id ) )
        $response = wp_remote_get( 'http://api.twitter.com/1/statuses/show.json?id=' . $id );
    if( $json || ( $response['response']['code']==200 && $json = json_decode( $response['body'] ) ) ):
        set_transient( 'itweet-' . $id, $json, 60*60*24 ); // 24h
        $created_at_text = date_i18n( get_option( 'date_format' ). ' ' . get_option( 'time_format' ), strtotime( $json->created_at ) ) ;
        $tweet = '<blockquote class="twitter-tweet" lang="' . esc_attr( $lang ) . '" data-in-reply-to="' . esc_attr( $json->in_reply_to_status_id_str ) . '">' . "n" . ' ' . esc_html( $json->text ) . ' ' . "n" . ' — ' . esc_html( $json->user>name ) . ' (@' . esc_html( $json->user->screen_name ) . ') ' . '<a href="' . esc_url( 'https://twitter.com/' . $json->user->screen_name . '/status/' . $id ) . '" data-datetime="' . esc_attr( $json->created_at ) . '">' . esc_html( $created_at_text ) . '</a>' . '</blockquote&glt;' . "n";     
    endif;     
return $tweet; 
} 
add_shortcode( 'itweet', 'insert_tweet' );

[/pastacode]
[itweet]123456789123456789[/itweet] : sans paramètres, l’ID est dans le content.
ou
[itweet id=”123456789123456789″] : avec paramètres, l’ID est donc le paramètre id.

Le détail du code

Lignes 3-7 : Je commence par extraire les paramètres du shortcode avec extract(), vous n’êtes même pas obligés de les utiliser, même pas l’ID car je le gère aussi via le content.

Lignes 8-9 : Vient ensuite la réassignation après filtrage des possibles ID du tweet à afficher. Je ne garde que les chiffres grâce à un preg_replace(). Je ne cast pas en integer car ce chiffre est plus greand qu’un integer. Donc un (int)$id me renvoie 2147483647… logique.

Lignes 10-11 : Après ça j’affecte dans $id la valeur trouvée parmis le paramètre id ou le content, avec priorité au paramètre. Puis si $id vaut du vide, ce’st qu’il valait du texte non valide pour être un tweet, je return un null ce qui n’affiche rien et terminé.

Lignes 12-13 : Ha, voici une ligne interessante, je vais chercher si la donnée transitoire existe avec get_transient(), si elle existe alors je m’en sert, sinon la ligne 13 récupère les infos du tweet via l’API tweeter.

Lignes 14&22 : Je vérifie que j’ai ma donnée correcte dans $json ou que la réponse de l’API est bonne. J’affecte directement dans mon test IF  la valeur du body de la réponse avec un json_decode() car tweeter me renvoie des données sous forme de I.sachez que vous êtes limités à 150 appels par IP, donc si vous êtes sur un mutualisé (OVH, 1&1, etc), vous partagez ces 150 appels avec tous les sites sur le même serveur …

Ligne 15 : Si ma donnée est correcte je peux donc l’écrire en tant que transient avec set_transient() afin de m’en reservir plus tard et éviter de recharger une fois de plus ce tweet qui n’aura pas changé, cela m’économise un appel parmis mes 150. Imaginez, vous posez 5 tweets grâce au shortcode, 30 visites sur la pages auront raison de vos 150 appels, ça va vite ! C’est donc obligatoire de passer par une gestion de cache simple. Mais pourquoi limiter la donnée à 24heures (60*60*24) ? Car vos 150 appels se remettent à zéro 24h après et si personne ne visite la page contenant ces tweets, les données seront supprimées de votre base de données par WordPres lui même, pas besoin d’intervenir. Plutôt sympa non ?

Ligne 16 : Je récupère la date du tweet et en profite pour la localiser avec date_i18n() et les options du site. Aussi avec strtotime(), je ne me prends pas la tête à convertir la date de tweeter, merci strtotime() !

Lignes 17-21 : C’est le texte du tweet, il est ici assez complet car c’est cette version qui serait affiché si le navigateur ne supportait pas le javascript ou simplement si l’utilisateur navigue sur votre page sans javascript. J’utilise esc_url(), esc_attr() et esc_html() pour sanitizer les données.

Ligne 23 : Euh, le return, dans un shortcode, on ne fait pas de echo.

Ligne 25 : J’ajoute mon shortcode dans WordPress avec add_shortcode() et je le nomme itweet.

Euh ça ne marche pas … !

Vous avez ça ?

Oui je sais, il manque quelquechose : le script de twitter ! Le fameux widget.js dont je vous parle. Normalement je pourrais faire ça :

a) L’insérer dans le header quand je suis sur un post/page (avec is_singular()) pour que mes shortcodes soient fonctionnels.

b) L’insérer dans le shortcode en ajoutant en ligne 22 ceci :
[pastacode lang=”php” message=”” highlight=”” provider=”manual”]

$tweet .= '<script charset="utf-8" type="text/javascript" src="//platform.twitter.com/widgets.js"></script>';

[/pastacode]
Mais ces 2 solutions ont un inconvénient :

a) Si je n’utilise pas le shortcode, le javascript sera quand même chargé, dommage …

b) Si j’insère 100 shortcodes, le script sera inclus 100 fois, ouille !

Alors j’ai ma solution :

c) Charger le fichier widget.js que si j’utilise le shortcode dans mon post/page !

[pastacode lang=”php” message=”” highlight=”” provider=”manual”]

function enqueue_itweet_script()
{
    global $post;
    if( !$post ) return;
    $matches = array();
    $pattern = get_shortcode_regex();
    preg_match_all( '/' . $pattern . '/s', $post->post_content, $matches );
    foreach( $matches[2] as $value ) {
        if( $value == 'itweet' ) {
            wp_enqueue_script( 'itweet', 'http://platform.twitter.com/widgets.js', null, '1.0', true );
            break;
        }
    }
}
add_action( 'wp_print_scripts', 'enqueue_itweet_script' );

[/pastacode]
Maintenant ce script ne s’insère qu’une seule et unique fois par page contenant notre shortcode ! (De rien …)

PS : J’attends vos commentaires et avis avec impatience comme toujours !

Cet article a été mis à jour il y a 4366 jours - Il n'est peut être plus à jour !

Article écrit par Julio P.

Fondateur de SecuPress, l’extension de sécurité WordPress, Julio Potier est un Expert WordPress, un Formateur Expérimenté et un Consultant en Sécurité Web.

Il aime partager ses compétences et ses réflexions sur WordPress, donnant des conférences partout dans le monde.

11 Commentaires

  1. le plus c’est évidemment “oui on fait les choses bien ici monsieur”
    merci pour le code est le détail :)

  2. Yeah ! Bon boulot :)

    Twitter a bien fait son travail du côté du HTML originel, puisque sans JS le tweet reste lisible (faut le dire quand c’est bien fait).

    Sinon c’est plutôt :
    if( $value == ‘itweet’ )

    Si je ne m’abuse…
    Encore merci !

  3. Ouah ça c’est du tuto ! Bravo.
    J’ai eu juste un souci mais cela doit venir de chez moi, j’ai du remplacer & par & tout court pour que cela marche, souci d’encodage sûrement. M’enfin peut-être que d’autres auront ce même souci.

  4. Je n’arrive pas à l’insérer chez moi. Il me donne une erreur de synthaxe en disant qu’il y a un “=” au lieu d’un “(” attendu à partir de la ligne 4. N’étant as du tout un expert, quelqu’un peut me dire ce qui cloche et comment le réparer ?
    Merci

  5. Sympa cette astuce, mais il va falloir la mettre à jour avec le nouvel api.
    Mais en tout cas, merci, c’est une bonne base

  6. C’est cool tout ça ! Bien vu pour le script qui ne se charge qu’une fois et que si besoin.

    Mais (oui il y a un mais ) la version 1 de l’API Twiter n’est plus trop a utiliser
    https://dev.twitter.com/blog/api-v1-retirement-final-dates

    Il me semble aussi que tu aurais put utiliser la méthode “statuses/oembed” plutôt que “statuses/show”. Pour que le script ne soit pas charger automatiquement tu as un paramètre “omit_script”. Cela t’éviterais de reconstituer tout le HTML du Tweet.
    https://dev.twitter.com/docs/api/1/get/statuses/oembed

  7. Sympa cette astuce, mais il va falloir la mettre à jour avec le nouvel api.
    Mais en tout cas, merci, c’est une bonne base