Créer une nouvelle entité « Projets » avec les Custom Post Type

26 février 2011 dans Tutoriels Wordpress

the-power-of-wordpress

Pour rappel les Custom Post Types permettent de rajouter des entités supplémentaires à votre site wordpress. Par exemple je souhaite ajouter une entité « projets » afin de gérer et afficher mes projets en cours. J’aurai pu simplement créer une catégorie « projets » dans les articles mais mon entité projet est plus complexe qu’un simple billet de blog.

Dans un précédent article j’ai fais une première approche des Custom Post Type grâce au plugin Easy Post Type.

Ce tutoriel va vous permettre de créer vos propres custom post type sans plugin, ce qui vous permettra une meilleur souplesse dans vos projets WordPress.

De bonnes notions de développement sont nécessaires afin de bien comprendre. Si vous êtes débutant je vous invite à regarder ce lien avant de vous attaquer à ce long tutoriel : plugin Easy Post Type.

Du côté back-office

Afin de déclarer à WordPress ma nouvelle entité « Projets » j’insère ce code dans function.php :

function projet_module() {
 $args = array(
 'label' => __('Projets'),
 'singular_label' => __('Projet'),
 'public' => true,
 'show_ui' => true,
 '_builtin' => false, // It's a custom post type, not built in
 '_edit_link' => 'post.php?post=%d',
 'capability_type' => 'post',
 'hierarchical' => false,
 'rewrite' => array("slug" => "projects"),
 'query_var' => "projets", // This goes to the WP_Query schema
 'supports' => array('title', 'editor', 'thumbnail') //titre + zone de texte + champs personnalisés + miniature valeur possible : 'title','editor','author','thumbnail','excerpt'
 );
 register_post_type( 'projet' , $args ); // enregistrement de l'entité projet basé sur les arguments ci-dessus
 register_taxonomy_for_object_type('post_tag', 'projet','show_tagcloud=1&hierarchical=true'); // ajout des mots clés pour notre custom post type
 //add_action("admin_init", "admin_init"); function pour ajouter des champs personnalisés
 //add_action('save_post', 'save_custom'); function pour la sauvegarde de nos champs personnalisés
}
add_action('init', 'projet_module');

Résultat :

Depuis l’administration wordpress l’entité « Projets » doit apparaitre.

Actuellement si on souhaite ajouter un projet, ce dernier aura quasiment la même structure qu’un billet libre.

Le but maintenant est d’ajouter des champs personnalisés à notre entité.

Ajout des champs personnalisés

Nous allons rajouter un champ Url du projet pour préciser l’adresse web (cas d’un site internet).

1)Pour ce faire : copier le code ci-dessous au dessus du code précédent :

function admin_init(){ //initialisation des champs spécifiques
 add_meta_box("url_projet", "Url du projet", "url_projet", "projet", "normal", "low");  //il s'agit de notre champ personnalisé qui apelera la fonction url_projet()
}
function url_projet(){     La fonction qui affiche notre champs personnalisé dans l'administration
 global $post;
 $custom = get_post_custom($post->ID); fonction pour récupérer la valeur de notre champ
 $url_projet = $custom["url_projet"][0];
 ?>
 <input size="70" type="text" value="<?php echo $url_projet;?>" name="url_projet"/>
 <?php
 }
function save_custom(){ //sauvegarde des champs spécifiques
 global $post;
 if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) { // fonction pour éviter  le vidage des champs personnalisés lors de la sauvegarde automatique
 return $postID;
 }
 update_post_meta($post->ID, "url_projet", $_POST["url_projet"]); //enregistrement dans la base de données
 }

2)Repérer les lignes ci dessous et enlever les // :

//add_action("admin_init", "admin_init"); function pour ajouter des champs personnalisés
 //add_action('save_post', 'save_custom'); function pour la sauvegarde de nos champs personnalisés

ce qui donne :

add_action("admin_init", "admin_init"); function pour ajouter des champs personnalisés
 add_action('save_post', 'save_custom'); function pour la sauvegarde de nos champs personnalisés

Résultat :

Le champ personnalisé doit apparaître dans l’édition d’un projet.

Si tout c’est bien déroulé vous devriez pouvoir créer des projets de la même manière qu’un article.

Nous allons maintenant rajouter une catégorie client qui nous permettra de saisir des noms de clients et les attribuer à nos futurs projets .

Ajouter une catégorie à un custom post type (taxonomy)

1) Repérer la ligne :

register_taxonomy_for_object_type('post_tag', 'projet','show_tagcloud=1&hierarchical=true'); // mots clés

2)Et juste en dessous de cette ligne rajouter ces lignes de codes :

$labelsCat1 = array(
 'name' => _x( 'Clients', 'post type general name' ),
 'singular_name' => _x( 'Client', 'post type singular name' ),
 'add_new' => _x( 'Add New', 'client' ),
 'add_new_item' => __( 'Ajouter un client' ),
 'edit_item' => __( 'Modifier le client' ),
 'new_item' => __( 'Nouveau client' ),
 'view_item' => __( 'Voir le client' ),
 'search_items' => __( 'Rechercher des clients' ),
 'not_found' =>  __( 'Aucun client trouvé' ),
 'not_found_in_trash' => __( 'Aucun client trouvé' ),
 'parent_item_colon' => ''
 );
 register_taxonomy("clients", array("projet"), array("hierarchical" => true, "labels" => $labelsCat1, "rewrite" => true));

Résultat :

L’entité projet possède maintenant une catégorie Clients (vous pouvez créer d’autres catégories si vous le souhaitez).

Depuis l’édition d’un article un bloc Client apparait.

Après avoir ajouté quelques projets depuis l’admin nous allons maintenant créer un modèle de page qui va accueillir tous nos projets.

Création d’un modèle de page.

  • Dupliquer le fichier page.php de votre template et renommer ce nouveau fichier par exemple : page-projets.php.
  • Editer page-projets.php avec un éditeur de texte et ajouter cette ligne de code :
/**
 Template Name: Page des projets
 */

Pour mieux comprendre voici le début de mon fichier page-projets.php :

<?php
/**
 Template Name: Page des projets
 */
get_header(); ?>
		<div id="container">
  • Uploader ce nouveau fichier via ftp dans le répertoire de votre template.
  • Depuis votre administration WordPress, créer une nouvelle page « projets ».
  • Changer le modèle de page « Modèle par défault » par « Page des projets » depuis la liste déroulante :

  • Voila votre modèle de page relié à votre page projets, maintenant il reste simplement à appeler la fonction d’affichage des projets.

Affichage des projets sur le site

Dans votre fichier page-projets.php repérer la ligne :

<?php the_content(); ?>

Juste en dessous de cette ligne ajouter ce code :

<div id="projets">
 <?php  $temp_query = $wp_query;
 $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
 $args=array(
 'caller_get_posts'=>1,
 'post_type' => 'projet',
 'paged'=>$paged
 );
 $wp_query = new WP_Query($args);
 while ($wp_query->have_posts()) : $wp_query->the_post();
 $src = wp_get_attachment_image_src( get_post_thumbnail_id($post->ID));
 ?>
 <a href="<?php the_permalink();?>"><img src="<?php echo $src[0];?>" /></a>
 <h2><a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title_attribute(); ?>"><?php the_title(); ?></a></h2>
 <?php
 $terms = get_the_terms($post->ID, 'clients', '', ', ','');
 if ( !empty( $terms ) ){
 $numTerm = 0;
 echo "<h3>CLIENT : </h3>";
 echo "<p>";
 foreach( $terms as $term ) {
 $numTerm++;
 if ($numTerm == 1){
 echo " ".$term->name;
 }
 else{
 echo ", ".$term->name;
 }
 }
 echo "</p><br/>";
 }
 ?>
 <div>
 <p><?php the_excerpt(); ?></p>
 </div>
 </div>

Ce code affichera tous les projets par ordre chronologique (miniature, titre, client(s) )

Un peu de CSS permet d’adapter cela à votre design.

Résultat : Notre page devrait accueillir les projets, il ne reste plus qu’à faire la page intérieur.

Page intérieur (single-project.php)

Dupliquer le fichier single.php et renommer la copie single-project.php

Tous les codes sont à coller à l’intérieur de la boucle WordPress :

<?php if ( have_posts() ) while ( have_posts() ) : the_post(); ?>
Intérieur de la boucle (Ici le code varie en fonction du thème choisie)
<?php endwhile; // fin de laboucle. ?>

1) Ajouter le champ personnalisé Url du projet :

<?php
 $custom = get_post_custom($post->ID);
 $url_projet = $custom["url_projet"][0];
 ?>
<a href="<?php echo $url_projet;?>">Voir ce lien</a>

2)Ajouter la catégorie client :

<?php
 $terms = get_the_terms($post->ID, 'clients', '', ', ','');
 if ( !empty( $terms ) ){
 $numTerm = 0;
 foreach( $terms as $term ) {
 $numTerm++;
 if ($numTerm == 1){
 echo " ".$term->name;
 }
 else{
 echo ", ".$term->name;
 }
 }
 }
 ?>

Si vous avez des difficultés n’hésitez pas à poser vos questions via les commentaires.

25 Commentaires

  1. Bonjour Benjamin,
    Merci pour cet article, j’ai tourné à travers un tas de site et ce n’est pas évident de trouver quelque chose d’à peu près clair en terme de codes sur les post_type et les taxonomies.
    Je suis confronté à un problème depuis plusieurs jours, sans trouver de solution. J’ai une taxonomie hiérarchisée (France, Régions, Villes) et quand je veux afficher l’élément le plus bas (la ville) WordPress me retourne parfois ‘France’ et d’autre fois ma ville.
    Pourrais-tu me guider avec un code qui m’assure d’avoir ma ville à chaque coup ? Je suis sur que c’est une question d’ordre, mais je ne vois pas ou placer ce paramètre.

    Merci d’avance.

    • benjamin

      Le code ci-dessous à mettre dans le fichier single- »ton-custom-post-type ».php fonctionne pour une taxonomy à 3 niveaux (Pays,Régions,Villes) :


      $taxonomy = "ta-taxonomy";
      $terms = get_the_terms(get_the_ID(), $taxonomy);
      $villesAndRegions = array();
      $villes = array();
      $pays = array();
      foreach ($terms as $term) {
      if ($term->parent){ $villesAndRegions[] = $term->term_id;}
      else{$pays[] = $term->term_id;} //on recupere les pays
      }
      foreach ($terms as $term) {
      if ($term->parent){
      if(in_array($term->parent,$pays)){
      // il s'agit des regions
      }
      else{
      //et la des villes !
      $villes[] = $term->name;
      }
      }
      }
      echo 'Ville: ' . implode(', ', $villes);?>

  2. Il fallait que je trouve une solution rapidement, alors j’ai finalement utilisé une autre méthode, mais je reviendrait sans doute sur ton code pour voir d’un peu plus près ce que tu m’a suggéré ^^ En tous cas merci d’avoir pris le temps de répondre.

  3. Bonjour,
    Je suis un peu embêté, je ne sais pas si j’ai bien tout compris.

    Je fais une partie encyclopédie sur mon site, j’ai donc utilisé ses custom post type pour avoir des fiches de types personnalités, de type personnages, de types consoles, de type sociétés, etc.

    Hors le soucis c’est que j’aimerai avoir un template différent pour chacun de ses fiches.
    Quand on créé un nouveau template, par exemple un template personnalité, le modèle est accessible depuis les attributs de la page (quand on créé une nouvelle page) mais pas depuis l’admin des personnalités. Il n’y a que l’ordre qu’on peut influencer.

    Avez vous une idée pour que le modèle soit accessible par là où qu’il soit directement sélectionné (peut être que vous l’avez expliquer mais je n’ai pas tout saisi)

    Merci d’avance

    • ben-wpSpirit

      Bonjour,

      Tu devrais créer un modele de page « page-fiche-personnages.php » par exemple comme expliqué dans cet article, tu repères cette portion de code :

      $args=array(
      'caller_get_posts'=>1,
      'post_type' => 'projet',
      'paged'=>$paged
      );

      et tu la remplace par :

      $args=array(
      'caller_get_posts'=>1,
      'post_type' => 'projet',
      'taxonomy' => 'prodcat', // le nom de ta taxonomy (fiche)
      'term' => 'term name', //le slug de ton terme (personnage)
      'paged'=>$paged
      );

      Le slug est en dessous du titre (minuscule sans espace).

      • Gorn

        je ne t’avais jamais remercié, mais merci bien pour tes instructions, tuto clair et aides personnalisées, c’est plutôt rare.
        Un grand merci à toi.

      • ben-wpSpirit

        Merci pour ton commentaire ! J’essaye au mieux malgré mon manque de temps à fournir à tous le plus d’aides personnalisés. A bientôt !

  4. McBright

    Bonjour,

    Bien qu’ayant respecter ce qui était écris (placer le code au dessus du premier, enlever les //), une erreur s’affiche quand je place le code « champ personnalisé ».

    Une idée d’où pourrait venir le problème ?

    Merci

  5. Lors de l’étape : Affichage des projets sur le site, j’ai un soucis apparemment il y aurai une erreur :)

    Apparemment une erreur de « syntaxe » que je ne trouve pas.

    Julie Franck.

    • ben-wpSpirit

      Bonsoir Julie pourrais tu m’indiquer cette erreur ?

      • 1,
        'post_type' => 'projet',
        'paged'=>$paged
        );
        $wp_query = new WP_Query($args);
        while ($wp_query->have_posts()) : $wp_query->the_post();
        $src = wp_get_attachment_image_src( get_post_thumbnail_id($post->ID)); */
        ?>

        Apparement on utilise plus : caller_get_posts mais ignore_sticky_posts

        De plus je pense que tu a une erreur ou niveau de ici :

        while ($wp_query->have_posts()) : $wp_query->the_post();

        J’en suis presque sur :)

        Tiens moi au courant, du coup je bloque sur ton tuto ^^

      • ben-wpSpirit

        Bonjour Julie,

        Je suis énormément occupé en ce moment beaucoup de boulot et pas de vacances donc je vais te demander plus d’infos :

        Je n’ai pas eu le temps de tester ce code sous WP 3.2 donc peux tu me confirmer que tu utilises bien cette version car j’ai utilisé ce code à de nombreuses reprises sans aucun soucis.
        As tu un problème au niveau du front office ou du back-office ?

        Si le problème est en front, pour l’affichage des projets, as tu un message d’erreur php ou rien ne s’affiche ?

  6. Bonjour, j’ai le même ‘soucis’ que Julie, ça m’affiche un Parse error: ‘syntax error, unexpected $end’ lorsque je souhaite utiliser le code de page-projets.php. Je suis bien sous 3.2

    Mais après avoir réfléchi 5 minutes, c’est juste que ta portion de code ne comprend pas le endwhile; de ta loop ().

    Bref, ça marche comme une rolex, merci bien ;)

  7. Bonjour,

    j’ai un petit soucis qui me reste encore. Tout le code fonctionne bien et j’arrive à créer catégories, nouvelle article…

    Mais lorsque je clic après l’avoir récupéré sur un des liens des articles créer avec ce dernier module et il ne me trouve pas la page.

    Pourtant j’ai bien crée la page single-apps.php (pour moi c’est pas projet mais apps).

    Qu’elle ligne défini le fichier qui affichera nos articles ? Rien à faire je ne trouve pas.

    D’avance merci de votre aide

  8. Désolé pour le double post.

    En fait mon fichier single-apps.php se charge bien mais à une condition. Mettre les permaliens par défaut exemple :

    http://localhost/?app=test-article

    Par contre si j’essaye avec des liens rewrite cela m’affiche une erreur 404.

    Après recherche sur google cela arrive souvent ce genre d’erreur.

    Auriez-vous une idée pour que la réécriture d’url (rewrite) fonctionne avec custom_post_type ?

    Encore merci

    • ben-wpSpirit

      Bonjour Alex,

      En effet il arrive souvent d’avoir des erreurs 404 avec les custom post type.

      As tu essayé la structure permalien sous cette forme : /%category%/%postname% ?

      As tu une page qui a pour slug(identifiant)le mot apps de la même forme que ton custom post type ? Cela peut provoquer des conflits ( voir ce post)

      Sinon le fait de travailler en local peut poser aussi des problèmes.

      Bon courage.

  9. Bonjour,

    je voudrais juste comprendre à quoi servent ces 2 lignes de codes dans page-projets.php : (pour le reste j’ai compris):

    $temp_query = $wp_query;
    $paged = (get_query_var(‘paged’)) ? get_query_var(‘paged’) : 1;

    Merci par avance !

    • ben-wpSpirit

      $temp_query = $wp_query; //on stock la requête dans une autre variable pour éviter les éventuelles conflits.

      $paged = (get_query_var(‘paged’)) ? get_query_var(‘paged’) : 1; //on récupère la valeur de la pagination (page 2-3-.. ?) si la variable est vide alors on attribut la valeur 1;

      • Mylène

        Merci pour ta réponse.

        J’ai une autre question : dès que j’active le fichier functions.php avec ton bout de code pour les CPT, mon admin plante et j’ai le droit à une page blanche…
        Que faire ?

      • ben-wpSpirit

        on parle bien du fichier functions.php de ton thème ?

        Il faut que tu vérifies si tu possèdes bien une version wordpress 3 ou supérieur, que les balises PHP sont bien refermées à chaque ouverture, pour les accolades aussi.

        Si cela ne résous pas ton problème envoi moi tes coordonnées email par ma page contact afin de m’envoyer ton fichier functions.php de ton thème.

  10. Mathieu

    Bonjour et merci pour ce super tuto.
    Il m’arrive un problème au niveau du fichier page-projet.

    J’affiche bien toute les projets que j’ai créés mais ils n’en finissent plus de ce dupliquer.(page de 3km de long)

    J’ai lu quelque commentaire plus haut que la boucle n’était pas terminé.
    Malheureusement pour moi, je ne vois pas ou la fermer.

    Merci d’avance pour ton aide.

  11. darkM

    après qq galère de boucles avec dupli à l’infini, c nikel ! thx :) ))

  12. bonjour ,je lis cette tuto ,mais j’ai un question :
    Est ce que je peut ajouter deux projet avec bien sur noms different sur le menu wordpress.
    par ce que lorsque que j’ajoute les deux projet ,il y a un probléme pour la fonction « admin-init »
    merci de me donnez une solution pour cette probléme

Trackbacks/Pingbacks

  1. Custom post type Wordpress 3 | Wordpress spirit - [...] Créer une nouvelle entité « Projets » avec les Custom Post Type : http://wordpress-spirit.com/tutoriels-wordpress/creer-une-nouvelle-entite-projets-avec-les-custom-po... [...]

Laisser un commentaire