WordPress 2.9: une piste pour gérer les vignettes des anciens articles

Avant la version 2.9, la méthode de gestion des vignettes associées aux articles, était basée sur les champs personnalisés. Basé sur un plugin, ou sur un petit développement au niveau du thème, cette gestion était relativement simple. Avec la version 2.9, WordPress permet maintenant d’associer une vignette à chaque article. Les utilisateurs vont devoir faire un choix: adopter le nouveau mode de gestion, ou conserver le mode de gestion actuel. Les deux cas seront difficiles à gérer à l’avenir. La question est donc: comment convertir les vignettes des anciens articles?

  • Passer dans le nouveau mode n’implique pas de gros changements: quelques lignes à ajouter au fichier functions.php, et dans les fichiers index.php et single.php. Le problème est que les fonctionnalités de WordPress
    ne s’appliqueront qu’aux nouveaux articles. Gérer les anciens articles impliquera de garder le plugin ou la personnalisation développée précédemment. Cela veut dire qu’il faudra administrer les outils nécessaires aux deux modes de gestion,
  • Conserver le mode actuel n’implique aucun changement au niveau du thème, ni au niveau de l’administration du site.

Mais dans les deux cas, la gestion des anciens articles deviendra de plus en plus problèmatiques, au fur et à mesure des évolutions de WordPress. Quand nous en serons à la version 3.x ou 4, il deviendra certainement difficile ou lourd de continuer à gérer les deux solutions. Les plugins gérant les vignettes aujourd’hui risquent peu à peu de ne plus être supportés par exemple.

L’idéal serait donc de convertir les vignettes pour n’avoir plus qu’un seul système de gestion à prendre en compte. Je vous propose d’explorer les solutions possibles pour réaliser cette conversion.

Il ne s’agit, en aucun cas, d’une solution « clé-en-main », mais de pistes à explorer.

N’essayez en aucun cas, les fonctions présentées dans cet article, directement sur votre site de production. Elles doivent être préalablement testées plusieurs fois sur un site de test.

Les outils nécessaires

De quoi avons-nous besoin pour réaliser cette conversion?
Nous devons d’abord lire les données actuelles. Il nous faut connaître

  • Le nom du champ personnalisé (meta_key) utilisé,
  • La fonction pour extraire les valeurs des champs personnalisés,
  • Le format du chemin de l’image (chemin absolu depuis la racine du blog? Chemin relatif? Depuis ou?

Nous devons ensuite savoir re-introduire dans la base, l’image trouvée dans l’étape précédente:

  • Si l’image n’est pas une pièce jointe, il faut la déclarer en temps que tel,
  • Et associer l’image au bon article.

Récupérer les informations des anciens articles

Nous supposons que la gestion des vignettes consiste simplement à stocker l’adresse de chaque vignette dans un champ personnalisé.
La façon la plus simple pour lister l’ensemble des vignettes associées aux articles, est d’utiliser une requête SQL:

global $wpdb; 
$meta_key = 'logo';
$sql = $wpdb->prepare('SELECT meta_id, post_id, meta_value FROM '.$wpdb->postmeta.', '.$wpdb->posts.' WHERE meta_key="%s" AND ID=post_id ORDER BY ID', $meta_key);
$thumbnails_values = $wpdb->get_results($sql, ARRAY_N);

Cette requête nous fournit l’ensemble des vignettes associées aux articles.

Déclarer les vignettes dans WP 2.9

Avec WP 2.9, les vignettes sont avant tout, des pièces jointes. Donc si ce n’est pas déjà le cas, les vignettes trouvées avec la requête précédente, doivent être déclarées comme pièces jointes.
Une fois passée cette étape, il ne reste plus qu’à déclarer la vignette avec le champ personnalisé _thumbnail_id.

La façon la moins risquée d’ajouter une pièce jointe, est d’utiliser la fonction wp_insert_attachment. Il faudra également générer les metadata de la vignette,
avec la fonction wp_update_attachment_metadata.

L’ajout du champ personnalisé se fera ensuite avec la fonction add_post_meta.

Les difficultés

L’opération ne semble pas trop compliquée. Il sera cependant difficile d’obtenir un plugin ou une fonction applicable dans tous le cas. Les deux problèmes possibles:

  • Détecter comment est codé l’adresse de la vignette, et comment le convertir en chemin absolu,
  • Générer, si cela est nécesaire, une image de la bonne taille.

Le code

Une fonction de conversion pourrait ressembler à cela:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
global $wpdb;
 
// Getting current thumbnails path
$meta_key = 'logo';
$sql = $wpdb->prepare('SELECT post_title, meta_id, post_id, meta_value FROM '.$wpdb->postmeta.', '.$wpdb->posts.' WHERE meta_key="%s" AND ID=post_id ORDER BY ID', $meta_key);
$logo_values = $wpdb->get_results($sql, ARRAY_N);
 
// Getting the current setting for upload path
$upload_path = get_option('upload_path');
 
// Foreach current thumbnails
foreach ($logo_values as $values) {
	list($post_title, $meta_id, $post_id, $meta_value) = $values;
 
	// Building the attachment object
	$path_parts = pathinfo($meta_value);
	$attachment = array( 'post_mime_type' 	=> 'image/'.$path_parts['extension'],
				 'guid'		=> $SITE_URL.'/'.$meta_value,
				 'post_parent'      => $post_id,
				 'post_title'		=> $path_parts['filename'],
				 'post_content'	=> '');
	// Managing path format
	$new_path = str_replace($upload_path.'/','', $meta_value);
 
	// Adding the attachment
	$attachment_id = wp_insert_attachment($attachment, $new_path);
 
	// Adding metadata of the attachment
	wp_update_attachment_metadata($attachment_id, wp_generate_attachment_metadata( $attachment_id, path_join(ABSPATH, $meta_value)));
 
	// Add custom field to declare the attachment as a thumbnail
	add_post_meta($post_id, '_thumbnail_id', $attachment_id, TRUE);
 
	// Deleting the old entry
	delete_post_meta( $post_id, $meta_key );
}

Dans mon cas, j’utilisais une personnalisation « maison », qui consistait à utiliser un champ personnalisé logo pour coder le chemin de l’image a prendre comme vignette. Le chemin est relatif par rapport à la racine du blog. Les vignettes étaient stockées dans la même arborescence que les pièces jointes, mais les vignettes n’étaient pas des pièces jointes, elles n’étaient donc pas présentes dans la base.

Actions restantes

La fonction précédente fonctionne bien dans mon cas. Il reste cependant quelques soucis:

  • Nous ne testons pas l’éventuelle présence de l’image dans la base de données,
  • Dans certains cas, la taille de l’image ne correspond pas à la taille de la vignette: il faudrait donc générer une vignette de la bonne taille. Cette opération peut être effectuée à part, avec un plugin comme Regenerate Thumbnails.
  • Dans les articles utilisant le shortcode Gallery, les images que nous venons d’ajouter vont apparaître, ce qui ne sera pas forcement, ni voulu, ni esthétique. Dans mon cas par exemple, les vignettes utilisées sont de taille réduite (100×100).

Avec WordPress 2.9, le shortcode Gallery propose deux nouveaux arguments: include et exclude. L’idée pourrait donc être

  • identifier les articles contenant le shortcode,
  • pour chacun des articles, ajouter le paramètre exclude, en spécifiant l’identifiant de la vignette.

La fonction pourrait prendre la forme:

1
2
3
4
5
6
7
8
9
10
global $wpdb;
 
$posts_list = $wpdb->get_results('SELECT ID, post_content, meta_value FROM '.$wpdb->wp_posts.', '.$wpdb->wp_postmeta.' WHERE post_content LIKE "%[gallery%" AND meta_key = "_thumbnail_id" AND ID = post_id');
foreach ($posts_list as $values) {
	list($post_id, $post_title, $post_content, $meta_value) = $values;
	$search_pattern = "/(.*?)[gallery(.*?)](.*?)/";
	$replace_pattern = '$1[gallery$2 exclude='.$meta_value.']$3';
	$new_post_content = preg_replace ( $search_pattern , $replace_pattern , $post_content);
	$wpdb->query('UPDATE '.$wpdb->posts.' SET post_content="'.$new_post_content.'" WHERE ID='.$post_id);
}

Conclusion

Voici donc quelques pistes pour utiliser le nouveau système de vignette avec les anciens articles. Ces pistes sont encore au stade de brouillon, mais fournissent une bonne base de travail.
La complexité ne vient, en fait, pas de la conversion elle-même, mais de la prise en compte de l’existant: Quelle convention est utilisée pour signaler la vignettes? Comment les chemins sont-ils codés? Ne sont que deux questions parmi beaucoup d’autres.
Je pense continuer encore l’étude, pour détecter d’éventuelles autres conséquences, avant de lancer le script sur mon propre blog.
Espérons que, bientôt, apparaîtront des plugins nous permettant de réaliser les conversions automatiquement.

4 thoughts on “WordPress 2.9: une piste pour gérer les vignettes des anciens articles”

  1. @Gabriel: i don’t think it’s possible only with SQL. I am not a SQL expert, I think there are two many changes to do. And with PHP, we can use the WP functions, to be sure that the images is well inserted in the DB.

  2. I’m very interested in this because I was using MagidFields plugin with custom field to add thumbnails, now with WP 3.0 I no longer have the need to use MagicFields since I can create Custom Post Types, but I would like to use the Post Thumbnail instead of custom fields, just like you describe in your article, but I was thinking the same could be achieved more easily in the DB, unfortunatly I don’t know enough SQL to perform the task, maybe you could take a look a it and give some pointers.

    Thanks a lot

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *