Créer un formulaire en front end avec ACF

Advanced Custom Field est un plugin vraiment utile pour bâtir des sites complexes: on peut rajouter autant de nouveaux champs que souhaité dans un article, une page, un custom post type: dans la page d’édition d’un article ou d’une page, au traditionnel champs de texte qui représente « the_content() » dans le code, on peut rajouter d’autres champs texte, des uploader de média, qui se retrouveront dans le front end et donneront à vos pages un aperçu bien plus « professionnel ».

Aujourd’hui on va se servir de ACF pour créer et afficher un formulaire de soumission d’article en front end. Un peu comme le fait l’excellent plugin User Submitted post.

Pourquoi utiliser ACF?

Prenons un exemple concret.Par exemple, On souhaite réaliser un site de recettes de cuisine.Dans la page d’édition d’un article on retrouve donc logiquement l’éditeur par défaut de wordpress, à l’intérieur duquel on va organiser notre texte de la manière suivante:

« Ingrédients:…. »

« Préparation:…. »

« Temps de cuisson :… » etc etc..

Pour chaque recette, on voudra respecter cet agencement donc il faudra à chaque fois penser à organiser son texte de la même manière à l’intérieur de l’éditeur de texte.

C’est là qu’ACF prend toute son utilité.

Créer des champs additionnels avec ACF

Avec le plugin, on va pouvoir créer nos champs additionnels (« Ingrédients », « Préparation », « temps de cuisson » etc..) dans la page d’édition et on aura plus qu’à fournir du contenu directement dans chacun de ces champs.

On télécharge ACF sur cette page

Une fois installé, on se rend dans l’onglet du plugin en backoffice, et on crée un groupe de champs, en cliquant sur Add New.

acf1

On donne un titre à notre groupe, ici par exemple, « recette ».Dans ce groupe recette, je vais rajouter tout un tas de nouveau champs, comme ici:

acf-2

A la création de chacun de ces champs, ACF nous permet de choisir le type de champs : la plupart des champs seront ici des champs de type texte.

acf4

Saut pour l’image, je choisis un champ de type image.

acf5

Et comme type « image Object »:

acf6

Ensuite, ACF me permet de choisir le type de page ou d’article sur lequel je souhaite afficher ces champs.Ici, ça sera sur la page d’un article, c’est à dire en l’occurrence, une recette.

acf3

Les champs additionnels en backoffice

Tout en bas de la page de création des « custom field« , ACF nous offre la possibilité de supprimer certains éléments de la page d’édition, comme ici:

acf7

Ici je choisis donc de supprimer l’éditeur par défaut (« content Editor »).De cette manière, si je regarde une page d’édition d’article, je retrouve donc tous mes champs, et l’éditeur a bien disparu.C’est désormais beaucoup plus simple pour moi de remplir chacun de ces champs pour créer des recettes.

acf8

Afficher ses custom fields en front end

Un peu de code.Maintenant, dans notre fichier single.php, censé afficher les contenus de nos recettes, je vais devoir appeler tous mes champs grâce aux fonctions de ACF

Voici un exemple de page single.php ou j’appelle mes différents champs, avec la condition pour n’afficher les champs que s’ils ont été renseignés (sinon on se retrouverait avec des cases vides)

       <div class="meta">

<?php if( get_field('Ingredients') ): ?>
<p> <span class="glyphicon glyphicon-list-alt"></span> <strong>Ingredients</strong> :<?php the_field('Ingredients'); ?></p>
<?php endif; ?>


<?php if( get_field('Preparation') ): ?>
<p> <span class="glyphicon glyphicon-list-alt"></span> <strong>Preparation</strong> :<?php the_field('Preparation'); ?></p>
<?php endif; ?>

<?php if( get_field('Cuisson') ): ?>
<p><span class="glyphicon glyphicon-fire"></span> <strong>Cuisson</strong>:<?php the_field('Cuisson'); ?></p>
<?php endif; ?>

<?php if( get_field('Difficulté') ): ?>
<p> <span class="glyphicon glyphicon-signal"></span> <strong>Difficulte</strong>:<?php the_field('Difficulté'); ?></p>
<?php endif; ?>

<?php if( get_field('Temps') ): ?>
<p><span class="glyphicon glyphicon-time"></span><strong>Temps</strong>:<?php the_field('Temps'); ?></p>
<?php endif; ?>

</div>

Ici pour la forme je rajoute des glyphicon bootstrap. En front end, je me retrouve donc bien avec tous mes champs.

acf9

A chacun après de styliser sa page comme on l’entend.

Laisser l’utilisateur poster un article

Maintenant qu’on a commencé à utiliser ACF, il serait mal venu d’utiliser un autre plugin pour afficher un formulaire de soumission d’article. Les plugins de soumission d’article comme User Submitted Post en général ne contiennent qu’un éditeur classique.Or ici on réalise un site particulier, et on a supprimé l’éditeur de texte par défaut pour le remplacer par nos  « custom fields« . A partir du moment ou l’on utilise des customs fields pour afficher du contenu, plutôt qu’avec l »éditeur par défaut (défini par the_content() dans le code )  on n’a pas d’autres choix que d’utiliser ACF ou de coder soi-même un formulaire sur mesure pour restituer nos données.

Première étape: création d’un template de page

Dans le dossier de mon thème, je crée donc une nouvelle page que j’appelle usersubmit.php

Voici le code en entier de la page : acf_form_head() va nous permettre d’enregistrer et d’envoyer nos données saisies en base. acf_form($options) va afficher le formulaire

En option j’indique que c’est pour créer un « new » post, je spécifie le groupe de champ concerné en ciblant son ID (que je retrouve en survolant avec la souris le nom du groupe de champ dans l’onglet custom fields), je précise le type de post : « draft » pour brouillon ou « pending » pour les laisser en attente de modération dans le backoffice. Ici je place mes différents champs que l’utilisateur devra remplir, et je peux supprimer la fonction « the_content() » devenue inutile.

<?php /*Template Name: User Submit*/;?>
<?php acf_form_head(); ?>
<?php get_header(); ?>

<div id="container" >

<div class="row">
<div class="col-sm-12">

<?php /* The loop */ ?>
<?php while ( have_posts() ) : the_post(); ?>

<h1><?php the_title(); ?></h1>
<!-- a supprimer si on enlève l'éditeur par défaut -->
<?php the_content(); ?>
<!------------>
<p> <?php the_field('Ingredients'); ?></p>
<p> <?php the_field('Preparation'); ?></p>
<p> <?php the_field('Cuisson'); ?></p>
<p> <?php the_field('Temps'); ?></p>
<p> <?php the_field('Difficulté'); ?></p>
<?php $options = array('post_id' => 'new',
'field_groups' => array(735),
'post_title' => true,


'post_type' => 'post',
'post_status' => 'draft',

'updated_message' => 'Merci pour votre participation!Votre recette sera publiée prochainement',
'submit_value' => 'Postez votre recette'
);
acf_form($options);?>

<?php endwhile; ?>
</div>
</div><!-- #content -->
</div><!-- #primary -->

<?php get_footer(); ?>

Dans le backoffice, je crée aussi ma page « Postez votre recette », et je lui donne comme modèle de page, userSubmit

acf10

Normalement, on n’a pas besoin de rajouter une condition dans notre groupe de champ pour dire Show this field group if « page template » is equal to « userSubmit » (le nom de votre template) .La page étant liée à notre fichier php, elle affiche déjà bien en front notre nouveau formulaire, contenant tous nos champs.On n’a pas besoin de les afficher dans le template de page en backoffice

Si je me rend en front end, sur ma nouvelle page « Postez une recette » j’ai bien mon formulaire avec tous mes champs qui s’affichent.

acf11

Comme on le voit ici, j’ai rajouté un champ titre.L’idée est fournir à  l’utilisateur la possibilité de renseigner lui même le titre de sa recette, sans que j’ai à le réécrire en backoffice.

L’enregistrement des données

Dans notre fichier functions.php, on va donc rajouter un filtre (add_filter(‘acf/pre_save_post’… ) pour enregistrer le tout, et faire en sorte que le champs titre devienne par défaut le titre de ma nouvelle recette.


function my_pre_save_post( $post_id ) {

// check if this is to be a new post
if( $post_id != 'new' )
{
return $post_id;
}

// Create a new post
$post = array(
'post_status' => 'pending',
'post_title' => $_POST['fields']['field_58416c03647e0'],
'post_type' => 'post',
);

// insert the post
$post_id = wp_insert_post( $post );

// update $_POST['return']
$_POST['return'] = add_query_arg( array('post_id' => $post_id), $_POST['return'] );

// return the new ID
return $post_id;
}

add_filter('acf/pre_save_post' , 'my_pre_save_post' );

Ici pour enregistrer mon titre en tant que « post_title », je cible la meta key de mon champ titre  ‘post_title’    => $_POST[‘fields’][‘field_58416c03647e0’].
Dans la version pro, le code est différent.($_POST[‘acf’][‘field_58416c03647e0’] )

Pour info: Je peux retrouver l’id de chacun de mes champ, dans l’onglet custom field  du backoffice, en déroulant l' »option screen » dans la page de mon groupe de champ et en cochant la case »Show Field key »–>Yes

acf12

Maintenant, le texte renseigné en front, dans le champ « titre », apparaît bien comme titre du nouvel article en backoffice. C’est donc l’utilisateur lui même qui indique le titre de sa recette!

Afficher l’image à la une

Maintenant, on veut en plus que l’image que l’utilisateur uploade soit l’image à la une de la nouvelle recette

Toujours en functions.php, à la suite du code précédent, on rajoute une nouvelle fonction

function acf_set_featured_image( $value, $post_id, $field  ){

if($value != 'field_583ab680bb00b'){
//Add the value which is the image ID to the _thumbnail_id meta data for the current post
add_post_meta($post_id, '_thumbnail_id', $value);
}

return $value;
}

// acf/update_value/name={$field_name} - filter for a specific field based on it's name
add_filter('acf/update_value/name=votre_image', 'acf_set_featured_image', 10, 3);

Mon champ s’appelle « votre_image« , et il a comme field key, field_583ab680bb00b.

Je renseigne donc les bonnes valeurs au bon endroit, et normalement l’image que l’utilisateur uploade s’affiche désormais comme image à la une de l’article.

Comme dans le fichier single.php je n’appelle pas mon champ « votre_image« , je peux utiliser le code classique de wordpress « the_thumbnail() » pour afficher l’image à la une, sans qu’il y ai de doublon.

En tant qu’administrateur je n’ai donc plus qu’à approuver ou non l’article, sans rien toucher d’autre!! Et voili, on a un formulaire qui fonctionne!!