Meta box : liez un pdf à votre article
Dans l’article d’hier on s’initiait aux meta boxes de WordPress. Ces petites boites que nous rajoutons dans l’admin, nous permettant d’ajouter des informations complémentaires à vos articles, pages, contenus…
Maintenant je vous propose de découvrir des metaboxes plus complexes, pour des utilisations spécifiques.
Je ne sais pas si vous avez déjà rencontré ce problème mais pour créer dans WordPress des boites contenant des champs input:file, c’est un peu la merde. Tout simplement car les formulaires de l’admin ne sont pas fait pour ça (ils n’ont pas l’attribut enctype=“multipart/form-data”), peut-être pour des raison de sécurité…
Donc pour uploader des PDFs et les associer à vos contenus il va falloir trouver une autre méthode.
Celle que nous allons voir est amplement pompée du génialissime ouvrage « Professional WordPress Plugin Development » que je vous conseille vivement de lire.
Codons la meta box !
Tout d’abord voyons le principe.
Nous allons créer un champ texte et un bouton.
Au clic sur le bouton, un code javascript va nous permettre d’utiliser la fenêtre d’upload des medias pour envoyer notre contenu dans WordPress…
Après l’upload, un clic sur “insérer dans l’article” renseignera l’URL du fichier dans le champ texte prévu à cet effet.
Le code de base
La première étape consiste donc à créer notre metabox, avec le bouton et le champ texte.
On procède comme expliqué dans le précédent article. Il faut initialiser la metabox, la construire puis prévoir la sauvegarde de la metadonnée.
Pour l’instant un clic sur le bouton ne sera suivi d’aucune action. Si on renseigne du texte dans le champ et que l’on sauvegarde l’article, les données seront sauvegardée.
Le javascript
Maintenant il va falloir créer le javascript. Son rôle sera de faire apparaitre la fenêtre d’upload des médias lorsque l’on cliquera sur “Télécharger un document pdf”.
Créez un nouveau fichier .js puis copiez-y le code suivant.
Ce code ne sert (en gros) qu’à charger la fenêtre des medias, maintenant il faut ajouter un autre bout de code.
Après avoir sélectionné/envoyé un fichier, un clic sur “insérer dans l’article” envoie l’URL du fichier dans notre champ texte.
La méthode de WordPress correspondant au bouton insérer dans l’article est “send_to_editor”. C’est elle que nous allons intercepter.
Il faut ajouter à notre Javascript (avant la fermeture du jQuery) le code suivant
Voilà… En fait on voit dans ce code qu’il a fallu employer une ruse pour différencier notre usage de la boite d’upload de son usage normal, afin qu’elle ai toujours le comportement attendu.
Il ne nous reste qu’a enregistrer notre script et à le charger, via wp_enqueue_script(), dans l’admin. Insérez ce code dans la fonction pdf_metabox().
Pour que le script fonctionne, il faut qu’il soit chargé après jQuery, media-upload et thickbox.
Vous pouvez maintenant tester notre metabox, elle doit normalement fonctionner.
Les dépendances
Ahhh… un petit détail. Si vous souhaitez utiliser cette metabox sur un type de contenu n’ayant pas d’éditeur, ça ne marchera pas. Enfin pas dans l’état…
La raison est simple, notre script a beaucoup plus de dépendances, qui sont normalement chargées en même temps que l’éditeur. Il faudra donc, avant d’appeler notre javascript, appeler tous ces javascripts et feuilles de style.
Un shortcode pour ressortir tout ça
Nous pouvons récupérer l’URL du PDF lié via la fonction get_post_meta(), dans le template. Cependant cela peut être très pratique de le récupérer directement dans le contenu également.
Voici un shortcode permettant de faire ça. L’avantage de l’utiliser est que vous n’aurez pas modifier le lien dans l’éditeur si vous mettez à jour le PDF. Et puis ça sera un peu plus clair pour vos clients.
Pour l’utiliser, il suffit d’insérer [pdf] dans votre article, ou bien encore [pdf]Téléchargez mon PDF ![/pdf].
Pour utiliser le shortcode, il suffit de copier le code ci-dessus dans votre fichier functions.php.
Aller plus loin : un custom post type «téléchargements»
Jusqu’ici nous avons vu comment ajouter une meta box de type fichier, afin de lier un pdf à un article.
Il m’arrive souvent, en plus, de créer un Custom Post Type “Téléchargement” et d’y assigner cette seule metabox. L’intérêt de procéder ainsi est :
- d’identifier clairement un type de contenu PDF
- de faciliter la traduction de ces contenus, avec WPML par exemple
- de pouvoir lier une multitude de PDFs à un article
Il faut commencer par créer ce type de contenu, dans le fichier functions.php.
Pour l’instant, ce type de contenu ne supporte que le champ “titre” . Il faut aussi y associer la meta box crée plus haut, en modifiant le 4ème paramètre par telechargement.
Nos fichiers PDFs sont maintenant totalement indépendants. Il ne reste plus qu’à les re-rendre associables aux autres contenus…
La metabox pour lier plusieurs fichier relatifs
Pour ce faire on va faire une autre meta box, plutôt simple. On peut repartir du modèle des “meta-check-box” du dernier article, auquel on va simplement ajouter une boucle pour lister tous les téléchargements disponibles.
Ça y est, nous pouvons associer autant de fichiers PDFs que l’on veut à nos articles. À noter que c’est également plus simple pour associer le même PDF à plusieurs contenus.
Obtenir la liste
Pour afficher la liste de tous les PDFs lié au contenu, on peut là encore utiliser la function get_post_meta() ou bien nous pouvons utiliser un autre shortcode que voici :
Pour l’utiliser, il faut juste ajouter dans votre contenu [tous_pdf]. Simple, n’est ce pas ?
Je trouve que cette solution est très facile à utiliser sur les sites, et pas si dur à mettre en place.
Merci à Brad Williams pour le javascript !
Bon… demain on se fait une autre metabox ?
Bravo pour le boulot, et vivement les prochains articles de la série. 😉
Malheusement le shortcode ne fonctionne pas pour moi (mais tous le reste fonctionne.
J’ai pourtant bien copier la fonction dans fonction.php
Respect 😉
Le shortcode il faut l’appeler avec [pdf] et non
[lien_pdf]. Idem pour le second shortcode qu’il faut appeler avec [tous_pdf]Merci de m’avoir faire remonter l’erreur 🙂
L’ouvrage que tu cite en introduction est effectivement un « must-have », 500 pages qui valent de l’or.
Merci, ça va largement servir.
Hâte de lire les prochains de la série.
Dans le bouquin, Brad Williams parle comme ça de la méthode « send_to_editor » de WordPress. C’est frustrant, j’ai fouillé pour voir s’il y en avait d’autre du même genre (par exemple pour intercepter l’image à la une) mais je n’ai pas trouvé grand chose…
Tu parles de sécurité en debut d’article. On utilise ici la fenêtre d’upload des médias, cela signifie que c’est parfaitement safe ?
Bonne fin de semaine,
Mathieu
Petit bémol par contre: le javascript pour uploader les pdf (via le custom type téléchargements) ne fonctionne pas sur mon install de wordpress 3.4.1:
J’ai mis « editor » dans la liste des support du custom type, le javascript est bien chargé et la fenêtre d’upload s’ouvre bien mais ça n’ajoute pas le lien lorsque l’on clique sur « insérer dans l’article »
Via firebug j’ai ces erreurs là:
Syntax error: invalid label:
Notice: Undefined index: post_id in /wp-admin/includes/media.php on line 1270
et
ReferenceError: formfield is not defined
Une idée pour résoudre ça ?
Comment faire quand on veut lier la métabox non pas à un post classique mais à un custom-post?
c’est vraiment très intéressant.
Comment adapter cela pour un type d’article ou de page en particulier ?
Je pense notamment aux « custom_post »
Merci pour tes tuto métabox elles me sont vachement utiles pour comprendre ces précieuses metabox, beau boulot !
((( Je tente à mon tour d’en coder une pour attribuer un format à mon article (image, vidéo, lien url, citation, discussion etc). ;p )))
Je suis un débutant et donc je souhaiterai quelques précisions sur celle-ci.
– les codes affichés sont corrigés pour les versions wordpress en court ?
– J’ai mis tes codes/ fichiers à la racine de mon thème pour tester cette métabox mais rien ne fonctionne. Dois-je insérer ces codes/fichiers ailleurs ? ah oui la seul chose modifiée c’est la valeur ‘post’ en ‘portfolio’ afin que cette métabox apparaisse dans la section portfolio de mon theme.
Merci.