Contenu principal
Onglet media de WordPress, plusieurs tailles d'images

Davantage de tailles d’images dans l’administration de WordPress

D’origine, WordPress nous arrive avec 4 tailles d’images disponibles. Grâce à la fonction add_image_size( ), WordPress nous permet même d’en ajouter dans nos thèmes. Pour autant, ces nouvelles tailles ne sont pas disponibles depuis l’administration. Sauf si…

[update] L’article a été mis à jour pour WordPress 3.3

Voilà une chose qui m’a semblé étrange la première fois que j’ai eu besoin de rajouter des tailles d’images nécessaires au développement d’un plugin : la fonction add_image_size( ) permet effectivement ceci mais… C’est tout? Pas de trace dans l’administration? Rien dans la base de données? Et bien non.
Ensuite je me suis dit : « A la fois, est-ce qu’on a besoin de 10 tailles d’images pour mettre dans nos articles? ». Je serais tenté de dire non, sauf cas exceptionnel, donc pourquoi pas réserver ces tailles supplémentaires au développement de thèmes et plugins. Cependant, je suis quand même surpris que WordPress ne permette pas simplement une telle chose, grâce à une fonction ou un hook.

Allez, je suis quand même sympa, je vais vous montrer un moyen de le faire ;)

Première chose, la création

La création des nouvelles tailles se fait avec la fonction dont nous avons parlé, add_image_size( ). Grâce à ceci, lorsque vous uploadez une image depuis l’administration de WordPress, en plus des tailles thumbnail, medium et large (et l’image originale), de nouvelles seront crées. Ajoutons donc 3 nouvelles tailles dans le fichier functions.php de votre thème :

123

add_image_size( 'top-slideshow',  760, 248, true );
add_image_size( 'half-slideshow', 288, 496, true );
add_image_size( 'full-slideshow', 760, 496, true );

Pour rappel (ou pas) :
add_image_size( $name, $width, $height, $crop );
$name : le nom donné à la taille d’image.
$width : largeur en pixels.
$height : hauteur en pixels.
$crop : ce que l’on appelle le « hard crop », c’est à dire que l’image sera retaillée pour coller aux dimensions.

Enregistrement en base de donnée

La deuxième étape consiste à enregistrer les nouvelles dimensions dans la base de donnée. Rassurez-vous, c’est très simple.
Je me suis rendu compte que les largeur et hauteur de nos images d’origine sont enregistrées en tant qu’option (logique après tout, puisque ce sont des options réglables dans l’administration) sous le nom de ‘medium_size_w’ pour la largeur des images medium par exemple. Faisons donc de même.

Méthode 1 : simple, et efficace

A mettre encore dans functions.php :

123456

add_option('top-slideshow_size_w',  760);
add_option('top-slideshow_size_h',  248);
add_option('half-slideshow_size_w', 288);
add_option('half-slideshow_size_h', 496);
add_option('full-slideshow_size_w', 760);
add_option('full-slideshow_size_h', 496);

Ensuite? Enregistrer le fichier, aller faire un tour sur votre site, supprimer ces lignes.
Pourquoi? Au chargement d’une page les options sont inscrites dans la base de données, ensuite nous n’avons plus besoin de les changer ou de les mettre à jour, donc autant supprimer tous ces add_option( ) qui ne feront que ralentir le site inutilement.

Méthode 2 : un peu feignasse

Vous avez envie de garder ces lignes? Bon, réduisons leur impact en les limitant à l’administration et en ne les lançant que si nos valeurs ne sont pas encore crées :

12345678

if ( is_admin() ) {
if (!get_option('top-slideshow_size_w'))	add_option('top-slideshow_size_w',  760);
if (!get_option('top-slideshow_size_h'))	add_option('top-slideshow_size_h',  248);
if (!get_option('half-slideshow_size_w'))	add_option('half-slideshow_size_w', 288);
if (!get_option('half-slideshow_size_h'))	add_option('half-slideshow_size_h', 496);
if (!get_option('full-slideshow_size_w'))	add_option('full-slideshow_size_w', 760);
if (!get_option('full-slideshow_size_h'))	add_option('full-slideshow_size_h', 496);
}

Hey! J’ai toujours rien!

Hé ho, ça va, j’ai dit que ce serait facile? Bon, en l’occurrence, ce n’est pas bien compliqué mais un peu fastidieux (et encore, je vous donne tout sur un plateau, vous plaignez pas ^^).
Le « problème » maintenant c’est que même si on a ajouté les dimensions dans la base de données, WordPress ne va pas les lister pour autant dans l’administration, car les tailles d’images sont « hardcodées » : au lieu de faire un appel vers la base de données pour retrouver ces tailles, WordPress utilise une variable array construite localement. Avec un peu de recherche j’ai réussi à localiser la fonction en question. Heureusement, je suis tombé sur un seul fichier (ça facilite la chose), malheureusement, cette fonction ne dispose pas de hook (un apply_filters au niveau de l’array en question aurait grandement facilité la manœuvre).
Heureusement (encore), cette fonction est appelée par une autre fonction disposant d’un hook. o/
La méthode consistera donc à :
– copier la première fonction et la renommer,
– modifier la variable qui nous concerne en rajoutant nos nouvelles tailles d’images,
– copier la deuxième fonction et la renommer,
– la faire appeler notre première fonction,
– hooker notre deuxième fonction.

Toujours dans functions.php, une fois les fonctions renommées et les nouvelles tailles ajoutées (repérez la ligne 5) :

010203040506070809101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475

if ( is_admin() ) {
function sf_image_size_input_fields( $post, $check = '' ) {

		// get a list of the actual pixel dimensions of each possible intermediate version of this image
		$size_names = array('thumbnail' => __('Thumbnail'), 'medium' => __('Medium'), 'large' => __('Large'), 'full' => __('Full Size'), 'top-slideshow' => __('Top Slideshow', 'MonTheme'), 'half-slideshow' => __('Half Slideshow', 'MonTheme'), 'full-slideshow' => __('Full Slideshow', 'MonTheme'));

		if ( empty($check) )
			$check = get_user_setting('imgsize', 'medium');

		foreach ( $size_names as $size => $label ) {
			$downsize = image_downsize($post->ID, $size);
			$checked = '';

			// is this size selectable?
			$enabled = ( $downsize[3] || 'full' == $size );
			$css_id = "image-size-{$size}-{$post->ID}";
			// if this size is the default but that's not available, don't select it
			if ( $size == $check ) {
				if ( $enabled )
					$checked = " checked='checked'";
				else
					$check = '';
			} elseif ( !$check && $enabled && 'thumbnail' != $size ) {
				// if $check is not enabled, default to the first available size that's bigger than a thumbnail
				$check = $size;
				$checked = " checked='checked'";
			}

			$html = "<div class='image-size-item'>ID][image-size]' id='{$css_id}' value='{$size}'$checked />";

			$html .= "<label for='{$css_id}'>$label</label>";
			// only show the dimensions if that choice is available
			if ( $enabled )
				$html .= " <label for='{$css_id}' class='help'>" . sprintf( "(%d × %d)", $downsize[1], $downsize[2] ). "</label>";

			$html .= '</div>';

			$out[] = $html;
		}

		return array(
			'label' => __('Size'),
			'input' => 'html',
			'html'  => join("n", $out),
		);
}
function sf_image_attachment_fields_to_edit($form_fields, $post) {
	if ( substr($post->post_mime_type, 0, 5) == 'image' ) {
		$alt = get_post_meta($post->ID, '_wp_attachment_image_alt', true);
		if ( empty($alt) )
			$alt = '';

		$form_fields['post_title']['required'] = true;

		$form_fields['image_alt'] = array(
			'value' => $alt,
			'label' => __('Alternate Text'),
			'helps' => __('Alt text for the image, e.g. “The Mona Lisa”')
		);

		$form_fields['align'] = array(
			'label' => __('Alignment'),
			'input' => 'html',
			'html'  => image_align_input_fields($post, get_option('image_default_align')),
		);

		$form_fields['image-size'] = sf_image_size_input_fields( $post, get_option('image_default_size', 'medium') );

	} else {
		unset( $form_fields['image_alt'] );
	}
	return $form_fields;
}
add_filter('attachment_fields_to_edit', 'sf_image_attachment_fields_to_edit', 11, 2);
}	// fin de is_admin()

Repérez aussi la ligne 67, c’est là que la 2ème fonction appelle la 1ère.
Notez également que tout ceci ne sera appelé que depuis l’administration, car inutiles en front-end.
Nota : à la ligne 4 vous pouvez également traduire en plusieurs langues le nom de vos nouvelles tailles avec la fonction __( ).

Et voilà

Fenêtre médias pour ajouter des images dans les articles et pages :
Fenetre media de WordPress, plusieurs tailles d'images

Onglet médias du menu général :
Onglet media de WordPress, plusieurs tailles d'images

See ya!