Gestion d’événements avec l’extension ACF

Pour faire suite au très bon tutoriel de Lycia Diaz, je vous propose de découvrir une autre utilisation de l’extension ACF : une gestion simple d’événements. ça permettra de découvrir l’utilisation des dates et d’automatiser des comportements pour l’affichage.

Bien sûr de nombreuses extensions proposent ce genre de services mais elles sont parfois complexes à mettre en place, gourmandes en ressources et souvent payantes. De plus, ça peut être passionnant de composer des fonctionnalités soi-même pour maîtriser tous les éléments (y compris le visuel). Par la même occasion, on apprend des petites choses autour de la création-modification de thèmes.

Nous allons créer un petit gestionnaire qui permet de créer des événements avec des dates de début et de fin. En ‘front end’, nous afficherons les événements à venir, les événements en cours et les événements passés…

Création du post type ‘événement’

Tout d’abord, nous allons créer un post type ‘événement’ avec l’extension ‘Custom Post UI’ comme c’est très bien expliqué dans l’option 2 du tutoriel de Lycia Diaz:

3 façons d’utiliser Advanced Custom Fields pour WordPress


Nous allons juste ajouter un ‘icon’ spécifique. Pour la personne qui va publier sur le site, c’est toujours + sympa de personnaliser chaque post type avec une image. Vous pouvez choisir un ‘dashicon’ de WordPress. Il y en a assez pour que vous puissiez trouver celui qui vous convienne.

Dashicons


Ici, nous allons prendre ‘calendar-alt’ et nous allons l’indiquer dans le formulaire de création du post type.
formulaire_extension_cptui

back-office-wp-post-type-evenement

 

Création des champs

Par la suite, nous allons créer un groupe de champs ‘événements’. Encore une fois, pour la création des champs, je vous renvoie vers le tutoriel de Lycia.
Nous allons créer deux champs de type ‘date et heure’. Pour être original, le premier va s’appeler ‘Début’ et l’autre ‘Fin’ . Le choix du format de la date est important pour la suite et pour que notre gestion d’événements fonctionne correctement.
acf_plugin_backoffice
Et nous allons affilier notre groupe de champs au post type ‘événement’.
acf_plugin_backoffice

 

Création d’un template de page

Maintenant, nous allons travailler sur l’affichage de nos événements. Si vous travaillez sur un thème préexistant, il est nécessaire avant toute chose de créer un thème enfant. Je vous renvoie au tutoriel de Benoit H. pour savoir comment s’y prendre:

Créer un thème enfant pour WordPress


Pour afficher nos événements, le + simple est de créer une page personnalisée. Encore une fois, cet aspect est expliqué dans le tutoriel de Lycia Diaz. Dans votre thème enfant vous créez ‘page-events.php’ et dans la fonction ‘get_template_part()’, vous faites référence au fichier ‘content-events.php’.
Dans ‘content-event.php’, on va écrire quelques lignes de code pour gérer l’affichage des événements. Tout d’abord, vous ajoutez trois titres de niveau h2 avec les événements à venir, les événements en cours et les événements passés comme ceci:
vs_code_wp_template

 

Affichage des événements

Pour l’affichage des événements en fonction de leur temporalité, le principe est assez simple. Nous allons comparer les dates des événements ‘Début’ et ‘Fin’ avec le ‘datetime’ actuel. Et pour cela, la doc de ACF, nous aide beaucoup. Dans la section ‘Date Time Picker’, nous trouvons un ‘snippet’ qui permet d’afficher les événements en cours.

Date Picker


Il suffit de l’adapter et nous obtenons ce code à coller dans notre fichier ‘content-events.php’.

<?php
// date actuelle
$date_maintenant = date('Y-m-d H:i:s');

// événements en cours
// requêtes des événements en cours avec la fonction wp get_posts
$past_posts = get_posts(array(
  ‘posts_per_page’ => -1,
  ‘post_type’ => ‘evenement’,
  // comparaison des dates
  ‘meta_query’ => array(
    ‘relation’ => ‘AND’,
    array(
      ‘key’ => ‘debut’,
      ‘compare’ => ‘<=’,
      ‘value’ => $date_maintenant,
      ‘type’ => ‘DATETIME’
    ),
    array(
      ‘key’ => ‘fin’,
      ‘compare’ => ‘>=’,
      ‘value’ => $date_maintenant,
      ‘type’ => ‘DATETIME’
    )
  ),
  // ordre d’affichage
  ‘order’ => ‘ASC’,
  ‘orderby’ => ‘meta_value’,
  ‘meta_key’ => ‘debut’,
  ‘meta_type’ => ‘DATE’
));
if( $past_posts ): ?>
  <h2>Evenements en cours</h2>
  <ul id=”events”>
    <?php foreach( $past_posts as $p ): ?>
    <li>
      <h3><a href=”<?php the_permalink($p->ID); ?>”><?php echo $p->post_title; ?></h3></a>
      <?php echo $p->post_content; ?>
    </li>
   <?php endforeach; ?>
 </ul>
<?php endif; ?>

Quelques explications:

  • on instancie une variable ‘$date_maintenant’ avec la fonction date() de php et on indique le format dans les arguments.
  • pour filtrer les publications que nous voulons afficher (les événements en cours), nous utilisons la fonction ‘get_posts()’ avec plusieurs arguments
  • ‘posts_per_page’ => -1, ça permet d’indiquer que nous voulons afficher toutes les publications correspondantes
  • nous indiquons le post type, ici les ‘evenements’
  • Dans des ‘array’ nous indiquons qu’on doit afficher toutes les publications avec un champ ‘Début’ + grand ou égal à la date courante et en même temps avec un champ ‘Fin’ + petit ou égal à la date courante. C’est le cœur ici de notre filtre. Nous allons chercher dans la base de données les publications ‘événements’ qui correspondent à ces critères de temporalité.
  • Nous indiquons l’ordre d’affichage. Ici dans l’ordre chronologique des dates indiquées dans le champ ‘Début’.
  • Ensuite si des publications correspondent à notre filtre, nous faisons une boucle sur la variable ‘$posts’ et nous les affichons dans des balises html. Ici j’ai choisi d’afficher le titre de la publication dans une balise ‘<h3>’ et le contenu. On fait aussi un lien vers la publication avec la balise ‘<a>’ pour afficher l’événement que l’utilisateur-trice aura sélectionné. Nous verrons cet aspect + en détail dans un dernier chapitre.

Pour les événements à venir, on trouve un autre ‘snippet’. En l’adaptant, ça donne ceci:

//événements à venir
// requêtes des événements en cours avec la fonction wp get_posts
$upcoming_posts = get_posts(array(
  ‘posts_per_page’ => -1,
  ‘post_type’ => ‘event’,
  // comparaison des dates
  ‘meta_query’ => array(
    array(
     ‘key’ => ‘debut’,
     ‘compare’ => ‘>’,
     ‘value’ => $date_maintenant,
     ‘type’ => ‘DATETIME’
    )
  ),
  // ordre d’affichage
  ‘order’ => ‘ASC’,
  ‘orderby’ => ‘meta_value’,
  ‘meta_key’ => ‘debut’,
  ‘meta_type’ => ‘DATETIME’
));
if( $upcoming_posts ): ?>
  <h2>Evenements à venir</h2>
  <ul id=”events”>
  <?php foreach( $upcoming_posts as $p ): ?>
    <li>
      <h3><a href=”<?php the_permalink($p->ID); ?>”><?php echo $p->post_title; ?></h3></a>
      <?php echo $p->post_content; ?>
    </li>
  <?php endforeach; ?>
  </ul>
<?php endif; ?>

Ici on fait une simple comparaison: le champ ‘Début’ doit être strictement + grand que la date actuelle

Et pour les événements passés, c’est quasi la même chose sauf que la comparaison se porte sur le champ ‘Fin’ qui doit être + petit que la date actuelle.

Maintenant, nous pouvons nous rendre dans le back-office de WordPress et nous allons publier trois événements (passés, en cours et à venir). Un exemple:

wp_acf_example_fields_dates

et en front end avec nos exemples de publication, cela donne:

wp_list_events_frontend

Notre petit système fonctionne. L’administrateur-trice du site n’aura plus qu’à entrer deux dates pour chaque événement et l’affichage se fera automatiquement. Bien sûr, il faudrait faire un peu de la mise en page en changeant le html, en ajoutant un peu de CSS. Par exemple, on pourrait mettre en évidence les événements à venir. Il est conseillé aussi d’ajouter des images…Nous ne ferons pas de CSS dans ce tutoriel et il y a tellement de possibilités…

 

Affichage des dates

Bon c’est bien joli tout ça, mais il faut maintenant afficher les dates pour qu’on puisse voir quand commence et finit l’événement.

Avec ce bout de code qu’on trouve aussi dans la doc de ACF, ça fait le boulot.

<p>Debut de l’événement: <?php the_field(‘debut’, $p->ID); ?></p>
<p>Fin de l’événement: <?php the_field(‘fin’, $p->ID); ?></p>

Mais l’affichage des dates n’est pas top :/

wp_acf_display_date_frontend

Pour ça, j’ai créé ce petit bout de code que nous allons coller dans notre fichier ‘functions.php’

function display_french_date($date) {
  $dateformatstring_day = "l ";
  $dateformatstring_date = "d ";
  $dateformatstring_month = " F Y";
  $unixtimestamp = strtotime($date);
  echo date_i18n($dateformatstring_day, $unixtimestamp);
  echo intval(date_i18n($dateformatstring_date, $unixtimestamp));
  echo date_i18n($dateformatstring_month, $unixtimestamp);
}

Cette fonction est basée sur la fonction native de WordPress ‘date_i18n()’. Elle permet d’afficher les dates dans la langue sélectionnée dans le back-office à partir du ‘timestamp’. Vous trouvez toutes les infos autour de cette fonction ici:

https://codex.wordpress.org/date_i18n

Donc au final, on veut une jolie date en français genre “dimanche 28 juillet 2019”. Ainsi on va découper notre date en plusieurs formats: un pour le jour de la semaine, un pour le jour du mois et un pour le mois suivi de l’année. C’est pour ça que notre fonction effectue trois affichages différents.

On revient à notre fichier ‘content-events.php’ et on ajoute l’appel à la fonction ‘display_french_date()’ en ajoutant notre champ dans les arguments

<p>Debut de l’événement: <?php display_french_date(get_field(‘debut’, $p->ID)); ?></p>
<p>Fin de l’événement: <?php display_french_date(get_field(‘fin’, $p->ID)); ?></p>

Ici il est important d’apporter une précision: on utilise une autre fonction de ACF: ‘get_field()’ et non pas ‘the_field()’ comme précédemment. Quelle différence ? ‘the_field()’ affiche directement le champ dans notre template. ‘get_field()’ appelle le contenu du champ mais ne l’affiche pas. Et c’est pour ça que ici nous utilisons ‘get_field()’, nous voulons envoyer le contenu du champ dans le paramètre de la fonction, mais nous ne voulons pas l’afficher dans le template. Ce que nous voulons afficher c’est le résultat obtenu par la fonction ‘display_french_date()’.

et ça donne ceci:

wp_acf_display_dates_french

C’est déjà mieux mais maintenant il manque les heures. Pas de problèmes ! On va aussi les ajouter via une fonction. Celle-ci est beaucoup + simple que la précédente car nous n’avons pas besoin de traduire dans une langue. C’est surtout une question de mise en forme. Nous allons utiliser la fonction ‘date()’ de PHP. Par défaut, la fonction affiche la date du jour au format proposé dans les paramètres. Si nous ajoutons le ‘timestamp’ désiré comme deuxième paramètre, nous pouvons formater n’importe quelle date. Ainsi, nous avons la fonction suivante que nous pouvons coller dans ‘functions.php’:

function display_time($time) {
  echo date(“H:i”, strtotime($time));
}

et dans notre fichier ‘content-events.php’, nous avons maintenant:

<p>Debut de l’événement: <?php display_french_date(get_field(‘debut’, $p->ID)); ?> à <?php display_time(get_field(‘debut’, $p->ID)); ?></p>
<p>Fin de l’événement: <?php display_french_date(get_field(‘fin’, $p->ID)); ?> à <?php display_time(get_field(‘fin’, $p->ID)); ?></p>

et notre affichage maintenant:

wp_acf_display_date_and_time

Mais c’est pas fini pour l’affichage car on doit penser aux événements qui auront lieu sur une seule journée. Dans ce cas, on n’affichera pas de la même façon. Ainsi, nous allons poser une condition afin de savoir si la date du champ ‘Début’ est la même que le champ ‘Fin’. La difficulté ici est de comparer uniquement la date en ne tenant pas compte des heures. Et pour ça, nous devons utiliser une fonction qui ressemble à la précédente:

function get_date($date) {
  return date(“d m Y”, strtotime($date));
}

qu’on va bien sûr coller dans notre fichier ‘functions.php.

et voici le code dans notre fichier ‘content-event.php’:

if( $upcoming_posts ): ?>
  <h2>Evénements à venir</h2>
  <ul id=”events”>
    <?php foreach( $upcoming_posts as $p ): ?>
    <li>
      <h3><a href=”<?php the_permalink($p->ID); ?>”><?php echo $p->post_title; ?></h3></a>
      <?php echo $p->post_content; ?>
      <?php if(get_date(get_field(‘debut’, $p->ID)) === get_date(get_field(‘fin’, $p->ID))): ?>
      <p>Le <?php display_french_date(get_field(‘fin’, $p->ID));?> de <?php display_time(get_field(‘debut’, $p->ID)); ?> à <?php display_time(get_field(‘fin’, $p->ID)); ?></p>
<?php else: ?>
      <p>Debut de l’événement: <?php display_french_date(get_field(‘debut’, $p->ID)); ?> à <?php display_time(get_field(‘debut’, $p->ID)); ?></p>
      <p>Fin de l’événement: <?php display_french_date(get_field(‘fin’, $p->ID)); ?> à <?php display_time(get_field(‘fin’, $p->ID)); ?></p>
<?php endif; ?>
    </li>
<?php endforeach; ?>
  </ul>
<?php endif; ?>

Ici on compare les dates de notre événement avec la fonction ‘get_date()’. Si c’est équivalent nous affichons uniquement “le …de…à…” et si elles sont différentes, on affiche comme précédemment, ce qui donne:

wp_acf_display_date

Affichage d’un événement sélectionné

Auparavant, nous avons vu comment afficher une liste d’événements et les ordonner selon leurs dates. L’utilisateur-trice voudra probablement cliquer sur un événement pour aller lire dans les détails le contenu de la publication. Mais pour l’instant, si nous cliquons sur un événement, nous obtenons ceci:

single_event

C’est pas génial, car nous avons la date de publication de l’événement et la date de l’événement qui nous intéresse ici est absente. Dans mon thème (‘twentynineteen’), il y a un fichier single.php et c’est celui-ci que WordPress va utiliser pour afficher mon événement sur lequel j’ai cliqué (voir la hiérarchie des templates WordPress).

Dans notre thème, il va falloir créer un fichier ‘single.php’ particulier pour nos événements et ce fichier va porter le nom: ‘single-le_nom_de_votre_post_type_slug.php’ donc ici ‘single-evenement.php’. Nous allons copier notre fichier ‘single.php’ du thème parent et le copier dans notre thème enfant et le renommer.

Dans ce fichier, nous faisons appel à un autre fichier avec la fontion ‘get_template_part()’. Donc comme pour la création de ‘page-evenement.php’, on va créer un fichier ‘content-event.php’ (ici au singulier du coup). ça se présente comme ceci:

templates_wordpress

Maintenant, nous sommes libre de modifier l’affichage dans ce nouveau template. En premier, j’aimerais par exemple retirer les métas données de la publication. Car elles contiennent la date de publication et j’estime que mes visiteur-se-s n’auront pas besoin de ces informations.

Dans notre fichier ‘content-event.php’, nous pouvons retirer l’appel du fichier ‘entry-header.php’ (qui contient les métas données) et juste afficher le titre de la publication comme ceci:

modif_template_wordpress

et dans ce header de la publication, on peut ajouter nos lignes de code pour l’affichage des dates:

vs_code_display_dates

et cela donne ceci:

display_date_frontend

 

Voilà notre petit système de gestion d’événements est opérationnel. Maintenant, le chantier est ouvert et il reste beaucoup d’aspects à penser et mettre en place. En premier, vous devez créer un visuel et une interface qui soit raccord avec le reste de votre site. A partir de là, on pourrait imaginer d’afficher le prochain événement sur la page d’accueil, on pourrait afficher les événements par semaine ou pourquoi pas créer un moteur de recherche par date…

Amusez-vous et expérimentez ;-)

 

wpformation
NE MANQUEZ PLUS RIEN !
Inscrivez-vous pour recevoir le meilleur de WordPress dans votre boîte de réception, chaque mois.

Nous ne spammons pas ! Consultez notre politique de confidentialité pour plus d’informations.

A propos de l'auteur...

Avatar de Cyril BRON

Cyril BRON

Formateur média-vidéo dans une Haute Ecole à Genève et développeur web indépendant, j'utilise WordPress au quotidien. Je pratique beaucoup la veille technologique; j'aime découvrir, expérimenter et partager. Je me déplace souvent en Europe avec mon ordinateur, j'occupe mon temps entre exploration, prises de vue, traitement d’images et lignes de code...