Une image à la une

Une demande récurrente concerne la possibilité de préciser une image à la une pour un billet dans Dotclear. Ça permettrait de simplifier le développement de certains thèmes. En attendant que ce soit intégré ou plutôt développé via un plugin tiers qui pourrait s’appuyer sur les métas et en fournissant une ou plusieurs balises template pour son intégration dans un thème, j’ai choisi pour mon thème Hermine (qui sera prochainement visible sur Open-Eyes, a priori dans la journée) une autre voie.


Je vous propose de vous expliquer ici comment utiliser la première image locale de vos billets comme image à la une et faire en sorte que celle-ci ne soit ensuite pas répétée dans le corps du billet.

Mon cahier des charges pour le thème, et plus spécialement le contexte du billet seul était le suivant :

  1. Si une image locale existe dans le billet, utiliser celle-ci (ou la première d’entre elles) comme image à la une et l’afficher en grand au dessus du titre, donc en dehors du contenu du billet. Dans ce cas, l’image utilisée ne doit pas être répétée dans le contenu du billet.
  2. Dans le cas contraire, si le billet dépend d’une catégorie et si une image locale est présente dans la description d’icelle, l’utiliser comme image à la une.

Trouver une image locale dans le billet ou la catégorie

Pour afficher la première image locale d’un billet il suffit d’utiliser la balise template {{tpl:EntryFirstImage}}, ce que je fais avec ce code :

<!-- Display first image of entry -->
<figure>
	{{tpl:EntryFirstImage size="o" class="media-title"}}
</figure>

Vous remarquerez que je ne demande pas de recherche dans la description de la catégorie si une image n’est pas trouvée dans le corps du billet, parce que sinon je ne pourrais différencier l’origine de l’image trouvée. Par contre, cela m’oblige à développer une autre balise template qui va déterminer si une image a été trouvée ou pas. Le code de cette nouvelle balise est placée dans le fichier _public.php du thème :

# Templates
$core->tpl->addBlock('IfEntryFirstImage',array('tplHermineTheme','IfEntryFirstImage'));

class tplHermineTheme
{
	public static function IfEntryFirstImage($attr,$content)
	{
		$size = !empty($attr['size']) ? $attr['size'] : '';
		$class = !empty($attr['class']) ? $attr['class'] : '';
		$with_category = !empty($attr['with_category']) ? 1 : 0;
		$no_tag = !empty($attr['no_tag']) ? 1 : 0;
		$content_only = !empty($attr['content_only']) ? 1 : 0;
		$cat_only = !empty($attr['cat_only']) ? 1 : 0;

		return
			"<?php if (context::EntryFirstImageHelper('".addslashes($size)."',".$with_category.",'".addslashes($class)."',".
			$no_tag.",".$content_only.",".$cat_only.") != '') : ?>".
			$content.
			"<?php endif; ?>";
	}
}

Cette balise reprend exactement les mêmes attributs que la balise {{tpl:EntryFirstImage}} afin de tester son résultat dans les mêmes conditions.

Du coup je peux maintenant tester et utiliser la bailse {{tpl:EntryFirstImage}} en fonction du résultat que je souhaite :

<tpl:IfEntryFirstImage size="o">
	<!-- Display first image of entry -->
	<figure>
		{{tpl:EntryFirstImage size="o" class="media-title"}}
	</figure>
{{tpl:else}}
	<figure>
		{{tpl:EntryFirstImage size="o" with_category="1" cat_only="1" class="media-cat-title"}}
	</figure>
</tpl:IfEntryFirstImage>

Le premier test permet de déterminer si une image locale existe dans le billet et dans ce cas elle sera affichée avec la classe media-title, sinon on utilisera, si elle existe, la première image trouvée dans la description de la catégorie, image affublée d’une classe media-cat-title.

Voilà comment positionner une classe différente en fonction de l’origine de l’image trouvée.

Masquer la première image locale du billet

Ensuite il suffit d’un peu de javascript pour masquer la première image locale du billet affiché. Je place le code suivant dans le fichier user_footer.html de mon thème :

<script type="text/javascript">
	$(document).ready(function(){

		// 1. Add specific .local-media class to paragraph with media inside
		$(".post-content p a img, .post-content figure a img, .post-excerpt p a img, .post-excerpt figure a img").each(function(){
			// Scheme = (p/figure) a (for full-size media) img (for thumbnail-size media)
			var src = $(this).attr("src");
			var cls = "local-media";
			if (src.indexOf("http://") !== 0 && (src.indexOf("https://") !== 0)) {
				// Add class to media container (p or figure)
				$(this).parent().parent().addClass(cls);
			}
		});

		// 2. Add specific style if first local media is used in post header
		if($(".media-title")) {
			$(".post-content .local-media:first-child, .post-excerpt .local-media:first-child").css("display","none");
		}
	});
</script>

La partie 1 du code[1] permet de positionner une classe local-media aux images locales. Il faudra surement adapter ce code si vous n’utilisez pas de lien sur les images pour les afficher en grand.

La partie 2 positionne un style spécifique (display: none;) à la première image locale du billet si celle-ci a été utilisée auparavant (d’où l’usage de la classe media-title). Du coup celle-ci ne sera pas affichée dans le corps du billet mais restera disponible le cas échéant pour les plugins de type lightbox, colorbox et consorts qui recherchent les images contenues dans les liens du billet.

Extension à l’affichage des catégories

J’ai utilisé la même technique pour l’affichage des catégories, en utilisant le cas échéant la première image locale contenue dans la description et en la masquant ensuite dans le corps de la description. Cela permet d’utiliser cette image en dehors du « flux » normal prévu par les jeux de templates de Dotclear.

Je ne détaille pas ici le détail du code en question, côté template et côté javascript pour ne pas surcharger cette explication. Elle sera visible sur le thème Hermine, une fois celui-ci visible publiquement.

Que ce passe-t-il quand javascript est désactivé ?

Dans ce cas là, la première image reste affichée en dehors du « flux », mais elle restera visible dans le corps du billet ou de la description de la catégorie, ce qui reste une dégradation acceptable pour l’utilisateur.

Note

[1] Le code provient du thème Hermine que j’ai légèrement expurgé pour illustrer mes propos et étant du coup surement optimisable.

Ajouter un commentaire

Les champs suivis d'un * sont obligatoires

Les commentaires peuvent être formatés en utilisant la syntaxe Markdown Extra.

Ajouter un rétrolien

URL de rétrolien : https://open-time.net/trackback/12429

Haut de page