Série : développer une extension Joomla! 3.0 - Episode 3 : l'écriture du noyau

Written by | 30 April 2013 | Published in 2013 May
Dans les articles précédents, nous avons "préparé le terrain" et commencé la mise en place de la structure du composant. Dans ce tutoriel, nous allons nous concentrer sur certains détails comme l’écriture des fonctions et des fichiers constituant le noyau de cette extension. Nous allons ainsi commencer à la faire "fonctionner". Nous tenterons également d'unifier l'ensemble du composant avec le secret espoir d'avancer dans la réalisation de notre objectif final.

Etape 0 : préparez-vous un expresso

Aujourd'hui, vous aurez vraiment besoin d'un café serré. Dans ce tutoriel, nous allons aborder en détail les modèles et vues nécessaires au composant Lendr, éléments que nous avons commencés à mettre en place dans nos précédents tutoriaux. Si vous nous rejoignez tout juste et avant de prendre connaissance de ce tutoriel, je vous invite à lire le premier article de cette série, puis l'article sur la configuration initiale.
Ca y est, c'est fait ? Prêt pour la suite ?
En premier lieu, assurez-vous que la configuration de votre système est correcte et ouvrez votre éditeur de code. Et bien sur, n'oubliez pas votre expresso !

Etape 1 : fonctions et détails des fichiers modèles

Maintenant que nous avons créé nos fichiers de base et commencé le codage de nos modèles, il nous faut entrer dans le vif du sujet. Première chose à faire : lister les modèles que nous allons écrire et définir les fonctions qui devront y être ajoutées. Voici un bref aperçu de ces modèles et fonctions :

Fichiers de base et fonctions souhaitées
Modèles/ModelsFonctions/Functions
Default (défaut)* save
delete
set
get
getItem
listItems
getState
getTotal
getPagination
Book (livre) _buildQuery
_buildWhere
Wishlist (liste d'envie) _buildQuery
_buildWhere
Profile (profil) _buildQuery
_buildWhere
Library (bibliothèque) _buildQuery
_buildWhere
Waitlist (liste d'attente) _buildQuery
_buildWhere
Review (commentaires) _buildQuery
_buildWhere

* NDT : Les traductions entre parenthèses sont données à titre indicatif. Il est souhaitable et parfois obligatoire de conserver les termes définis dans le présent article.

Une fois que nous avons défini grossièrement les modèles et fonctions dont nous aurons besoin, nous pouvons commencer l'écriture des modèles.
Pendant toute la durée de ce processus, il est très important de garder à l'esprit le principe suivant : notre liste est fluide et dynamique. Il est possible de retourner à notre liste, d'ajouter ou supprimer des fonctions en cas de besoin. N'ayez pas peur de revenir régulièrement à cette liste tout au long de notre progression et lorsque nous évaluons les choses. Il est tout à fait possible que nous opérions des simplifications avec l'ajout d'une fonction à un modèle en particulier, ou peut-être aurons-nous besoin de réécrire de façon plus concise une fonction que nous ajouterons à notre modèle par défaut.
Une chose est sûre, nous ne voulons pas réécrire le même code encore et encore, à la minute où nous nous apercevrons que nous nous engageons sur cette voie, il nous faudra réfléchir à la manière de résumer ce code en un modèle commun.
Commençons à rédiger nos modèles.

Etape 2 : écrire les modèles

Notre composant Lendr est constitué d'un grand nombre de modèles mais nous n'avons pas le temps ici de tous les écrire.
Nous allons nous concentrer sur plusieurs modèles clés permettant de vous familiariser avec une bonne partie du composant et nous laisserons quelques modèles secondaires sur notre dépôt Github afin que vous puissiez les consulter.

Commençons par coder le modèle "book" (livre). Après réflexion, j'ai décidé de débuter mon codage par le fichier le plus spécifique, puis de travailler sur le modèle "library" (bibliothèque) et enfin sur le modèle "profile" (profil). La raison en est fort simple. Le livre représente la plus petite unité, une bibliothèque est composée de plusieurs livres et un profil quant à lui, contient une bibliothèque. Je suis sur que cela vous aidera à comprendre la raison pour laquelle notre travail débutera par le modèle "book" (livre).

Avant toute chose, le tout premier modèle que nous allons examiner sera le "default" (par défaut). Nous utilisons le modèle "default" (par défaut) pour y stocker quelques fonctions de base que nous souhaitons rendre disponible dans tous nos modèles et puisque nous écrivons un code Orienté Objet, nous ne voulons pas réécrire les mêmes fonctions dans chacun de nos modèles.

Les fichiers modèle
default.php
book.php
library.php
profile.php

Etape 3 : intégrer des fonctionnalités supplémentaires

Au cours de la réalisation de ce composant, il m'a semblé intéressant de pouvoir y intégrer des extensions tierces plutôt que de devoir "réinventer la roue".

Nous avons pu simplifier nos styles et types d'affichages grâce à l'utilisation des classes Bootstrap présentes dans Joomla! 3.
D'autres extensions peuvent être utilisées comme Gravatar et Open Library. Si vous n'êtes pas familier avec ces outils, vous trouverez la documentation sur leurs sites respectifs. Voici une brève explication de l'utilisation que nous en faisons dans Lendr.

Gravatar

Gravatar propose une méthode simple de récupération d'une image ou d'un avatar associé à une adresse e-mail. Lendr l'utilise pour afficher les photos de profil de façon incroyablement simple. Vous verrez le code nécessaire pour y parvenir lorsque nous écrirons les affichages de vue dans l'étape suivante.

Open Library

Open Library permet notamment de récupérer l'image de couverture d'un ouvrage grâce à son numéro ISBN. Cela nous permet d'intégrer facilement une couverture pour chaque livre, sans avoir à nous préoccuper de notre espace de stockage, de l'ajout d'images etc. Open Library propose différents champs pouvant être utilisés pour trouver la couverture d'un livre et ajouter l'image. Lendr utilise le code ISBN qui fait partie intégrante du formulaire d'ajout de livres que vous pouvez voir ci-dessous.
Vous trouverez le code dans les présentations de vue ci-dessous.

Etape 4 : commencer la mise en forme des Vues et Styles

La première chose à faire est de retourner au point d'entrée du composant. Ce point de départ est le contrôleur par défaut dont nous faisons référence dans le fichier racine lendr.php. Après avoir écrit nos modèles, il est clair qu'il nous faut retourner et mettre à jour le point de départ des utilisateurs. Nous modifions ainsi les lignes de code suivantes dans notre contrôleur par défaut default.php :

joomla_root/components/com_lendr/controllers/default.php

$layoutName   = $app->input->getWord('layout', 'list');

L'utilisateur sera ainsi dirigé vers la liste de vue des profils. C'est la première vue que nous allons étudier. Dans notre dossier views (vues), nous avons un dossier profile avec l'organisation suivante :

Organisation du dossier

profile
  tmpl
    _entry.php
    index.html
    list.php
    profile.php
  html.php
  index.html
  phtml.php

Ecriture des fichiers

Nous examinerons tout d'abord le fichier html.php. Suivant les prescriptions Joomla!, ce fichier est le fichier "par défaut", respectant la convention de nommage actuelle. Nous avons découvert la structure de base de ces fichiers dans l'article précédent.

Fichiers individuels

html.php

Aparté : puisque nous appelons le fichier helper de la vue, il est utile de le réviser dès maintenant.

view.php

Revenons maintenant au fichier html de vue original, nous pouvons voir les paramètres pour la fonction de chargement du helper de vue. Tout d'abord, nous indiquons au helper le dossier de vue que nous souhaitons utiliser, puis la mise en page à utiliser, et enfin, le type de format de page associé.
Pour diverses raisons, nous avons créé un nouveau fichier que nous avons nommé phtml.php contenant une partie du html.php. Nous utilisons ce fichier au lieu du fichier de vue standard html en raison des différentes fonctions supplémentaires appelées. Puisque dans la plupart des cas nous voulons simplement une fonction de rendu basique applicable à une partie des templates, nous n'aurons pas besoin de l'intégralité du contenu d'un fichier html standard. Bien qu'il existe d'autres méthodes pour traiter ce genre de problème, disposer d'un fichier différent pour la vue offrira une meilleure organisation et une localisation aisée au cas où des fonctions supplémentaires se rapportant à une partie des templates s'avéraient nécessaires.

phtml.php
_entry.php
list.php
profile.php

Les autres mises en page

Nous avons passé en revue toutes les mises en page pour l'onglet profil mais tout au long du processus, nous avons découvert des vues supplémentaires appelées pour l'affichage du profil. Afin d'éviter que cet article ne soit trop long, nous ne listerons pas ici chaque vue et code associé, mais vous pouvez consulter le code associé à chaque vue directement dans notre dépôt GitHub.

Etape 5 : Javascript et CSS

Les javascript et les CSS associés à Lendr sont les derniers éléments que nous allons étudier dans ce tutoriel.
Lendr utilisant Bootstrap et jQuery, la fenêtre modale mentionnée à l'étape précédente pour l'ajout d'un nouveau livre est automatiquement incluse et nous n'avons donc pas besoin d'écrire de fonctions Javascript spécifiques pour la faire fonctionner.
Seules quelques parties du système nécessiteront l'écriture d'un code javascript spécifique, parfois des styles CSS spécifiques seront également nécessaires. Nous ajouterons le fichier d'aide suivant pour spécifier la localisation des styles et du javascript.

joomla_root/components/com_lendr/helpers/style.php

<?php
// no direct access
defined('_JEXEC') or die('Restricted access');
 
class LendrHelpersStyle
{
  function load()
  {
    $document = JFactory::getDocument();
 
    //stylesheets
    $document->addStylesheet(JURI::base().'components/com_lendr/assets/css/style.css');
 
    //javascripts
    $document->addScript(JURI::base().'components/com_lendr/assets/js/lendr.js');
  }
}

Ici, nous associons tous les CSS et javascript en relation avec à notre composant. Ce fichier helper se trouve dans le dossier helper et comme d'habitude respecte la convention de nommage standard des classes pour le composant. Cette classe est automatiquement intégrée avec la fonction par le namespace (loader) comme défini dans le fichier racine lendr.php. Nous appelons cette classe par ce même fichier racine grâce à cette ligne de code :

joomla_root/components/com_lendr/lendr.php

//Load styles and javascripts
LendrHelpersStyle::load();

Maintenant que nous avons inclus les fichiers javascript et CSS, nous pouvons commencer à ajouter les fonctions dont nous avons besoin. La première que nous allons ajouter est relative à la fenêtre modale que nous venons tout juste de créer pour l'ajout d'un livre.

Une fois que le formulaire d'ajout de livre est complété, l'utilisateur le soumet en cliquant sur le bouton "Ajouter". Lorsque ce bouton est cliqué, la commande javascript addBook() s'exécute.

joomla_root/components/com_lendr/assets/js/lendr.js

//add a book
function addBook()
{
  var bookInfo = {};
  jQuery("#bookForm :input").each(function(idx,ele){
    bookInfo[jQuery(ele).attr('name')] = jQuery(ele).val();
  });
 
  jQuery.ajax({
    url:'index.php?option=com_lendr&controller=add&format=raw&tmpl=component',
    type:'POST',
    data:bookInfo,
    dataType:'JSON',
    success:function(data)
    {
      if ( data.success ){
        jQuery("#book-list").append(data.html);
        jQuery("#newBookModal").modal('hide');
      }else{
 
      }
    }
  });
}

Dans cette fonction, nous utilisons d'abord jQuery pour créer un objet "bookInfo" contenant l'ensemble des variables de notre formulaire.
Une fois que nous disposons de ces variables dans un formulaire unique, nous commençons à créer une soumission Ajax, toujours en utilisant jQuery. Vous remarquez que nous spécifions notre URL détaillée pour y inclure le contrôleur, le format et le tmpl (ou type de template).

A ce stade, quelques petites remarques. Lendr étant une extension développée pour Joomla! 3.x, nos contrôleurs sont des contrôleurs à fonction unique, ce qui signifie qu'ils n'exécutent qu'une seule tâche. Ce format permet de ne retourner que les données de ce contrôleur et le tmpl indique au template Joomla! quel fichier (component.php ou index.php) utilisé.
Ensuite nous décrivons le type de soumission, dans notre cas, POST. Pour les données, nous assignons l'objet bookInfo que nous avons créé précédemment, et pour le type nous spécifions JSON.

Le contrôleur (dans notre cas add.php) va alors gérer le formulaire de soumission, le publier dans le bon modèle pour y stocker les données et renvoyer le résultat. Le résultat sera un array (tableau) encodé en JSON avec une variable de "réussite" définie.
Voici ce contrôleur :

joomla_root/components/com_lendr/controllers/add.php

<?php defined( '_JEXEC' ) or die( 'Restricted access' ); 
 
class LendrControllersAdd extends JControllerBase
{
  public function execute()
  {
 
    $return = array("success"=>false);
 
    $model = new LendrModelsBook();
    if ( $row = $model->store() )
    {
      $return['success'] = true;
      $return['msg'] = JText::_('COM_LENDR_BOOK_SAVE_SUCCESS');
 
      $bookView = LendrHelpersView::load('Book','_entry','phtml');
      $bookView->book = $row;
 
      ob_start();
      echo $bookView->render();
      $html = ob_get_contents();
      ob_clean();
 
      $return['html'] = $html;
    }else{
      $return['msg'] = JText::_('COM_LENDR_BOOK_SAVE_FAILURE');
    }
    echo json_encode($return);
  }
}
Note : ob_start(), ob_get_contents(), et ob_clean() sont utilisés pour le rendu d'une partie du template et pour retourner ainsi le html généré au javascript pour être ajouter dynamiquement à la page.
Note : le résultat de l'exécution de cette fonction est un echo du tableau (array) renvoyé en encodage JSON, du fait que ce contrôleur est traité en AJAX.

Revenons à la fonction javascript ci-dessus et examinons maintenant les résultats du post AJAX et la réponse retournée.

if ( data.success )
  {
    jQuery("#book-list").append(data.html);
    jQuery("#newBookModal").modal('hide');
  }else{
    ...
  }

Ici, nous récupérons le html (généré par le contrôleur et assigné à la variable html) et nous l'ajoutons au corps du tableau de la liste des livres. Nous allons également masquer la fenêtre en cas de succès.
Pour l'instant, notre statut "else" est vide, nous le complèterons plus tard avec un message approprié. Cela fera partie d'un de nos articles à paraître sur les "finitions".

Conclusion

Vous y êtes arrivé ? Cet article entre plus dans le détail que les précédents mais devrait vous fournir une approche assez complète quant au développement d'une extension commerciale pour Joomla! 3.x, notamment par l'utilisation de normes de codage standards et par l'implémentation de nouvelles fonctionnalités MVC ainsi que d'autres fonctionnalités propres à Joomla! 3.x. Nous continuerons dans le prochain tutoriel de cette série à compléter les modèles et contrôleurs, les vues et javascript nécessaires au développement de l'extension.

J'espère que ces éléments vous auront été utiles pour la création de vos propres composants pour Joomla! et j'espère que vous n'hésiterez pas à nous contacter si vous avez des questions ou commentaires sur cette étape. J'ai réécrit à plusieurs reprises des parties de cet article pour tenter de trouver la meilleure méthode et le format le plus clair possible tant pour le code que pour les mises en forme. Je suis conscient que certains éléments de cet article ne sont pas détaillés pas à pas (comme par exemple la mise en forme du book_entry avec boutons), mais je suis prêt à fournir des petits tutoriaux complémentaires sur les éléments qui vous sembleraient devoir être détaillés et pour lesquels vous en ferez la demande dans les commentaires.

Dans le prochain article de cette série, nous poursuivrons l'ajout de fonctionnalités au composant et nous ajouterons également des fonctions encore plus excitantes !

Téléchargement

Téléchargez le composant (tel qu'il existe à cette étape) depuis le dépôt GitHub

Téléchargement

Visitez le site tutoriel complet: http://lendr.sparkbuilt.com/

Ressources :

lendr.sparkbuilt.com

Dans la série :

Read 17366 times Tagged under French
Sandra Thevenet

Sandra Thevenet

Of course, I am passionate about the web, and even more about Joomla! and especially its fabulous Community of people with whom it is so easy to share.
Some call me the CSS fanatic and I must confess, it is truly a passion for me.
From my little island, I try to contribute and participate to the Joomla! project.

----

Vous êtres francophone et vous souhaitez écrire ou traduire un article sur notre CMS préféré ? Contactez-moi par mail : sandra.thevenet@community.joomla.org