La gestion des pièces jointes (attachments), n’est pas ce que l’on peut appeler un point fort de WordPress. Avec le Media Manager, la version 2.5.x améliore sensiblement l’ergonomie d’un point de vue utilisateur. L’API s’étoffe également, mais la documentation reste assez pauvre. Voici donc un résumé des fonctions que WordPress met à notre disposition pour la gestion des attachements.
La base de données
Les pièces jointes sont stockées dans la base de données dans la table wp_posts sous forme d’articles (posts). Ils sont considérés comme des « sous-articles », et sont rattachés à des articles principaux. Les champs de la table wp_posts concernés sont:
| Champ | Type | Valeur | Description |
|---|---|---|---|
| ID | bigint(20) | Identifiant unique de l’article | |
| post_content | longtext | Description | |
| post_title | text | Nom du fichier | |
| post_excerpt | text | Intitulé | |
| post_status | varchar(20) | inherit | |
| post_parent | bigint(20) | ID de l’article auquel est attachée la pièce jointe | |
| guid | varchar(255) | url du fichier (de la pièce jointe) | |
| post_type | varchar(20) | attachment | |
| post_mime_type | varchar(100) | Type mime du document (image/jpeg par exemple) |
Les autres champs ne sont pas utilisés.
L’API
Les fonctions
Les fonctions sont toutes regroupées dans trois fichiers
wp-include/posts.php,wp-include/post_template.php,wp-include/media.php.
Il faut distinguer deux catégories de fonctions: la première permet de manipuler les pièces jointes, et la seconde permet d’en récupérer la liste et les paramètres pour les afficher.
Dans la première catégorie, nous trouvons wp_delete_attachment, wp_insert_attachment ou wp_update_attachment_metadata, qui permettent respectivement d’ajouter, d’effacer ou de modifier
une pièce jointe.
Les fonctions de la seconde catégorie sont plus nombreuses, mais souvent redondantes. Les plus importantes sont:
| Fonction | Arguments / Valeur par défaut |
Description |
|---|---|---|
| wp_attachment_is_image | $id | True ou False selon que la pièce jointe est une image ou pas |
| wp_get_attachment_image_src | $id, $size=’thumbnail’, $icon = false |
Renvoi un tableau contenant l’URL de l’image, ainsi que ses dimensions (hauteur, largeur). L’image peut être la pièce jointe elle-même ou une vignette |
| wp_get_attachment_image | $attachment_id, $size=’thumbnail’, $icon = false |
Renvoi la balise html pointant sur l’image ou la vignette (thumbnail). La réponse prend donc la forme: <img src= »" …> |
| wp_count_attachments | $mime_type | Renvoi un tableau avec la liste des types mime, et le nombre de documents par type (Array ($mime, $count)) |
| wp_get_attachment_link | $id = 0, $size = ‘thumbnail’, $permalink = false, $icon = false |
Renvoi le [perma]lien complet permettant l’affichage de la pièce jointe spécifiée. |
| get_children | $args, $output | Renvoi la liste des pièces jointes, en fonction des critères spécifiés dans args. La syntaxe est identique à la fonction get_posts $ouput peut prendre les valeurs OBJECT, ARRAY_N, ou ARRAY_A. La fonction appelle get_posts en ajoutant les arguments numberposts=-1, post_type=attachment et post_status => inherit |
| wp_get_attachment_metadata | $post_id, $unfiltered = false |
|
| wp_mime_type_icon | $id | Renvoi une url vers l’icône correspondant au type mime de la pièce jointe. |
size peut prendre les valeurs thumb, thumbnail, medium ou full.
Exemple d’application des fonctions précédentes: Affichage d’une liste de documents attachés (sans les images) à un article spécifié par $id.
$attachments = get_children( array( 'post_parent' => $post_id, 'post_status' => 'inherit', 'post_type' => 'attachment') ); if ( empty($attachments) ) return ''; $output = "\n"; foreach ( $attachments as $id =>; $attachment ) { if (substr($attachment->post_mime_type, 0, 5) != 'image') { $output .= wp_get_attachment_link($id, 'thumbnail', true, true) .' '; $output .= wp_get_attachment_link($id, 'thumbnail', true, false) . "\n"; } } echo $output;
Ce code va générer le HTML suivant:
<a title="album_martinique_2007" href="url 1">
<img class="attachment-thumbnail" src="url thumbnail" alt="" width="46" height="60" />
</a>
<a title="album_martinique_2007" href="url 1">album_martinique_2007</a>
<a title="Calendrier" href="url 2">
<img class="attachment-thumbnail" src="url thumbnail" alt="" width="46" height="60" />
</a>
<a title="Calendrier" href="url 2">Calendrier</a>
<a title="IPTC XMP Core" href="url 3">
<img class="attachment-thumbnail" src="url thumbnail" alt="" width="46" height="60" />
</a>
<a title="IPTC XMP Core" href="url thumbnail">IPTC XMP Core</a>ce qui donne:

Liste obtenue
Les fonctions get_posts et get_children ont quelques limitations. Par exemple, nous ne pouvons pas récupérer les pièces jointes d’un ensemble de catégories, ou exclure une ou plusieurs catégories. Dans ce cas, il reste à « taper » directement dans la base de données, ce qui n’est pas conseillé, et rend le développement plus vulnérable aux changements de version.
Les filtres et les hooks
Les filtres et les hooks ne sont pas très nombreux:
| Fonctions | Filtres | Actions (Hooks) |
|---|---|---|
| wp_insert_attachment | edit_attachment, add_attachment |
|
| wp_delete_attachment | wp_delete_file | delete_attachment |
| wp_get_attachment_url | wp_get_attachment_url | |
| wp_get_attachment_metadata | wp_get_attachment_metadata | |
| wp_get_attachment_image_src | icon_dir | |
| wp_mime_type_icon | icon_dir icon_dirs wp_mime_type_icon |
|
| wp_ext2type | ext2type |
Autres ressources
WordPress inclut également une série de vignettes pour décrire les types mime des documents. Ces images se trouvent dans le répertoire /wp-includes/images/crystal.
Les filtres icon_dir, icon_dirs et wp_mime_type_icon permettent d’influer sur l’affichage des vignettes (thumbnail). ext2type permet d’ajouter des types de documents.
Ces filtres ne sont pas complètement efficaces, car mal gérés dans certaines fonctions (wp_get_attachment_link par exemple). Je n’ai réellement réussi à m’en servir qu’avec la fonction wp_mime_type_icon.
Les templates
Les pièces jointes sont stockées comme de simples articles dans la base de WordPress. Au niveau des templates, il faut pourtant différencier un article principal et une pièce jointe, pour adapter l’affichage. WordPress propose quelques fonctions complémentaires pour gérer les attachments dans les thèmes.
Il existe d’abord un tag conditionnel (conditional tag), is_attachment() qui permet de savoir si nous sommes dans le cas d’un article ou d’une pièce jointe. WordPress propose également des templates dédiées. Lorsque l’on clique sur un lien correspondant à une pièce jointe, WordPress cherchera à utiliser les templates suivantes (dans cet ordre):
image.phpattachment.phpindex.php
Les templates image.php et attachment.php peuvent être créees pour afficher proprement une pièce jointe. Vous pouvez regarder, à titre d’exemple, la template image.php du thème classic, disponible par défaut dans WordPress.
Le permalien d’une pièce jointe prend la forme suivante:
http://<url du blog>/<url de l'article>/<url de la pièce jointe>
Conclusion
Depuis les versions 2.5.x, WordPress améliore sensiblement la gestion des pièces jointes, à la fois côté utilisateur, avec le Media Manager, et du côté développeur, avec une série de fonctions et de filtres permettant de proposer de nouvelles fonctionnalités, sans avoir besoin de requêter directement la base de données. Il subsiste encore quelques points à améliorer, notamment dans la gestion des vignettes.
Commentaires & rétroliens
Commentaires
17 commentaires
Rétroliens
1 rétrolien.
-
[...] Gorgeon a écrit un article théorique fort intéressant sur la gestion des pièces jointes par [...]
English
Vincent
14:33
Bonjour Emmnanuel,
Je me replonge dans ton article (dont j’ai déjà dit le plus grand bien), riche en enseignements !
Néanmoins, car je suis légèrement bouché, je ne comprends pas deux éléments dans ton exemple… Quels sont les utilités de :
1/if (substr($attachment->post_mime_type, 0, 5) != ‘image’)
2/$output .= wp_get_attachment_link($id, ‘thumbnail’, true, false) . « \n »;
Cette deuxième ligne se rapporte-t-elle à la fonction get_children ?
Merci pour les éclaircissements.
J’espère que le code ajouté à mon commentaire ne perturbera la page !
V.
Emmanuel
16:56
Bonjour,
J’ai legerement modifie le code pour qu’il soit plus lisible.
En fait, la condition
if (substr ...)permet de ne pas afficher les images.Ensuite, le premier appel a
wp_get_attachment_linkpermet l’affichage de l’icone (dernier parametre a TRUE), tandis que le second affiche le nom de l’attachement.Ces deux lignes sont dans la boucle foreach qui parcourt la liste des attachments.
Je prepare actuellement un plugin qui permettra d’afficher la liste des fichiers attaches via un shortcode, ce qui evitera tout developpement. Le plugin devrait etre publie d’ici une semaine maximum.
Vincent
17:51
Merci pour ces éclaircissements…
En revanche, le « substr » n’empêche pas, selon mes tests, en copiant-collant fidèlement ton code (première version…) l’affichage des images… Voilà pourquoi, je ne comprenais pas.
Je teste ta nouvelle version, et te tiens informé.
Je suis avec intérêt ton extension.
Merci.
Emmanuel
23:24
Oups, effectivement; l’accolade fermante n’etait pas au bon endroit.
Maintenant cela doit fonctionner.
JUST4iD
00:07
alors la, bravo, code clair, et simple
j’avais refait ca a ma sauce en moins propre.
et ta doc est plus concise et plus facile d’accès que celle de WP
la je code un petit bout pour récup les images automatiquement et les afficher en thumb, sans avoir à passer par des champs complémentaires comme c’est souvent expliqué dans les autres site …. domage d’avoir a passer par des champs complémentaires et donc des uploads via ftp, des remaniement d images alors que WP fait tout ca tres bien
je vais revoir ca avec ton code …
merci !
Emmanuel
00:59
Merci pour les compliments.
Effectivement, il est toujours plus pratique d’utiliser le « media manager » que d’uploader les images via FTP et d’en saisir le nom a la main. J’avoue pratiquer ce genre de chose pour les icones situes a gauche des articles. Il est dommage que WP n’aille pas plus loin, en proposant de quoi reellement exploiter les pieces jointes.
JUST4iD
01:23
j ai un peu buté pour utiliser le menu_order car il n’est pas décrit ici.
j’ai trouvé ce lien impressionnant!!
http://wphackr.com/get-images-attached-to-post/
un joli codeur aussi ce monsieur
a++
JUST4iD
02:04
ha et tu veux pas installer suscribe to comments ?
ciao
C.
Vincent
11:11
Oui, le problème est l’attachement des pièces jointes qui ne peut concerner qu’un article… On ne peut donc les réutiliser dans d’autres articles en les affichant avec un appel comme wp_get_attachment_image, si j’ai compris.
Idéalement, il faudrait pouvoir :
- attacher une image à un fichier sans passer par l’édition d’un message ;
- pouvoir attacher l’image à plusieurs articles.
Du coup, je crois que la seule solution pour personnaliser la gestion des images reste les Custom Fields, et je vais m’en servir pour concevoir un thème… même si cette solution ne me satisfait pas sur le plan intellectuel.
JUST4iD
11:29
c’est vrai que l’idéal serait de pouvoir attacher un doc a plusieurs articles/pages…
il faudrait revoir le fonctionnement de WP, qui malheureusement bloque les liaisons en laissant le champs directement dans la table des posts, et il faudrait donc créer une table de liaison à part.
cela pourrait permettre sans passer par des custom fields de lier des articles avec d’autres articles ou bien des docs ou encore meme des commentaires, à la base n’ayant pas de rapport.
Le coté négatif d’un tel systeme est la complexité de la gestion que cela induit. il faut un backoffice propre, intelligent sinon les liaison prennent le dessus et on ne comprend vite plus rien.
a méditer
Masamune
00:03
Hey !
Un petit mot, tout d’abord pour dire merci d’avoir posté quelque chose d’intéressant et d’utile sur les pièces jointes, cela m’a bien aidé ^^.
Par contre j’aurai un question : sous WordPress quand j’affiche une pièce jointe de type image, il me l’a met dans une balise « caption », et affiche un aperçu de l’image, alors que quand je fais exactement la même manip pour n’importe quel autre type de fichier il me met juste un vieux lien tout pourri. Tu saurais ou il faut tripatouiller pour rajouter des icônes d’aperçu aux autres types de fichiers ?
D’après ton code j’ai réussi à afficher des icônes aux types de fichier, mais je bloque sur la fonction « the_content » appelée dans la boucle WordPress. J’arrive seulement à afficher les pièces jointes comme je veux en dessous du contenu.
(J’ai posté un article test sur mon blog, article du 18/07/09)
Enfin, pour résumer : comment remplacer le vieux lien a href des pièces jointes par une jolie icône dans un article ?
Merci d’avance ^^
Emmanuel
09:31
Bonjour,
La seule solution que je vois est de faire un preg_replace dans le filtre the_content.
J’utilise cette technique pour ajouter la balise « rel=lightbox » sur mon blog. La fonction ressemble a cela:
add_filter('the_content', 'add_lightbox' ); function add_lightbox($content) { global $post; if (!is_feed() && strpos($content, 'rel="lightbox"') === FALSE) { $search_pattern = "/<a(.*?)href=('|\")([^>]*).(bmp|gif|jpeg|jpg|png)('|\")(.*?)>(.*?)<\/a>/i"; $replace_pattern = '<a$1href=$2$3.$4$5 rel="lightbox['.$post->ID.']"$6>$7</a>'; $content = preg_replace ( $search_pattern , $replace_pattern , $content ); } return ($content); }Il faudra que tu transformes les expressions régulières pour obtenir ce que tu veux, et utiliser la fonction
wp_mime_type_iconpour recuperer l’icone correspondant au document.Sinon tu as toujours mon plugin
Masamune
12:17
Merci pour cette réponse rapide, claire et technique.
Pour les lightbox j’ai déjà un plugin-in qui tourne, mais pour ce que je veux faire c’est exactement ça ; je teste tout à l’heure ^^.
sebastien
18:02
j’ai des videos dans des articles, je me demandais si il était possible de récuperer l’url de la video via ce systeme d’attachment…
Emmanuel
09:35
Si les videos sont associees a l’article, il est tout a fait possible de recuperer les URL
Il faut pour cela faire une boucle comme indiqué dans l’article, et récupérer l’URL avec la fonction
get_attachment_link($id)Nohant
20:34
Bonjour,
Question bête mais à quoi sert la variable global $post dans l’exemple d’utilisation de preg_replace ? Ca m’intéresse car je suis en train d’essayer de manipuler the_content pour rajouter une div avec une class à une partie d’un post.
Merci d’avance,
Emmanuel
02:40
A rien dans l’exemple.
La seule information disponible dans cette fonction est le contenu de l’article en cours.