Posts Embeds dans WordPress 4.4
ce qu’il faut savoir

WordPress 4.4 apporte son lot de nouveauté qui sont visibles dans ce changelog.

Parmi toutes les améliorations et modifications, une fonctionnalité a attiré mon attention :

La nouvelle fonctionnalité « Posts Embeds »

Il s’agit de pouvoir faire un bel encadré stylisé d’un article interne ou externe, si ce site utilise aussi les posts embed de WordPress 4.4.

baw_151110-103852[1]

Son utilisation est on ne peut plus simple : il suffit de coller l’URL de l’article ou de la page en question pour obtenir ce nouveau cadre.

Que du bon ?

Mais voilà, il y a des choses à savoir et ce n’est pas toujours rose, les voici :

  1. C’est activé par défaut et il faut un plugin pour désactiver tout ça,
  2. Tout le monde peut donc embed vos articles de blogs, pages et autres Custom Post Type sans demander votre avis,
  3. Si vous aviez collé des URLs (sans en faire des liens), elles deviendront des post embed toutes seules,
  4. Si vous souhaitez faire un lien vers une URL qui supporte le post embed, vous devrez le faire dans l’éditeur en mode « texte » et non plus « Visuel » car à peine collé le lien devient embed.
  5. Seul l’excerpt de ces contenus sera affiché, donc les ajouts manuels dans vos templates seront évidemment ignorés, ce qui signifie par exemple que les templates de page type « contact.php » se verront être embed avec le contenu du post_content qui est… vide ou contient quelque chose du genre « NE PAS EFFACER CECI EST LA PAGE DE CONTACT » (car sinon votre client risque de la supprimer, voyant un contenu vide en back-end etc.).
  6. Tous les liens d’un contenu en back-end sont passés à la moulinette et feront un appel HTTP afin de tenter de récupérer les informations embed, à chaque premier enregistrement d’un article.
  7. Les images à la une sont chargées depuis le site distant, ce qui implique un lag d’affichage et augmente le temps de chargement de votre site, que vous ayez un plugin de cache ou pas.
  8. Ces images peuvent changer du jour au lendemain et devenir des images à caractère disons… non désiré. eggplant
  9. Les contenus peuvent changer aussi, si vous mettez à jour (après 24h de création) un article contenant un post embed, WordPress relancera la moulinette pour aller lire de nouveau ce contenu qui a peut-être changé entre temps.
  10. Le résumé (excerpt) visible dans un embed peut être différent de celui visible sur le site, vous le saurez qu’une fois embed !
  11. Rien ne ne supprimera ni ne videra un article embed une fois mis en cache (au pire on a vu qu’il pouvait être refresh), ce qui fait que si vous activez le plugin pour supprimer le support des posts embed, vous devrez vider ce cache (qui concerne TOUS les embeds et pas juste les posts) sinon ils seront encore disponibles à l’embed.

Essayons de régler ces points :

  1. Le plugin pour désactiver ça est Disable Embed,
  2. Si vous ne voulez pas, il vous faudra alors juste ça :
    1. <?php
      /**
       * Plugin Name: Disable Embeds for others
       * Description: Don't want people can embed your posts?
       * Version:     1.0
       * Author:      Julio Potier
       * Author URI:  https://wp-rocket.me
       * License:     GPLv2+
       *
       */
      
      function disable_embeds_init() {
      
      	// Remove oEmbed discovery links.
      	remove_action( 'wp_head', 'wp_oembed_add_discovery_links' );
      
      	// Remove all embeds rewrite rules.
      	add_filter( 'rewrite_rules_array', 'disable_embeds_rewrites' );
      }
      
      add_action( 'init', 'disable_embeds_init', 9999 );
      
      /**
       * Remove all rewrite rules related to embeds.
       *
       * @since 1.2.0
       *
       * @param array $rules WordPress rewrite rules.
       * @return array Rewrite rules without embeds rules.
       */
      function disable_embeds_rewrites( $rules ) {
      	foreach ( $rules as $rule => $rewrite ) {
      		if ( false !== strpos( $rewrite, 'embed=true' ) ) {
      			unset( $rules[ $rule ] );
      		}
      	}
      
      	return $rules;
      }
      
      /**
       * Remove embeds rewrite rules on plugin activation.
       *
       * @since 1.2.0
       */
      function disable_embeds_remove_rewrite_rules() {
      	add_filter( 'rewrite_rules_array', 'disable_embeds_rewrites' );
      	flush_rewrite_rules();
      }
      
      register_activation_hook( __FILE__, 'disable_embeds_remove_rewrite_rules' );
      
      /**
       * Flush rewrite rules on plugin deactivation.
       *
       * @since 1.2.0
       */
      function disable_embeds_flush_rewrite_rules() {
      	remove_filter( 'rewrite_rules_array', 'disable_embeds_rewrites' );
      	flush_rewrite_rules();
      }
      
      register_deactivation_hook( __FILE__, 'disable_embeds_flush_rewrite_rules' );
      
      
  3. Vous pouvez alors désactiver le fait que toutes les urls externes (passées et futures) qui sont potentiellement des post embed soient ignorées, avec ce code :
    1. <?php
      /**
       * Plugin Name: Disable Embeds posts for me
       * Description: Don't want to fetch external emebed posts?
       * Version:     1.0
       * Author:      Julio Potier
       * Author URI:  https://wp-rocket.me
       * License:     GPLv2+
       *
       */
      
      add_filter( 'embed_oembed_html', 'hack_embed_oembed_html', 10, 2 );
      function hack_embed_oembed_html( $html, $url ) {
      	if ( ! class_exists( 'WP_oEmbed' ) ) {
      		include( ABSPATH . WPINC . '/class-oembed.php' );
      	}
      	$WP_oEmbed = new WP_oEmbed();
      	if ( ! $WP_oEmbed->get_provider( $url, array( 'discover' => false ) ) ) {
      		return '';
      	}
      	return $html;
      }
      
  4. Voir 3. Mais vous ne pourrez alors plus embed des articles. Ou alors vous ne collez pas l’url mais un mot, puis lors de la création de ce lien vous modifiez ce mot pour en faire une ancre.
  5. À vous de bien vérifier que les excerpts sont corrects, que les contenus le sont aussi. Sinon vous pouvez toujours utiliser le hook filtre the_excerpt_embed pour filtrer tout ça.
  6. Si vous ne voulez pas, voir 1. ou 3.
  7. 2 solutions, soit ajouter votre propre template posts embed (voir plus bas le hook template_include), soit juste ajouter ceci :
    1. <?php
      /**
       * Plugin Name: Disable Thumbnails Embeds
       * Description: Don't like the thumbnails embed?
       * Version:     1.0
       * Author:      Julio Potier
       * Author URI:  https://wp-rocket.me    
       * License:     GPLv2+
       *
       */
      
      add_filter( 'embed_thumbnail_image_shape', '__return_false' );
  8. Il faudrait mettre en cache local perpétuel ces images, je n’ai pas fait le code, je vous donne l’idée ;)
  9. Il faut passer le cache à 100 ans avec ce code :
    1. <?php
      /**
       * Plugin Name: Disable Embeds Cache
       * Description: Don't like the 1 day embed cache?
       * Version:     1.0
       * Author:      Julio Potier
       * Author URI:  https://wp-rocket.me    
       * License:     GPLv2+
       *
       */
       
       add_filter( 'oembed_ttl', 'one_hundred_years_embed_cache_ttl' );
       function one_hundred_years_embed_cache_ttl() {
      	return 100 * YEAR_IN_SECONDS;
       }
  10. Alors là, il n’y a qu’une fois l’article embed, que vous vous apercevrez du contenu qui sera affiché sur votre site, pas avant. Au mieux, manuellement vous pouvez visiter le lien de l’article en question et ajouter /embed à la fin de ce lien pour lire le futur contenu embed.
  11. Pour vider le cache des embed (tous !), vous pouvez le faire manuellement dans un gestionnaire de base de données (PhpMyAdmin like) et dans la table wp_postmeta, supprimez toutes les meta_key qui commencent par _oembed_ ou alors, juste une fois, utilisez ce code :
    1. <?php
      /**
       * Plugin Name: Empty Embeds cache
       * Description: You already read it
       * Version:     1.0
       * Author:      Julio Potier
       * Author URI:  https://wp-rocket.me    
       * License:     GPLv2+
       *
       */
       
       add_action( 'plugins_loaded', 'empty_embed_cache' );
       function empty_embed_cache() {
       	global $wpdb;
      	$wpdb->query( 'DELETE from ' . $wpdb->postmeta . ' WHERE meta_key LIKE "_oembed_%"' );
      	wp_die( 'Cache emptied, please now remove this file : <b>' . __FILE__ . '</b>' );
       }

Au point 7 je vous parlais de pouvoir modifier le template des posts embed. Ce template sera inclus dans le template hierarchy en 4.5. En attendant, vous devez utilisez les hooks pour modifier le contenu.

Le fichier de base se trouve dans /wp-includes/embed-template.php.

Grâce aux hooks, vous serez alors libres d’y ajouter, modifier ou retirer tout ce que vous voudrez. Défigurez-moi ça !

Ce template utilise 3 nouvelles fonctions qui sont :

  • print_embed_sharing_dialog() qui sert à afficher la boite de dialogue qui va contenir les boutons de partage,
  • print_embed_sharing_button() qui sert à afficher le bouton de partage,
  • print_embed_comments_button qui sert à afficher le bouton des commentaires ;

puis des hooks filtre :

  • oembed_discovery_links sert à modifier les balises <link> imprimées en entête, elles contiennent par défaut les URLs embed de l’article en cours,
  • post_embed_url donne accès à l’URL embed de l’article en cours,
  • oembed_endpoint_url vous donne le endpoint de l’API rest pour l’oembed post,
  • embed_html contient le rendu HTML du post embed,
  • oembed_response_data donne la réponse de la demande oembed d’une URL,
  • the_excerpt_embed permet d’avoir des excerpts différents des excerpts de votre site,
  • embed_thumbnail_image_size  attend de votre part la taille de l’image à la une de vos article embed, par défaut il contient le tableau des tailles de l’image à imprimer. Cette taille sert ensuite à savoir si c’est une image plutôt rectangulaire ou carrée afin de modifier l’affichage du embed…
  • embed_thumbnail_image_shape… et cet affichage se trouve dans ce filtre qui attend soit rectangular soit square ou encore false pour désactiver l’image, comme nous l’avions vu au-dessus.
  • embed_site_title_html contient le titre de votre site qui sera affiché dans le footer du embed,

et enfin des hooks action :

  • embed_head est celle qui se lance entre les balises HEAD de l’entête du embed,
  • embed_content se lance juste après l’affichage de votre excerpt,
  • embed_footer sera lancée dans le pied du embed, juste avant BODY.
  • enqueue_embed_scripts se déclenche lors de l’impression des scripts pour les iframe post embed,
  • embed_content_meta sera déclenché dans le footer entre le titre du site et le nombre de commentaires (s’il y en a). Vous pouvez par exemple ajouter la date de l’article en utilisant ce simple code :
add_action( 'embed_content_meta', 'the_date' );

baw_151110-113234[1]

Autre exemple plus avancé :

baw_151110-142715[1]

add_filter( 'embed_site_title_html', 'baw_embed_site_title' );
function baw_embed_site_title( $title ) {
	return '<a href="http://wpsolo.fr" target="_top"><img src="/wp-content/uploads/2011/07/iMovie-Logo.png" width="32" height="32" alt="" class="wp-embed-site-icon"><span>MyMovies</span></a>';
}

add_action( 'embed_content', 'baw_embed_content' );
function baw_embed_content() {
	echo '<i>Rating</i>: ' . str_repeat( '&bigstar;', 5 );
}

J’ai utilisé ici les hooks embed_content pour ajouter le rating (cela peut venir d’un custom field par exemple)embed_site_title_html pour y ajouter mon icône, et ajouter une image à la une dans mon article.

En jouant avec embed_thumbnail_image_shape et embed_thumbnail_image_size je peux déplacer mon image à la une, j’ai pour cela créé une taille d’image de 320 sur 320, croppée et ai ajouté le code suivant :

<?php
add_action( 'after_setup_theme', 'my_square_size' );
function my_square_size() {
	add_image_size( 'square', 320, 320, true );
}

add_filter( 'embed_thumbnail_image_size', '__return_square' );
add_filter( 'embed_thumbnail_image_shape', '__return_square' );
function __return_square() {
	return 'square';
}

Le petit avantage de nommer ma taille d’image square est de ne pas nécessiter à avoir une seconde callback pour les deux hooks, et puis je trouve que ça reste dans une bonne logique. Cela donne :

baw_151110-143737[1]

Notez que vous devrez régénérer les images à la une pour la nouvelle taille, pour cela je ne peux que vous conseiller le plugin Simple Image Sizes de Nicolas Juen.

Si vous souhaitez qu’un plugin puisse charger son propre fichier au lieu du thème, vous pouvez le faire avec le hook qui existe déjà, template_include, comme ceci :

// MY_PLUGIN_FOLDER est une constante imaginaire correspondant au dossier de votre plugin qui contient ce template
add_filter( 'template_include', 'my_plugin_embed_template_include' );
function my_plugin_embed_template_include( $template ) {
	if ( basename( $template ) == 'embed-template.php' ) {
		return MY_PLUGIN_FOLDER . '/embed-template.php';
	}
	return $template;
}

Là vous avez vraiment la main. Sachez juste que ce contenu sera inclus dans une iframe sécurisée, c’est-à-dire en mode sandbox.

Un commentaire ?

Oui tiens, parlons des commentaires. Par défaut ils n’acceptent pas le contenu embed :

baw_151110-113547[1]

 

Mais bien sûr il est possible d’ajouter le support grâce à ce code :

add_filter( 'get_comment_text', 'add_post_oembed_comment_support', 0 );
function add_post_oembed_comment_support( $comment_text ) {
	global $wp_embed;
	if ( $wp_embed ) {
		return $wp_embed->autoembed( $comment_text );
	}
	return $comment_text;
}

Sauf que ce code donne accès à tous les embeds, et la liste de ces providers est longue et s’allonge presque à chaque version.

baw_151110-144149[1]

 

Si vous souhaitez n’ajouter que le support des post embed aux commentaires, utilisez plutôt le code suivant :

add_filter( 'get_comment_text', 'add_post_oembed_comment_support', 0 );
function add_post_oembed_comment_support( $comment_text ) {
	global $wp_embed;
	if ( ! class_exists( 'WP_oEmbed' ) ) {
		include( ABSPATH . WPINC . '/class-oembed.php' );
	}
	$WP_oEmbed = new WP_oEmbed();
	if ( $WP_oEmbed->get_provider( $comment_text, array( 'discover' => false ) ) ) {
		return $comment_text;
	}
	if ( $wp_embed ) {
		return $GLOBALS['wp_embed']->autoembed( $comment_text );
	}
	return $comment_text;
}

baw_151110-144241[1]

 

Provider ?

Un provider – ou fournisseur en français – vous fournit son API embed afin que vous puissiez insérez ses contenus dans les vôtres.

Avec le code précédent nous avons restreint les providers afin de ne traiter que ceux qui ne sont pas connus de WordPress, ce qui signifie que nous avons entré une url externe ou interne.

Cela veux aussi dire qu’il est tout à fait possible d’ajouter des providers grâce au hook oembed_providers disponible depuis la 2.9.

Petit exemple pour ajouter CodePen.io à la liste, ensuite il me suffit de coller l’url d’un codepen dans mon article pour en profiter, j’ai utilisé ce plugin sur ce blog (oui il faut bien 3 personnes pour créer ce plugin /troll) :

<?php
/*
Plugin Name: CodePen oEmbed
Description: Adds oEmbed support for CodePen.io
Version: 1.0
Author: Pippin Williamson and Andrew Norcross
Author URI: http://pippinsplugins.com
Contributors: mordauk, norcross
*/

wp_oembed_add_provider( 'http://codepen.io/*/pen/*', 'http://codepen.io/api/oembed' );

Démo (by CreativJuiz) :

Voilà vous avez fait le tour de cette fonctionnalité et un peu plus, allez-vous l'utiliser maintenant ?

ps : Je tiens à remercier Pascal Birchler qui a développé cette fonctionnalité ainsi que le plugin qui la désactive (avec ma contribution).

pps : L'ajout de ce template dans le template hierarchy de WordPress a failli se faire, j'y ai contribué, mais faute de temps de tests, c'est reporté en "Future Release", donc potentiellement 4.5.

ppps : j'aime Interstellar :)

Et vous, utiliserez-vous cette fonctionnalité ?

Lire la suite

Vous aimez ? Partagez !

6 commentaires

  1. twainisalive · décembre 9, 2015
    Très bon article ! Merci beaucoup. Je ne dirais pas non à un article détaillant des exemples d’utilisation des hooks action.

    Je pense que de nombreuses personnes – moi, le premier – vont chercher à personnaliser l’icône du site ou à ajouter des custom field dans le contenu de l’embed.

  2. Laetitia · décembre 9, 2015
    Bonjour Julio.
    J’utilise sur mon blog personnel des post embed d’un site qui a toute ma confiance. Comment faire, sur mon blog, pour supprimer les embed de tous les sites sauf celui-ci justement ? Merci :)
    • Laetitia · décembre 9, 2015
      Bon faute de réponse, j’ai mis un if pour sortir la boucle de l’interdiction d’embed mais, si vous avez une idée qui soit plus généraliste et mieux (autoriser un nom de domaine), je suis preneuse.
  3. C_Lucien · décembre 9, 2015
    Bonjour,

    merci, même sans grande connaissance technique, j’ai compris comment cela fonctionne.

  4. Li-An · décembre 9, 2015
    Juste pour dire que Firefox n’aime pas du tout mais pas du tout Boiteaweb…