Aller plus loin avec les Custom Fields (Champs Personnalisés) de Joomla! 3.7

Le présent article tente de compiler un maximum d'informations sur les Custom Fields (Champs Personnalisés) introduits dans Joomla! 3.7, qui ouvrent beaucoup de perspectives.

Il complète utilement l'article de présentation générale des Custom Fields (traduction de l'article de Sander Potjer publié dans le Webdesigner Magazine NL #94), disponible dans ce même numéro du Cinnk Magazine.

Il se veut aussi complet que possible, avec même parfois des sources dans différentes langues.

Le sujet est neuf et nombreux sont les articles et extensions qui continuent à sortir. Aussi, n'hésitez pas à partager vos découvertes dans les commentaires ci-dessus ou en me contactant directement.

joomla custom field

Les ressources générales

Commençons par le début : le site officiel de la Documentation Joomla

Article de survol (FR)

Articles de survol (EN)

"How to Add Custom Fields to Joomla! Contact Forms" (EN)

"Custom Fields in Joomla! 3.7" (DE)

Pour mémoire, avant l'introduction des Custom Fields, il était bien sûr déjà possible pour un "développeur" de créer "manuellement" des champs :

Les Custom Fields présentés lors de conférences

JoomlaDay DE (22-23/09/2017)

Joomladay UK (08/07/2017 - EN)

J&Beyond (02-04/06/2017 - EN)

JoomlaDay Marseille (12-13/05/2017 - FR)

JoomlaDay Austria (02-03/12/2016 - EN)

JoomlaDay Germany (16-17/09/2016)

Les plugins de Custom Fields

Comme on s'en aperçoit rapidement en survolant les ressources ci-dessus, les Custom Fields ouvrent… le champ des possibles.

En natif, Joomla! embarque une quinzaine de types de champs différents.

Techniquement, il s'agit de plugins. On peut donc désactiver un type de champ simplement en désactivant le plugin correspondant (filtrer les plugins sur le type "fields" pour directement voir tous les types disponibles).

Et puisque les types de champs sont des plugins, cela signifie aussi qu'il est facile d'en ajouter sur un site. De nombreux nouveaux types vont encore apparaître… et sont déjà apparus (parfois ils sont gratuits, parfois payants). Voici ceux déjà disponibles :

Par Allon Moritz de Digital Peaks (gratuit)

Plusieurs plugins de champs complémentaires sont disponibles dans les sous-dossiers ici :
https://github.com/Digital-Peak/DPFields

Par Elisa Foltyn (gratuit)

Par Tassos Marinos (version gratuite et version payante àpd € 19)

https://www.tassos.gr/joomla-extensions/advanced-custom-fields

  • YouTube Field
  • Google Maps Field
  • Vimeo Field
  • DailyMotion Field
  • SoundCloud Field
  • True/False Field
  • Timepicker Field
  • Currency Field
  • Country Field
  • Module Field (Pro)

Par Joomill

(version gratuite et version payante à € 10. Voir les différences sur https://www.joomill-extensions.com/extensions/custom-fields-vimeo-plugin/compare)

Par le JUG Nuremberg

Par Nordmograph (payant € 14)

Par EasyLayouts (payant, dans le cadre de l'extension EasyLayouts)

https://www.easylayouts.net/

  • Related Article
  • Managed Location (en lien avec JEvents)

Par Lomart

  • Lightbox
    Sur le forum, Lomart a posté un exemple de plugin qu'on peut développer soi-même pour gérer une demande particulière (dans le cas d'espèce, un lien lightbox sur une image)
    https://forum.joomla.fr/showthread.php?220731 

Par Christian Hent

Par JoomlaXTC

Par Sergio Iglesias

Par Brian Teeman

  • Last but not least, Brian Teeman a mis à disposition un plugin de Custom Field "vierge"
    https://github.com/brianteeman/joomla-extra-fields/tree/master/plugins/fields/blank
  • Mais en outre, beaucoup de propositions de plugins sont rassemblées 
    https://github.com/brianteeman/joomla-extra-fields
     
    • Certains sont déjà réalisés
      • Autocomplete address algolia
      • Lightbox
      • Youtube
    • D'autres sont sur la liste des suggestions (participez si vous pouvez !)
      • Country/state
      • Hebrew calendar
      • Workflow
      • Download zip
      • Google map
      • Time
      • Gravatar
      • Money
      • Content sharing - tweetable links
      • Galleries/slideshow
      • Charts, graphs and pies
      • PDF/doc base work done but cant progress because of core bug
      • Related articles (select article)
      • Advert/banner (select banner)
      • See also (select menu)
      • Contact for more info (select contact)
      • Include module (select module)
      • E-commerce product link
      • Buy now
      • External database

Les Template Overrides et les Alternate Layouts en général

Lorsqu'on crée des Custom Fields, on peut les faire afficher de plusieurs manières :

  1. automatiquement, p.ex. avant/après le contenu de l'article
  2. manuellement n'importe où dans un article grâce à la syntaxe
    {field ID}
    où ID est l'identifiant du champ, p.ex. 1
  3. mais si on veut aller plus loin, on peut aussi utiliser les Overrides (ou les Alternate Layouts, lesquels sont des également surcharges mais qui sont appliquées à la demande et pas d'office)

Même si vous n'avez jamais réalisé d'Override ou d'Alternate Layout, vous allez découvrir que cela est finalement assez facile et cela va vous permettre de tirer le plein potentiel des Custom Fields au niveau de la présentation de votre site.

Pour cette raison, nous compilons ci-dessous une série de ressources intéressantes pour faire le tour de la question.

JoomlaDay Paris 2016

Yann Gomerio et Cédric Keiflin avaient fait une excellente présentation sur les “surcharges et les layouts alternatifs”

JoomlaDay Netherlands 2017

Par Hans Kuijpers, sur une présentation d'Elisa Foltyn

OSTraining

Livres

Les Overrides dans le cadre des Custom Fields

Maintenant que le décor est planté, on peut voir comment concrètement réaliser un Override dans le cadre des Custom Fields.

Documentation officielle

En particulier, la présentation d'Elisa Foltyn (#jd17nl) évoque spécifiquement le cas des Custom Fields à partir du slide 37 (NB : c'était juste avant la sortie officielle des Custom Fields et certains exemples de code doivent entre-temps être adaptés, cfr infra)

Je profite d'ailleurs de l'occasion pour remercier ici Elisa Foltyn avec qui j'ai pu échanger directement au sujet de l'utilisation des Custom Fields dans les Overrides et qui m'a permis de compléter de manière substantielle ce dossier sur une série de points.

NB : vous aviez testé les Custom Fields dans des Overrides avant la sortie officielle (p.ex. dans les Release Candidates), sachez p.ex. que "fields" a été rebaptisé "jcfields" au moment. Exemple :

$this->item>fields est devenu $this->item>jcfields

Les Overrides dans le cadre des Custom Fields - concrètement

Comment afficher tous les champs à un endroit donné via une boucle

Override en utilisant le FieldsHelper :

<?php foreach ($this->item->jcfields as $field) : ?>
   <?php echo FieldsHelper::render($field->context, 'field.render', array('field' => $field)); ?><br />
<?php endforeach ?>

Raw override (brut, sans mise en forme) :

<?php foreach ($this->item->jcfields as $field) : ?>
   <?php echo $field->label . ':' . $field->value; ?><br />
<?php endforeach ?>

Comment afficher un seul champ

Par exemple, le champ ayant l'ID 9 :

Ingrédients : <?php echo $this->item->jcfields[9]->value; ?>

Encore mieux : d'abord vérifier si le champ est existe pour l'article (ou le contact, …)

<?php if (isset($this->item->jcfields[9])): ?>
   <?php echo $this->item->jcfields[9]->value; ?>
<?php endif; ?>

Comment afficher le bloc de tous les champs

<?php echo FieldsHelper::render('com_content.article', 'fields.render', array('item' => $this->item, 'context' => 'com_content.article')); ?>

Comment utiliser les Noms (alias) dans les Overrides

Au quotidien, pour une meilleure lisibilité du code, on peut préférer utiliser les Noms des Custom Fields plutôt que leur ID (attention cependant à la cohérence si vous changez en cours de route le Nom de certains champs)

Dans votre Override, il suffit d'ajouter la correspondance entre ID et Noms comme suit…

<?php
   $customFields = $this->item->jcfields;
   foreach ($customFields as $customField){
      $customFields[$customField->name] = $customField;
   }
?>

… et dans la suite du code, vous pourrez alors écrire simplement

Ingrédients : <?php echo $customFields['mes-ingredients']->value; ?>

Déboguer dans un Override

Quand on est occupé dans un (Template ou Layout) Override et que l'on souhaite déboguer, il peut être pratique d'afficher tous le détail concernant un champ donné.

Dans ce cas, on peut utiser une des deux lignes suivantes, dans le cas d'un champ ayant l'ID 9 (NB : la balise "preformatted" permet d'afficher le tout de manière plus lisible)

<pre><?php var_dump($this->item->jcfields[9]); ?></pre>
<pre><?php print_r($this->item->jcfields[9]); ?></pre>

Poser des conditions sur le type de champ

Avec quelques connaissances, on peut rapidement aller plus loin dans la personnalisation, comme par exemple ici on où met une condition sur le type de champ (pour le champ ayant l'ID 1)

<?php
// Affiche seulement si le Type du Champ est Text
 if ($this->item->jcfields[1]->type === 'text') {
 echo '<h1>This is a text field.</h1>';
 }
?>

Créer un Custom Field de type SQL permettant de sélectionner un ou plusieurs articles (et les transformer en liens)

Pour ce faire, créons tout d'abord un Custom Field de type SQL, avec la requête suivante (qui va afficher tous les articles du site d'une catégorie donnée, triés par ordre alphabétique)

select id as value, title as text from #__content WHERE state = 1 and catid = 10 ORDER BY title ASC

Dans l'exemple présent, je donne au champ comme Nom articles-lies et j'autorise même les sélections multiples.

Sur le site, je souhaite que tous les articles sélectionnés se transforment en hyperlien vers ces articles. Pour réaliser cela facilement (càd sans même savoir coder), je peux p.ex. utiliser l'extension Articles Anywhere de Regular Labs (NB : la version Pro permet d'insérer plusieurs articles, la version Free permet d'insérer un seul article à la fois)

Dans mon Override, je vais alors insérer le code suivant :

{articles <?php echo str_replace(', ', ',', $customFields['articles-lies']->value); ?>}[link][title][/link]<br />{/articles}

NB : par défaut, en cas de sélection multiple, il y a un espace après la virgule qui sépare les différentes valeurs. Nous supprimons cet espace avec la fonction str_replace afin de supprimer cet espace et respecter la syntaxe de Articles Anywhere.

Lien vers un seul article et sans utilisation d'une extension

Si on souhaite seulement faire un lien vers un seul article et qu'on ne souhaite pas utiliser d'extension, on peut p.ex. simplement créer un champ SQL, qui permette de choisir l'ID de l'article à lier, puis d'utiliser le code suivant :

<?php echo Jhtml::_('link', 'index.php?option=com_content&amp;view=article&amp;id=' . $customFields['my_article_id']->value, $customFields['my_article_id']->text); ?>

Ou encore mieux, tester un code tel que celui-ci qui génèrera des urls plus SEO-friendly :

$article->slug = $article->id . ':' . $article->alias;
$articlelink="<a href='".JRoute::_(ContentHelperRoute::getArticleRoute($article->slug, $article->catid, $article->language))."'". " title='".htmlspecialchars($article->title)."' >".$article->title."</a>";
echo $articlelink;

Render Class

Pour chaque champ, il est possible de spécifier une classe de rendu ("Render class").

A l'usage, on remarque cependant que sur le front-end cette classe de rendu n'est fonctionnelle que lorsqu'on affiche les champs en bloc p.ex. avant/après le contenu.

Autrement dit, cette classe de rendu est inactive

  1. si on affiche un champ au sein d'un article via le shortcode
    {field 1}
  2. si on affiche un champ via un Override

NB : s'il s'agit d'un bug et non d'un "feature", ceci devrait être corrigé lors d'une mise à jour future

Où est défini le layout pour un champ (field) ou pour le groupe des champs (fields)

Pour générer le rendu d'un champ donné, Joomla! utilise le fichier

/components/com_fields/layouts/field/render.php

La dernière ligne de ce fichier indique

<span class="field-value"><?php echo $value; ?></span>

 

Autrement dit, on affiche la valeur du champ, dans une balise span ayant la classe field-value.

De manière similaire, pour générer le rendu de le groupe des champs (p.ex. lorsqu'ils sont tous affichés avant/après le contenu), Joomla! utilise le fichier

/components/com_fields/layouts/fields

 

On note au passage la présence des deux lignes suivantes qui concernent la render_classs :

<?php $class = $field->params->get('render_class'); ?>
<dd class="field-entry <?php echo $class; ?>">

 

Ceci explique donc pourquoi la "Render Class" que l'on peut assigner à chaque champ ne joue que lorsqu'on affiche tous les champs en bloc p.ex. avant/après le contenu… (cfr point précédent)

Override pour le layout pour un champ (field) ou pour le groupe des champs (fields)

Imaginons que l'on souhaite créer un Override pour le rendu des champs.

On duplique alors simplement le fichier render.php évoqué ci-dessous, que l'on place au choix dans

/templates/MY_TEMPLATE/html/layouts/com_fields/field
/templates/MY_TEMPLATE/html/layouts/com_content/field

pour le rendu de champ

 

/templates/MY_TEMPLATE/html/layouts/com_fields/fields
/templates/MY_TEMPLATE/html/layouts/com_content/fields

pour le rendu du bloc des champs

 

Changez alors p.ex. la ligne

<span class="field-value"><?php echo $value; ?></span>

par

<span class="field-value btn btn-primary"><?php echo $value; ?></span>

et vous constaterez (si votre template utilise Bootstrap) que votre champ sera affiché sous la forme d'un bouton de la couleur primaire du site.

Alternate layout pour le layout pour un champ (field) ou pour le groupe des champs (fields)

L'Override est certes sympathique, mais il s'applique par définition à tous les champs.

Or, dans certains cas, on voudrait qu'il ne s'applique que pour certains champs.

C'est ce qu'on appelle l'Alternate Layout (layout alternatif).

 

La procédure est la même que celle expliquée ci-dessus pour l'Override, mais on renomme le fichier comme on le souhaite (et non plus render.php, qui est le nom d'origine).

Prenons comme exemple

/templates/MY_TEMPLATE/html/layouts/com_fields/field/joomladay.php
/templates/MY_TEMPLATE/html/layouts/com_content/field/jug.php

où joomladay et jug sont bien entendu des noms arbitraires que j'ai choisis de donner à mes layouts personnalisés.

Utiliser un Alternate Layout au sein d'un article

Comme déjà vu, pour insérer au sein d'un article le champ ayant l'ID 1, il suffit d'insérer le shortcode suivant :

{field 1}

Si on veut que le rendu soit différent, on va pouvoir utiliser nos Alternate Layouts comme suit :

{field 1, joomladay}
{field 1, jug}

Utiliser un Alternate Layout dans un Override d'article

On se souvient que dans un Override, on peut appeler le champ 1 comme suit :

<?php if (isset($this->item->jcfields[1])): ?>
   <?php echo FieldsHelper::render('com_content.article', 'field.render', array('field' => $this->item->jcfields[1])); ?>
<?php endif; ?>

 

Pour utiliser un de mes Alternate Layouts, il suffit que je remplace render par le nom de mon Alternate Layout (dans mon cas, joomladay ou jug) :

<?php if (isset($this->item->jcfields[1])): ?>
   <?php echo FieldsHelper::render('com_content.article', 'field.joomladay', array('field' => $this->item->jcfields[1])); ?>
<?php endif; ?>

 

Si en outre j'ai fait en sorte de pouvoir utiliser les Noms plutôt que les IDs, je peux réécrire ce code comme suit :

<?php if (isset($customFields['mes-ingredients'])): ?>
   <?php echo FieldsHelper::render('com_content.article', 'field.joomladay, array('field' => $customFields['mes-ingredients'])); ?>
<?php endif; ?>

Mettre en forme les champs pour qu'ils soient alignés

Si j'affiche mes champs en bloc p.ex. avant/après le contenu et que je souhaite aligner les valeurs des champs quelle que soit la longueur des différents libellés, je peux simplement utiliser un peu de CSS. Exemple de solution rapide exploitant Flexbox, donnant à tous les libellés la même largeur et en les alignant à droite :

dd.field-entry {
   display: flex;
}
span.field-label {
   flex-basis: 200px;
   text-align: right;
   margin-right: 10px;
}

Insérer les Custom Fields via un query plutôt qu'en éditant dans l'Administration

Si on a de nombreux Custom Fields à introduire, on pourrait vouloir le faire via un query plutôt qu'en éditant les articles à la main dans l'Administration.

Voici un simple exemple de query

INSERT INTO `#_fields_values` (`field_id`, `context`, `item_id`, `value`) VALUES
(1, 'com_content.article', '11', 'cats'),
(2, 'com_content.article', '11', 'food');

où on remplace # par le préfixe de la table (si on lance la requête depuis PHPMyAdmin p.ex.) et où la 1e variable les l'ID du champ et la 3e variable l'ID de l'article.

Les autres extensions liées au Custom Fields

Custom Fields CK par Cédric Keiflin

Permet de personnaliser très facilement la mise en forme des Custom Fields (€ 14)

EasyLayouts, par les auteurs de JEvents

Permet de gérer de manière visuelle les layouts sans devoir faire soi-même les Overrides et Alternate Layouts (àpd £ 30.25)

Documentation

Nouvelles fonctionnalités prévues bientôt (en date du 08/07/2017 - présentation JD17UK, cfr supra)

  • Conditional Field Display
  • Filter Module
  • Customisable Edit Pages by Type
  • More Custom Fields types and output options
  • Language specific Layouts

Filtres

  • EasyLayouts devrait prochainement intégrer une possibilité de filtres (à suivre)
  • Joomlart propose MegaFilter qui intègre déjà les Custom Fields ($ 35) - cfr infra

Joomlart MegaFilter plus en détail

Sur la démo, Joomlart MegaFilter a l'air sympathique, mais dans la pratique, sa prise en main n'est pas si intuitive que ça. Pour cette raison, je partage ici une série d'astuces qui vous permettront de gagner du temps, leur documentation étant loin d'être complète et leur support n'étant pas toujours super réactif.

Comment supprimer les mentions "hits" et "rating" dans la vue "Filtre"

Dans la vue "Filtre", apparaît sur le "résumé" de chaque article le nombre de vues ("hits") et les votes ("rating").

Pour effacer ces hits & ratings, faire un Override de

/plugins/jamegafilter/content/layouts/default/product-item.php

en le dupliquant dans

/templates/YOUR_TEMPLATE/html/layouts/jamegafilter/content/default/product-item.php

Effacer ensuite les lignes suivantes

<div class="product-reviews-summary short">
     <div class="rating-summary">
         {?rating}
         <div title="{rating} out of 5" class="rating-result">
  <span style="width:{width_rating}%"></span>
         </div>
         {:else}
         <div title="0%" class="rating-result">
  <span style="width:0%"></span>
         </div>
         {/rating}
     </div>
 </div>
 <div class="product-reviews-summary short">
     <div class="hits-summary">
         {?hit}
  <span class="file-downloads"><?php echo JText::_('COM_JAMEGAFILTER_HIT');?> : {hit}</span>
         {:else}
  <span class="file-downloads"><?php echo JText::_('COM_JAMEGAFILTER_HITS');?> : {hits}</span>
         {/hit}
     </div>
 </div>

NB : c'est dans ce fichier que l'on voit le nom de la chaîne de caractère correspondant au bouton "View detail". Il s'agit de COM_JAMEGAFILTER_VIEW_DETAIL, pour lequel on pourra utilement donner une traduction française.

Comment changer le nombre de caractères de l'introduction

1e étape : changer la valeur par défaut (100)

Editer (ou mieux : faire un Override)

/plugins/jamegafilter/content/helper.php

et changer la valeur de 100 dans le code suivant :

$item->desc = !empty($baseItem->introtext) ? strip_tags(substr($baseItem->introtext,0,100)).'...' : '';

 

2e étape : réindexer manuellement (via le menu Composant > MegaFilter)

 

3e étape : vider le cache navigateur (si nécessaire)

Fonctionnement de l'indexation

Visiblement, la réindexation ne se fait pas "en live" mais demande une intervention manuelle après chaque édition d'article concerné.

Pourquoi une indexation ? Sans doute parce que le résultat de la page "Filtre" ne se fait pas en interrogeant directement la base de données (peut-être parce que ce serait trop lourd sur un site avec des données importantes ?), mais se base sur un fichier json qui est justement généré lorsqu'on clique sur le bouton d'indexation.

Ce fichier json est disponible ici :

/media/com_jamegafilter/en_gb/1.json
/media/com_jamegafilter/fr_fr/1.json

Comment insérer un Custom Field dans la vue "Filtre"

Dans le fichier product_item.php mentionné plus haut il suffit d'ajouter

{attr.ct1.value}

pour obtenir le contenu du Field 1

 

Attention, l'affichage est brut ("raw"), càd qu'il s'agit de la valeur du champ sans son éventuel rendu.

Exemples :

  • pour un champ Media, cela donne
    images%2Fpizza-americano.png
  • pour un champ Editor, cela donne
    <ul> <li>pâte</li> <li>jambon</li> <li>fromage</li> </ul>

 

NB : si un champ peut avoir plusieurs valeurs et qu'on souhaite ajouter une classe pour chacune de ces valeurs, on peut alors ajouter le code suivant : 

{#attr.ct3.value}
   <p class="{.}">{.}</p>
{/attr.ct3.value}

qui donnera p.ex. ceci au niveau de l'output

<p class="red">red</p>
<p class="green">green</p>
<p class="blue">blue</p>

Comment activer le "infinite scroll" sur la page de filtre

Dans la configuration de JA MegaFilter, le "infinite scroll" s'appelle "auto page", qu'il suffit donc d'activer.

Liens utiles sur le forum de MegaFilter

Mon panier

Le panier est vide

Vous aimez lire Cinnk magazine ?

Abonnez-vous !

cinnk-magazine-abonnement-1-an

Template Creator

Envie de rejoindre le projet ?

Vous aimez écrire, vous avez une experience à partager, une expertise à apporter ou encore une vision à exposer et vous souhaitez participer au projet ?

Rejoignez-nous !

Proposer un article

Vous aimez le magazine !

Affichez-le haut et fort

Téléchargez nos bannières

Devenez annonceur

Please publish modules in offcanvas position.

Sur ce site, nous utilisons des cookies.