WordPress : Des custom post types vraiment custom
L’arrivée des custom post types dans WordPress 3 permet de gérer d’autres types que des articles et des pages. C’est une grande avancée : on peut définir de nouveaux types bien distincts, qui ont leur propre entrée dans le menu.
Cependant, ces custom post types sont un peu limités : en effet, on peut choisir quels champs on souhaite, mais seulement par rapport aux champs types d’un post (ou d’une page) : titre, extrait, champs personnalisés, vignette… En gros, on peut enlever des champs inutiles (ce qui est déjà pratique), mais on ne peut pas en ajouter.
Du coup j’ai développé un script pour ajouter des nouveaux champs. A noter que les fonctions citées ci-après vont se placer dans le fichier functions.php du thème, il n’y a donc aucune modification des entrailles de WordPress, et par conséquent pas de problème pour mettre ce dernier à jour.

Principe
- Nous créerons un custom post type, en gardant les champs qui nous intéressent.
- Nous créerons un tableau php dans lequel nous spécifierons les nouveaux champs souhaités ainsi que leurs types.
Petite remarque : pour les champs pour lesquels on souhaite une liste de cases à cocher, je vous suggère fortement d’utiliser la fonction register_taxonomy, qui permet d’ajouter des catégories ou tags spécifiques à un custom post. En ajoutant des catégories à votre custom post type (càd en mettant hierarchical à true), vous aurez la même interface que pour choisir des catégories. - Nous allons créér une fonction que nous placerons sur le hook ‘edit_form_advanced’. De cette façon, le texte affiché par notre fonction viendra se placer à la fin du formulaire d’édition d’un post. Nous n’oublierons pas de tester que nous sommes en train d’éditer notre custom type, sinon, nous allons affecter les formulaires de tous les posts !
Cette fonction va prendre notre tableau de champs, et pour chaque élément, afficher dans le formulaire un input, un textarea, un select ou un checkbox selon le cas. - A l’enregistrement du post (en s’attachant au hook ‘save_post’), nous prendrons tous les champs de notre tableau et l’on ajoutera/mettra à jour un champ personnalisé pour cet article.
Le code
Vous pouvez récupérer le code entier ici : code php pour des custom post types vraiment custom.
Explication de code
Préambule : Variables
global $myposttype; global $myCustomTypeOptions; $myposttype='moncustomposttype'; //id de mon custom post
N’ayant pas trouvé comment faire passer des paramètres à une fonction via add_action, je me suis rabattue sur la bonne ville méthode bien sale des variables globales (si qqn peut m’éclairer sur la question des paramètres via add_action, je suis preneuse).
Donc, on déclare deux variables globales, une pour le nom du custom post type, et une autre pour le tableau de champs de formulaires.
Etape 1 : Ajout de notre custom post type classique
On définit notre custom post type, on choisit les champs types qu’il supporte.
On ajoute éventuellement des catégories personnalisées.
add_action('init', 'moncustomposttype_init');
function moncustomposttype_init()
{
global $myposttype;
register_post_type($myposttype, array(
'label' => 'Custom Posts',
'singular_label' =>'Custom Post',
'public' => true,
'show_ui' => true,
'capability_type' => 'post',
'hierarchical' => false,
'supports' => array('title', 'editor', 'thumbnail' )
));
/********** pour les checkbox à choix multiples : le plus simple est de déclarer une taxonomie hiérarchique (= catégorie) ****************/
register_taxonomy( 'couleurs', $myposttype, array( 'hierarchical' => true, 'label' => 'couleurs', 'query_var' => true, 'rewrite' => true ) );
}
Etape 2 : Le tableau de champs
Le tableau doit être rempli ainsi :
Pour chaque champs :
tableau(‘name’=> Label du champ,
‘desc’ => Petite description
‘id’=> l’attribut « name » du champ (c’est une bonne idée de préfixer par $myposttype_)
‘type’ => le type du champ (parmi « checkbox », « text », « select », « textarea »
‘options’ => pour le type select : tableau des valeurs d’options
‘std’=>; la valeur par défaut )
$myCustomTypeOptions = array (
array(
'name' => 'Mon champ text',
'desc' => 'Description 1',
'id' => $myposttype.'_champtexte',
'type' => 'text',
'std' => ''),
array(
'name' => 'Mon textarea',
'desc' => 'Description 2',
'id' => $myposttype.'_textarea',
'type' => 'textarea',
'std' => 'Youpi'),
array(
'name' => 'Mon select',
'desc' => '',
'id' => $myposttype.'_choix',
'type' => 'select',
'options' => array('choix 1','choix 2','choix 3'),
'std' => 'choix 2'),
array(
'name' => 'Mon checkbox',
'desc' => 'Case à cocher',
'id' => $myposttype.'_case',
'type' => 'checkbox',
'std' => '1')
);
Etape 3 – La fonction qui ajoute les champs au formulaire
/************** à la fin du formulaire, ajout des champs définis dans $myCustomTypeOptions ***********/
add_action('edit_form_advanced', 'moncustomposttype_form');
add_action('save_post', 'moncustomposttype_save');
function moncustomposttype_form(){
global $myposttype;
global $myCustomTypeOptions;
if((isset($_GET['post_type'])) and ($_GET['post_type']==$myposttype)) /* formulaire d'ajout */
{
echo '
';
}
else{
if(!isset($_GET['post_type']))
{
if(isset($_GET['post']))
{
if(get_post_type($_GET['post'])==$myposttype) /* formulaire de modification */
{
$id=$_GET['post'];
/* formulaire prérempli avec les valeurs pré-existantes */
echo '
';
}
}
}
}
}
function get_champ($o,$val)
{
switch ($o['type'])
{
case 'textarea':
echo ' ';
break;
case 'text':
echo '
';
break;
case 'checkbox':
echo '
';
break;
case 'select':
echo '
';
break;
}
}
Etape 4 : Sauvegarder nos champs dans des champs personnalisés
/***************** Lors de la sauvegarde, ajout/modification d'un custom field par champs de $myCustomTypeOptions ***********/
function moncustomposttype_save(){
global $myposttype;
global $myCustomTypeOptions;
if(isset($_POST['post_ID']))
{
$id=$_REQUEST['post_ID'];
if(get_post_type($id)==$myposttype) /* si on édite bien un post du type $myposttype */
{
foreach ($myCustomTypeOptions as $o)
{
if(isset($_POST[$o['id']])) {
update_post_meta($id, $o['id'], $_POST[$o['id']]);
}
elseif($o['type']=='checkbox') {
update_post_meta($id, $o['id'], 0);
}
}
}
}
}





Par forunner
Vraiment pratique =) – ça devrait être intégré dans le codex
Par sebastien
il ne manque que l’upload d’image et ce serait parfait !
Par Virginie
C’est vrai ! Je l’ajouterai un de ces jours.
Par Stephane
j’ai suivi « a la lettre » , mais je n’arrive pas a afficher les custom posts avec les champs appropriés.
(ca fonctionne dans l’admin…)
Qqn aurait il un bout de code a insérer peut etre dans la page single.php » afin que je puisse afficher mes custom posts avec les champs.?
Merci d’avance.
Par Virginie
As-tu essayé comme ça : echo get_post_meta(get_the_ID(),’moncustomposttype_monchamp’, true); ?
Par stephane
ca marche pas mieux , j’ai meme essayé de creer un template perso (http://www.devblog.fr/2010/09/24/home-custom-post-wordpress/) ca marche pas pareil ….
Par Virginie
Etrange… Est-ce qu’en base dans la table wp_postmeta, tu as bien pour le post souhaité, une meta_key ’moncustomposttype_monchamp’, (sans faute de frappe), avec la valeur que tu attends ?
Par stephane
la meta_key es : moncustomposttype_champtexte
et la ca s’affiche !
Par stephane
C’est bon ca fonctionne maintenant, mais il a fallu que je renseigne dans mon single.php chaque custom_fields …
Merci de votre aide
Par YannouLeMerou
sauf erreur de ma part, le code de moncustomposttype_save() ne mettra pas à jour dans la base la valeur d’une case à cocher décochée.
On peut faire en reprenant le code existant :
if(isset($_POST[$o['id']])) {
update_post_meta($id, $o['id'], $_POST[$o['id']]);
}
elseif($o['type']==checkbox) {
update_post_meta($id, $o['id'], 0);
}
Par Virginie
Effectivement, je vais mettre à jour le script, merci.
Par stephane
Bonsoir,
j’ai créé un custom post grace a votre script, lors de la creation des mes custom fields, je voudrais récupérer l’ID du post en cours …
array(
‘name’ => ‘numero de l\’offre’,
‘desc’ => ‘Numero de l\’offre : $post_id ; ‘,
‘id’ => $mon_offre_type.’_numero_offre’,
‘type’ => »,
‘std’ => »),
J’ai mis $post_id mais ca ne me ramene pas l’ID du post en cours.
Merci encore …
Par walidos
salut tt le monde,
j’ai le mm erreur que stephane mais j’en ai pas les gamps dans la table post_meta, comment je êux afficher mes champs dans le back offices svp ???
Par walidos
@stephane : comment je peux declarer mes variables dans la pâge signe.php stp ?
Par unknownclubberz
ENORME ! Merci pour la pédagogie, le source en download et la traduction du codex, référence par excellence mais un peu obscur quelquefois ! Beau boulot les gars
Par unknownclubberz
Pour l’upload d’image, ajoutez simplement :
add_theme_support( ‘post-thumbnails’ );
Par Geoffrey
Bonjour,
Article vraiment pratique
Il est facile de rajouter les types « hidden », « email », sur le même modèle que le « text » (au niveau du traitement).
Un manquement peut-être, le traitement de champs de type radio.
Bonne continuation