Créer un module - Étape 2 - Module front-office

Maintenant que le module back-office est terminé et fonctionnel, il est temps d'afficher quelque chose sur la partie publique du site : le front-office !

Prérequis

Les compétences suivantes sont requises pour réaliser de ce tutoriel :

Configuration

Avant toute chose, il est nécessaire d'ajouter le module front-office que nous allons développer dans le fichier de configuration du module. Pour cela, ajouter au fichier config/config.php la ligne suivante :

$GLOBALS['FE_MOD']['miscellaneous']['cd_list'] = 'ModuleCdList';

ModuleCdList fait référence à la classe que nous allons créer dans la partie suivante.

Fichiers de langue

Pour que le nom de notre module soit traduit dans le back-office et, surtout, que le libellé soit affiché au lieu de l'alias défini dans la configuration, il est nécessaire d'ajouter les traductions dans le fichier de langues.

Pour cela, ajouter dans le fichier languages/fr/modules.php :

/**
 * Front end modules
 */
$GLOBALS['TL_LANG']['FMD']['cd_list'] = array('Liste de CD', 'Ajoute une liste de CD au site.');

Contrôleur - Partie I

La première étape de la création du module front-office consiste en la création d'un contrôleur. Le but de ce contrôleur est de réaliser tout le travail métier en vue de fournir à la vue les variables et objets nécessaires à l'affichage. Par exemple, dans le cas de notre module de gestion de bibliothèque de CD, la vue a besoin d'une liste de CD. Cette liste est fournie par le contrôleur qui aura effectué les appels à la base de données nécessaires.

Nous allons donc commencer par créer le fichier du contrôleur. Pour cela, il faut créer le fichier modules/ModuleCdList.php. Par convention, chaque classe de Contao est contenu dans un fichier portant le même nom.

Une fois le fichier créé, nous allons coller le contenu de ce fichier :

<?php

namespace CdCollection;

/**
 * Class ModuleCdList
 *
 * Front end module "cd list".
 */
class ModuleCdList extends \Module
{

    /**
     * Template
     * @var string
     */
    protected $strTemplate = 'mod_cdlist';


    /**
     * Display a wildcard in the back end
     * @return string
     */
    public function generate()
    {
        if (TL_MODE == 'BE')
        {
            $objTemplate = new \BackendTemplate('be_wildcard');

            $objTemplate->wildcard = '### ' . utf8_strtoupper($GLOBALS['TL_LANG']['FMD']['cd_list'][0]) . ' ###';
            $objTemplate->title = $this->headline;
            $objTemplate->id = $this->id;
            $objTemplate->link = $this->name;
            $objTemplate->href = 'contao/main.php?do=themes&table=tl_module&act=edit&id=' . $this->id;

            return $objTemplate->parse();
        }

        return parent::generate();
    }


    /**
     * Generate the module
     */
    protected function compile()
    {

    }
}

Nous pouvons voir que cette classe hérite de la classe \Module. Cet héritage est nécessaire pour que le code de notre module s'exécute correctement. Ensuite, nous apercevons le seul attribut de notre classe, à savoir $strTemplate. Cet attribut permet de définir le template (vue) qui sera utilisé pour l'affichage du module. Ici, nous avons choisi mod_cdlist qui correspond au template mod_cdlist.html5 (noter que l'attribut contient le nom du fichier de template sans extension).

Enfin, deux méthodes font partie de la classe : generate et compile. Pour faire court, la méthode generate effectue la génération de l'affichage en appelant la fonction compile et en initialisant le template. À noter que dans le cas de ce module, nous avons un cas particulier pour le back-office grâce à la condition if (TL_MODE == 'BE'). Cette condition permet d'avoir un affichage différent dans le back-office (dans la liste des éléments de contenu); ici, nous affichons uniquement le nom du module.

Pour l'instant, la méthode compile est vide mais nous allons créer son contenu. Mais avant cela, nous allons devoir créer un modèle.

Note : Pour qu'une classe soit utilisable dans Contao, il faut qu'elle soit référencée par l'autoloader. Cette fonctionnalité permet de pouvoir utiliser n'importe quelle classe située dans un fichier externe sans utiliser include ou require pour charger le fichier. L'autoloader permet d'inclure les fichiers de classes seulement quand nécessaire. Pour référencer une classe par l'autoloader c'est très simple, il suffit de se rendre dans le back-office puis dans Outils de développement → Générateur d'autoload et de sélectionner le ou les modules dont l'autoload doit être généré (dans notre cas, il s'agit du module cd_collection). Avant de cliquer sur le bouton Créer les fichiers autoload, il faut veiller à avoir cocher la case Écraser les fichiers existants..

Modèle

Le modèle permet un accès simplifié aux données. Plutôt que de travailler avec des requêtes SQL, Contao permet une couche d'abstraction grâce aux modèles, ce qui permet de travailler avec la base de données de manière simple.

Pour créer un modèle, c'est très simple. Il suffit de créer un fichier pour chaque table avec laquelle on souhaite travailler. Dans notre cas, c'est la table tl_cd qui nous intéresse. Nous allons donc créer le fichier models/CdsModel.php (noter que nous avons supprimé le préfixe tl_ et ajouté le suffixe Model tout en utilisant la syntaxe CamelCase).

Le contenu de ce fichier est le suivant :

<?php

namespace CdCollection;

/**
 * Class CdModel
 *
 * Reads and writes CDs.
 */
class CdModel extends \Model
{

    /**
     * Table name
     * @var string
     */
    protected static $strTable = 'tl_cd';
}

Encore une fois, nous retrouvons un héritage, cette fois-ci de \Model. Cet héritage nous permet de bénéficier de toutes les méthodes la classe abstraite \Model. Le seul attribut nécessaire à cette classe pour fonctionner est $strTable qui contient le nom de la table dont il est question.

Note : Ne pas oublier de regnérer le fichier autoload !

Contrôleur - Partie II

Maintenant que notre modèle est prêt, nous pouvons l'utiliser dans notre module. Nous allons donc compléter la fonction compile de notre classe ModuleCdList :

/**
 * Generate the module
 */
protected function compile()
{
    $this->Template->cds = \CdModel::findAll();
}

Et c'est tout ! Il n'y a rien besoin de plus pour envoyer notre liste de CD à la vue. Brèves explications tout de même : * $this->Template->cds permet d'attribuer au template la variable cds. Dans le fichier de template, nous pourrons utiliser cette variable comme ceci : $this->cds. * La méthode findAll est une méthode permettant de récupérer tous les enregistrements d'une table. Autrement dit, il s'agit d'un SELECT * FROM tl_cd;. * La méthode findAll ne retourne pas un tableau mais une collection. Il s'agit d'un objet propre à Contao (issu de la classe \Model\Collection). * La méthode findAll retourne null si aucun enregistrement n'est trouvé.

Vue

La création de la vue est également très simple et consiste également en un seul fichier. Nous allons donc créer le fichier templates/mod_cdlist.html5.

Une fois ce fichier créé, nous allons y ajouter son contenu. Ici, pas de classe, il s'agit uniquement de fragments HTML avec du PHP pour l'affichage des variables.

<div class="cds">

    <?php if ($this->cds): ?>
        <?php foreach ($this->cds as $cd): ?>
            <div class="cd">
                <?php if ($cd->cover): ?>
                    <img src="<?php echo \FilesModel::findByPk($cd->cover)->path ?>" alt="">
                <?php endif ?>

                <h3><?php echo $cd->title ?></h3>

                <p class="info"><?php echo $cd->artist ?> (<?php echo $cd->year ?>), <?php echo $cd->genre ?></p>

                <?php if ($cd->description): ?>
                    <div class="description">
                        <?php echo $cd->description ?>
                    </div>
                <?php endif ?>
            </div>
        <?php endforeach ?>
    <?php endif ?>

</div>

Dans le code ci-dessus, on peut remarquer un if englobant. Cette condition sur $this->cds permet de s'assurer que la variable ne vaut pas null auquel cas un warning serait généré.

La ligne suivante permet de créer une boucle grâce à un simple foreach. En effet, même si l'objet $this->cds est un objet \Model\Collection, il est être parcouru comme un tableau grâce à foreach. Cette fonctionnalité est rendue possible parce que la classe \Model\Collection implémente l'interface IteratorAggregate.

À l'intérieur de la boucle, les appels aux propriétés de l'objet CD se font très simplement. Par exemple, pour obtenir l'ID du CD : $cd->id.

Notons également la récupération du chemin de l'image sélectionnée dans le back-office grâce à un champ fileTree :

echo \FilesModel::findByPk($this->cds->cover)->path;

Note : comme pour les classes, les templates doivent être référencés par l'autoloader. Ne pas oublier de générer l'autoload après avoir créé un template.

Conclusion

Le module est désormais fonctionnel avec une partie back-office et une partie front-office. De cette façon, nous avons une partie privée, accessible uniquement par les administrateurs du site et une autre, publique, accessible par quiconque.

Néanmoins, la création de modules pour Contao permet de nombreuses autres choses plus poussées, notamment la possibilité de créer des tables enfants, de modifier des méthodes ou des classes de Contao, d'ajouter des champs à des tables préexistantes… Toutes ces possibilités sont bien sûr traitées dans les étapes suivantes du tutoriel !

Retour

comments powered by Disqus