Je vais ici vous présenter la méthode de génération des miniatures grâce à un script PHP qui s'appelle TimThumb. Je présenterai dans un autre article une seconde méthode qui n'utilise pas de PHP mais uniquement du CSS, encore un peu plus "bidouilleuse".

Installation et configuration du script PHP TimThumb

Commencez par enregistrer ce fichier ''timthumb.php'' et l'envoyer dans le dossier de votre thème.

Pour utiliser le script c'est très facile, il faut définir une image avec le fichier PHP et définir l'image d'origine en paramètre. C'est pas très clair ? Je m'explique, en code HTML cela donnerait :

<img src="timthumb.php?src=image.jpg&h=180&w=120&q=80" />

...où la valeur src renseigne l'image, h et w pour la taille et q pour la qualité (ici 80%).

Si vous souhaitiez simplement savoir comment générer des miniatures pour votre site avec un fichier PHP, vous pouvez vous arrêter de lire, c'était aussi simple que cela ! Pour les Dotcleariens qui souhaitent mettre cela en pratique sur leur blogue à l'aide du tpl:EntryFirstImage, il reste encore une petite modification à faire...

Extraire uniquement l'URL source de la première image

En effet, ce tpl générant le code complet de l'image (avec sa balise img) et non seulement sa source, il va falloir lui ajouter un petit paramètre qui corrigera cela, pour n'extraire que l'URL de la première image du billet. Pour cela, on peut remercier adjaya sur le forum Dotclear qui nous offre un morceau de code fort précieux pour nous venir en aide.

Toujours dans le dossier du thème, ouvrez le fichier _public.php (le créer si il n'existe pas) puis ajoutez simplement ces lignes de code à la suite :

# Surcharge EntryFirstImage
$GLOBALS['core']->tpl->addValue('EntryFirstImage',array('tplMytpl','MyEntryFirstImage'));
	
class tplMytpl
{
	/*dtd
	<!ELEMENT tpl:EntryFirstImage - O -- Extracts entry first image if exists -->
	<!ATTLIST tpl:EntryAuthorEmail
	size			(sq|t|s|m|o)	#IMPLIED	-- Image size to extract
	class		CDATA		#IMPLIED	-- Class to add on image tag
	with_category	(1|0)		#IMPLIED	-- Search in entry category description if present (default 0)
	with_post	(1|0)		#IMPLIED	-- Search in entry post content if present (default 1)
	src_only	(1|0)		#IMPLIED	--  return src only if present (default 0)
	>
	*/
	public static function MyEntryFirstImage($attr)
	{
		$size = !empty($attr['size']) ? $attr['size'] : '';
		$class = !empty($attr['class']) ? $attr['class'] : '';
		$with_category = !empty($attr['with_category']) ? 'true' : 'false';
		$with_post = 'true';
		if (isset($attr['with_post'])) {
			$with_post = !empty($attr['with_post']) ? 'true' : 'false';
		}
		$src_only = !empty($attr['src_only']) ? 'true' : 'false';

		return
		"<?php echo tplMytpl::EntryFirstImageHelper('".addslashes($size)."',".
		$with_category.",".$with_post.",".$src_only.",'".addslashes($class)."'); ?>";
	}
	
	# First post image helpers
	public static function EntryFirstImageHelper($size,$with_category=false,$with_post=true,$src_only=false,$class="")
	{
		if (!preg_match('/^sq|t|s|m|o$/',$size)) {
			$size = 's';
		}
		
		global $core, $_ctx;
		
		$p_url = $core->blog->settings->public_url;
		$p_site = preg_replace('#^(.+?//.+?)/(.*)$#','$1',$core->blog->url);
		$p_root = $core->blog->public_path;
		
		$pattern = '(?:'.preg_quote($p_site,'/').')?'.preg_quote($p_url,'/');
		$pattern = sprintf('/<img.+?src="%s(.*?\.(?:jpg|gif|png))"/msu',$pattern);
		
		$src = '';
		
		# We first look in post content
		if ($with_post && $_ctx->posts )
		{
			$subject = $_ctx->posts->post_excerpt_xhtml.$_ctx->posts->post_content_xhtml.$_ctx->posts->cat_desc;
			if (preg_match_all($pattern,$subject,$m) > 0)
			{
				foreach ($m[1] as $i) {
					if (($src = self::ContentFirstImageLookup($p_root,$i,$size)) !== false) {
						$src = $p_url.(dirname($i) != '/' ? dirname($i) : '').'/'.$src;
						break;
					}
				}
			}
		}
		
		# No src, look in category description if available
		if (!$src && $with_category && $_ctx->categories)
		{
			if (preg_match_all($pattern,$_ctx->categories->cat_desc,$m) > 0)
			{
				foreach ($m[1] as $i) {
					if (($src = self::ContentFirstImageLookup($p_root,$i,$size)) !== false) {
						$src = $p_url.(dirname($i) != '/' ? dirname($i) : '').'/'.$src;
						break;
					}
				}
			};
		}
		
		if ($src) {
			if ($src_only)
			{
				echo $src;
			}
			else
			{
				echo '<img alt="" src="'.$src.'" class="'.$class.'" />';
			}
		}
	}
	
	private static function ContentFirstImageLookup($root,$img,$size)
	{
		# Get base name and extension
		$info = path::info($img);
		$base = $info['base'];
		
		if (preg_match('/^\.(.+)_(sq|t|s|m)$/',$base,$m)) {
			$base = $m[1];
		}
		
		$res = false;
		if ($size != 'o' && file_exists($root.'/'.$info['dirname'].'/.'.$base.'_'.$size.'.jpg'))
		{
			$res = '.'.$base.'_'.$size.'.jpg';
		}
		else
		{
			$f = $root.'/'.$info['dirname'].'/'.$base;
			if (file_exists($f.'.'.$info['extension'])) {
				$res = $base.'.'.$info['extension'];
			} elseif (file_exists($f.'.jpg')) {
				$res = $base.'.jpg';
			} elseif (file_exists($f.'.png')) {
				$res = $base.'.png';
			} elseif (file_exists($f.'.gif')) {
				$res = $base.'.gif';
			}
		}
		
		if ($res) {
			return $res;
		}
		return false;
	}
}


Normalement, c'est tout bon ! Vous devriez pouvoir utiliser le script pour générer des miniatures pour vos listes de billets, très facilement. Voici un exemple, je veux afficher la première image d'un billet (à éditer dans le contexte post ou à l'intérieur d'une balise tpl:Entries des contextes home, category, tag). Je veux l'afficher avec une taille de 150x150 pixels, donc carrée et bien sûr sans aucune déformation ni aucun étirement. Je vais donc me baser sur le format small de ma première image, voici ce que ça donnerait dans mon fichier de template :

<img src="tpl:BlogThemeURL/timthumb.php?src=tpl:EntryFirstImage size="s" src_only="1"&h=150&w=150" />

Vous remarquerez qu'on utilise le fameux src_only grâce au gros bout de code que l'on vient d'installer. Magie, l'image s'affiche à la bonne taille, non déformée, non étirée ! N'hésitez pas à déposer des commentaires sur cet article si cela ne fonctionne pas chez vous, j'essaierai de vous aider.

Exemple d'utilisation

slideboxes-androidgamesfr.jpg Le header de mon site de jeux pour Android utilise cette méthode. Il présente six screenshots de jeux, qui sont les premières images de ces articles. Bien que le ratio de ces images soit pratiquement toujours identique, il arrive que des jeux soient en mode portrait tandis que la plupart sont en mode paysage, il a donc fallu utiliser cette technique pour harmoniser tout ça.

/!\ Avertissement technique /!\

Dernière précision importante, d'ordre technique : bien que le script génère un dossier cache dans votre theme pour récupérer rapidement les images redondantes, je vous conseille de ne pas trop abuser de cette méthode sur vos pages. Si vous l'utilisez sur des listes de billets avec des pages de 10 éléments ou plus, avec une qualité optimale (la valeur par défaut est de 90) votre hébergeur risque de ne pas aimer cela. Votre site sera ralenti et cela pourra causer d'autres problèmes de performances.

Bref, ne l'utilisez qu'avec parcimonie. Si vous souhaitez être plus "bourrin", ma deuxième technique de miniatures en CSS conviendra parfaitement, j'en parlerais dans un prochain article.