Logo Time4Digital Logo Time4Digital
  • Agence Web
  • Services
    Aperçu de tous les services
    Web development and software development
    Support pour votre site web & application web
    Agence de sites web innovants et durables
    Marketing en ligne & optimisation des moteurs de recherche
    Systèmes de gestion de contenu
    Solutions E-Commerce
    Agence SEO locale
  • Portefeuille
  • Sites Web
  • Équipe
  • Insights
  • Réserver
    rdv.
  • Check
    SEO gratuit
  • English
  • Deutsch
  • French

Création d'un plugin Contao - développement front & backend!

Écrit le 21.11.2024 16:35 by rd

Table de matières

Aller au contenu
  • La structure des fichiers du plugin
  • Plugin Contao: La structure de base
    • La structure de Composer
    • La structure de la classe Bundle
    • La structure de la classe Plugin
    • La structure de la class Dependency
    • Les fichiers Config et Services
  • La structure du Contao module Frontend "Hello World"
    • La structure de la classe du module Frontend
    • Porter le module Frontend dans le Backend
    • Fichier modèle pour le module Frontend
    • Intégrer CSS et JS dans le module Contao
  • Module Contao Backend: Structure et intégration de la base de données
    • Création de tables de base de données avec DCA
    • Traduction des champs
    • Porter le module Backend dans le backend de Contao
    • Afficher les données du backend dans le frontend
 
Plugin Darstellung im Frontend

Tous les débuts sont difficiles. Même pour des développeurs expérimentés comme nous, se lancer dans de nouvelles technologies est souvent un défi. Comprendre les concepts derrière le développement d'un plug-in Contao et les utiliser pour enrichir son propre site web Contao avec ses propres plug-ins innovants demande du temps. La documentation de Contao offre certes un assez bon aperçu, mais seulement jusqu'à un certain point. Plus les questions deviennent spécifiques, moins on y trouve ce qu'on cherche. C'est pourquoi nous avons décidé d'écrire un article sur la manière de créer soi-même un plugin Contao « Hello World ». L'article est écrit simplement et vous fournit des connaissances de base intéressantes dont vous avez besoin pour développer vos propres plugins dans Contao. Dans cet article, vous apprendrez comment mettre en place la base d'un plugin, comment afficher un texte « Hello World » sur le front-end, quelle doit être la structure des données et comment créer une connexion à une base de données. Au final, le tout devrait être un plugin « Hello World » qui affiche en plus des messages que l'on a définis dans le backend.

Le plugin est disponible sur Github à ce lien. Vous pouvez utiliser ce code comme base et à des fins de test.

La structure des fichiers du plugin

La structure de fichier du plugin Contao doit absolument être respectée pour que le Contao Manager reconnaisse le plugin Contao en tant que tel et le charge.

La structure de fichier du plugin sert d'orientation pour la construction du plugin

Plugin Contao: La structure de base

Dans la première étape, il faut construire le plugin de manière à ce que Contao le considère comme un plugin et que l'on puisse l'installer via le Contao Manager.
Pour cela, les classes suivantes doivent être créées et adaptées :

La structure de Composer

Contao utilise PHP Composer pour les modules, les extensions et les plugins. C'est pourquoi notre plugin a également besoin d'un fichier de configuration Composer, qui se trouve dans le répertoire racine du plugin. Si tu veux utiliser l'exemple JSON de Composer, tu dois absolument adapter les valeurs marquées d'un '#'.

./composer.json

{
  "name": "time4digital/dylans-hello-world-bundle",               # Nom du plugin
  "description": "Dylan's Hello World Plugin",                    # Description du plugin
  "license": "LGPL-3.0-or-later",
  "type": "contao-bundle",
  "version": "0.0.4",                                             # Version du plugin
  "authors": [
    {
      "name": "Ribeiro de Serra Dylan",
      "homepage": "https://www.time4digital.lu"                   # Auteur du plugin
    }
  ],
  "homepage": "https://contao.org",                               # OPTIONEL: Ton propre site web                    
  "support": {
    "issues": "https://github.com/ridy01-backup/contao-plugins/issues",   #OPTIONEL: Lien sur Git.
    "source": "https://github.com/ridy01-backup/contao-plugins"
  },
  "require": {
    "php": "^8.1",
    "contao/core-bundle": "^4.13 || ^5.0"                                   # Déclare tes dépendances ici
  },
  "require-dev": {
    "bamarni/composer-bin-plugin": "^1.5",
    "contao/manager-plugin": "^2.0",
    "phpunit/phpunit": "^9.5",
    "symfony/phpunit-bridge": "^6.1"
  },
  "conflict": {
    "contao/manager-plugin": "<2.0 || >=3.0"                                # Conflits potentiels peuvent être déclarés ici
  },
  "autoload": {
    "psr-4": {
      "Time4digital\\DylansHelloWorldBundle\\": "src/"                      # Le chemin qui sera lié, Format: "VendorName\\BundleName\\": "CHEMIN"
    }
  },
  "autoload-dev": {
    "psr-4": {
      "Time4digital\\DylansHelloWorldBundle\\Tests\\": "tests/"             # Le chemin pour les tests, Format: "VendorName\\BundleName\\Tests": "CHEMIN"
    }
  },
  "config": {
    "allow-plugins": {
      "bamarni/composer-bin-plugin": true,
      "contao-components/installer": true,
      "contao/manager-plugin": true
    }
  },
  "extra": {
    "bamarni-bin": {
      "bin-links": false,
      "target-directory": "tools"
    },
    "contao-manager-plugin": "Time4digital\\DylansHelloWorldBundle\\ContaoManager\\Plugin"    # Lien du plugin, Format:"VendorName\\BundleName\\ContaoManager\\Plugin
  },
  "scripts": {
    "all": [
      "@unit-tests",
      "@ecs",
      "@phpstan"
    ],
    "ecs": "@php tools/ecs/vendor/bin/ecs check src tests --config ecs.php --fix --ansi",
    "phpstan": "@php tools/phpstan/vendor/bin/phpstan analyze --ansi",
    "unit-tests": "@php vendor/bin/phpunit --colors=always"
  }
}

La structure de la classe Bundle

Le Contao Bundle est là pour regrouper tes ressources. Cette classe elle-même ne nécessite pas de spécifications supplémentaires ; il suffit d'étendre la classe du Symfony Bundle.

./src/DylansHelloWorldBundle.php

<?php
namespace Time4digital\DylansHelloWorldBundle;

use Symfony\Component\HttpKernel\Bundle\Bundle;

class DylansHelloWorldBundle extends Bundle
{
    
}

La structure de la classe Plugin

La classe Plugin sert à charger le bundle pour que le Contao Manager sache qu'il s'agit d'un plugin Contao.

./src/ContaoManager/Plugin.php

<?php

declare(strict_types=1);

namespace Time4digital\DylansHelloWorldBundle\ContaoManager;

use Contao\ManagerPlugin\Bundle\BundlePluginInterface;
use Contao\ManagerPlugin\Bundle\Config\BundleConfig;
use Contao\ManagerPlugin\Bundle\Parser\ParserInterface;
use Contao\CoreBundle\ContaoCoreBundle;
use Time4digital\DylansHelloWorldBundle\DylansHelloWorldBundle;

class Plugin implements BundlePluginInterface
{
    /**
     * {@inheritdoc}
     */
    public function getBundles(ParserInterface $parser)
    {
        return [
            BundleConfig::create(DylansHelloWorldBundle::class)
                ->setLoadAfter([ContaoCoreBundle::class]),
        ];
    }
}

La structure de la class Dependency

La classe Dependency sert à charger les fichiers de configuration et de services.

./src/DependencyInjection/DylansHelloWorldExtension.php

<?php
declare(strict_types=1);

namespace Time4digital\DylansHelloWorldBundle\DependencyInjection;

use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\Extension;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;

class DylansHelloWorldExtension extends Extension
{
    /**
     * {@inheritdoc}
     */
    public function load(array $mergedConfig, ContainerBuilder $container)
    {
        $loader = new YamlFileLoader(
            $container,
            new FileLocator(__DIR__.'/../Resources/config')
        );

        $loader->load('services.yml');
    }
}

Les fichiers Config et Services

Les fichiers Config et Services servent à lier les classes que l'on écrit au sein du bundle, afin qu'elles puissent être chargées et utilisées lors de l'installation.

./src/Resources/config/config.yml

imports:
    - { resource: services.yml }

./src/Resources/config/services.yml

services:
    _defaults:
        autowire: true
        autoconfigure: true

Et ainsi, la base du plugin est construite. On pourrait maintenant compresser le plugin, le télécharger via le Contao Manager et l'installer.
Mais cela ne suffit pas encore pour afficher 'Hello World' dans le frontend.

La structure du Contao module Frontend "Hello World"

Dans cette section, nous créons un module frontend qui doit afficher "Hello World" dans le frontend.
Le module charge en outre un fichier CSS et JS.

La structure de la classe du module Frontend

La moduleclasse sert à créer un module dans le backend, qui peut ensuite être chargé dans un article ou similaire.

./src/Module/DylanHelloWorldModule.php

<?php

namespace Time4digital\DylansHelloWorldBundle\Module;

use Contao\Module;

//Hier werden die CSS- und JS-Dateien gesetzt. Format: bundles/bundleName/dateiName.dateExtension
$GLOBALS['TL_CSS'][] = 'bundles/dylanshelloworld/styles.css';
$GLOBALS['TL_JAVASCRIPT'][] = 'bundles/dylanshelloworld/scripts.js';

class DylanHelloWorldModule extends Module
{
    // On définit ici le nom du template.
    // Le nom doit correspondre au modèle qui se trouve sous ./src/Resources/contao/templates.
    protected $strTemplate = 'mod_helloWorld'; 

    protected function compile()
    {
        // Avec $this->Template->nameVariable, tu crées des variables qui peuvent ensuite être utilisées dans le modèle.
        $this->Template->message = 'Hello World!';
    }
}

Porter le module Frontend dans le Backend

Le fichier Config PHP sert à apporter des modules dans le backend.

./src/Resources/contao/config/config.php

<?php
use Time4digital\DylansHelloWorldBundle\Module\DylanHelloWorldModule;

// Frontend modules
// Sous "miscellaneous", il devrait créer un nouveau onglet "Hello World Plugin" avec lequel on accède notre module Frontend
$GLOBALS['FE_MOD']['miscellaneous']['Hello World Plugin'] = DylanHelloWorldModule::class;

Fichier modèle pour le module Frontend

Le fichier modèle est en quelque sorte utilisé comme conteneur pour le module. Tu y intègres les données que tu définis dans le module et tu construis ainsi une structure HTML.

./src/Resources/contao/templates/modules/mod_helloWorld.html5

<?php $this->extend('block_searchable'); ?>

<?php $this->block('content'); ?>

<!-- Ici on utilise la valeur de la variable message. -->
<div class="dylan-hello-world-container">
    <?= $this->message; ?>
</div>

<?php $this->endblock(); ?>

Intégrer CSS et JS dans le module Contao

Tu peux intégrer tes propres fichiers CSS et JS dans le module Contao, comme défini dans le module ci-dessus. Pour cela, il suffit de respecter la structure de fichier suivante (le nom du fichier n'a pas d'importance) :

./src/Resources/public/scripts.js

./src/Resources/public/styles.css

... et voilà, tu peux créer un nouveau module dans le backend sous Themes > Frontend Module et tu choisis simplement le plugin Hello World comme type de module !

Ensuite, tu vas sur un article quelconque ou quelque chose de similaire et tu y sélectionnes le module créé.

Demonstration der Erstellung eines Frontend-Moduls aus dem programmierten Frontend-Modul
Im Contao Backend den Frontend-Module in einem Artikel zuweisen

Ouf, c'était déjà beaucoup de travail... mais ce n'est pas encore suffisant! Certes, notre module frontend peut bien afficher quelque chose de beau dans le frontend, et est équipé de fonctions PHP... mais si nous voulons en plus charger des données de la base de données et les gérer via le backend Contao ?

C'est précisément ce que nous allons aborder en détail dans la section suivante.

Module Contao Backend: Structure et intégration de la base de données

Dans cette section, nous allons créer un module backend qui charge des données à partir d'une table appelée tl_messages et qui peut en outre être édité. Le tout doit être visible dans le backend Contao sous un point de menu.
De plus, nous étendons le module Frontend pour qu'il lise également les données du backend.

Création de tables de base de données avec DCA

Le fichier PHP de FDCA te permet d'indiquer à Contao que tu souhaites créer une nouvelle table de base de données.
Tu configures ainsi la structure de la table et tu définis comment les données doivent être affichées.

./src/Resources/contao/dca/tl_messages.php

<?php
use Contao\DC_Table;

// Le nom de la table ; le fichier PHP doit porter le même nom.
$GLOBALS['TL_DCA']['tl_messages'] = [

    // On définit ici ce qui doit être affiché dans le backend Contao:
    'palettes' => [
        'default' => '{messages_legend},message;'
    ],

    // Les champs SQL sont définis ici:
    'fields' => [
        // Ce champs est obligatoire.
        'id' => [
            'sql' => "int(10) unsigned NOT NULL auto_increment",
        ],
        // Ce champs est obligatoire.
        'tstamp' => [
            'sql' => "int(10) unsigned NOT NULL default '0'",
            'label' => 'TS',
        ],
        'message' => [
            'inputType' => 'text',
            'eval' => ['tl_class' => 'w50', 'maxlength' => 255],
            'sql' => "varchar(255) NOT NULL default ''"
        ]
    ],
    
    // Les clés et autres attributs sont définis ici.
    'config' => [
        'dataContainer' => DC_Table::class,
        'sql' => [
            'keys' => [
                'id' => 'primary'
            ]
        ]
    ],

    // C'est ici que l'on définit comment l'ensemble sera représenté dans le backend Contao.
    'list' => [
        'sorting' => [
            'mode' => 1,
        ],
        'operations' => [
            'edit',
            'delete',
        ],
        'label' => [
            'fields'  => ['id','message'],
            'showColumns' => true,
        ]
    ],
];

Traduction des champs

Le fichier XLF de la traduction sert à définir les labels et les descriptions pour les différentes langues.

./src/Resources/contao/languages/en/tl_messages.xlf

<?xml version="1.0" ?><xliff version="1.1">
<!-- Format: contao/languages/LANGUE/TABELLE.php-->
  <file datatype="php" original="contao/languages/en/tl_messages.php" source-language="en">
    <body>
        <!-- Désignations des labels dans le backend de Contao -->
        <trans-unit id="tl_messages.messages_legend">
            <source>Messages</source>
        </trans-unit>
        <!-- Désignation du champs "Nachricht" -->
        <trans-unit id="tl_messages.message.0">
            <source>Message</source>
        </trans-unit>
        <!-- Désignation de la description du champs "Nachricht" -->
        <trans-unit id="tl_messages.message.1">
            <source>Your individual message.</source>
        </trans-unit>
    </body>
  </file>
</xliff>

Porter le module Backend dans le backend de Contao

Le fichier PHP Config doit maintenant être adapté comme pour le module frontend.

./src/Resources/contao/config/config.php

<?php
use Time4digital\DylansHelloWorldBundle\Module\DylanHelloWorldModule;

// Modules Frontend
// Sous "miscellaneous", on crée un nouvel onglet nommé "Hello World Plugin", qui chargera ensuite notre module frontend.
$GLOBALS['FE_MOD']['miscellaneous']['Hello World Plugin'] = DylanHelloWorldModule::class;

// Modules Backend
// Sous la catégorie de menu « content » devrait maintenant apparaître une nouvelle entrée de menu appelée "Messages", qui gère la table tl_messages.
$GLOBALS['BE_MOD']['content']['Messages'] = [
    'tables' => ['tl_messages']
];

Afficher les données du backend dans le frontend

Pour cela, le modèle et le module frontal doivent être adaptés.

./src/Module/DylanHelloWorldModule.php

<?php

namespace Time4digital\DylansHelloWorldBundle\Module;

use Contao\Module;

// Les fichiers CSS et JS sont placés ici. Format : bundles/bundleName/fileName.dateExtension
$GLOBALS['TL_CSS'][] = 'bundles/dylanshelloworld/styles.css';
$GLOBALS['TL_JAVASCRIPT'][] = 'bundles/dylanshelloworld/scripts.js';

class DylanHelloWorldModule extends Module
{

    // On définit ici le nom du modèle.
    // Le nom doit correspondre au modèle qui se trouve sous ./src/Resources/contao/templates.
    protected $strTemplate = 'mod_helloWorld'; 

    protected function compile()
    {
       
        // Avec $this->Template->nameVariable on peut créer des variables, qui peuvent être utilisées dans le modèle.
        $this->Template->message = 'Hello World!';
        
        // La classe Module nous donne la possibilité de charger rapidement des entrées de base de données via la classe Contao Database.
        // Ici, on récupère les données via une requête SQL. Cette requête extrait les entrées de la base de données et les stocke dans un array.
        try {
            $objEntries = $this->Database->execute("SELECT * FROM tl_messages");
            $this->Template->entries = $objEntries->fetchAllAssoc();
        } catch (\Exception $e) {
        // Si cela ne fonctionne pas, on retourne un tableau vide au modèle.
            $this->Template->entries = [];
        }
    }
}

./src/Resources/contao/templates/modules/mod_helloWorld.html5

<?php $this->extend('block_searchable'); ?>

<?php $this->block('content'); ?>

<!-- Ici on utilise la valeur de la variable message -->
<div class="dylan-hello-world-container">
    <?= $this->message; ?>
</div>

<!-- Nous parcourons ici le tableau entries et prenons pour chaque élément la valeur du message -->
<div class="dylans-hello-world-live-container">
    <ul>
        <?php foreach ($this->entries as $entry): ?>
        <li><?= $entry["message"]; ?></li>
        <?php endforeach; ?>
    </ul>
</div>

<?php $this->endblock(); ?>

Finalement, on y est! Après bien des hauts et des bas, nous avons atteint le sommet. Il est temps de se réjouir ! ;-)

Après la réinstallation du plugin, il devrait y avoir un nouvel élément de menu appelé « Messages », qui permet de créer de nouveaux messages. Ensuite, notre module frontal devrait afficher tous ces messages.

Dans le backend de Contao se trouve maintenant l'onglet de menu 'Messages', qui sert à créer des messages

Nous espérons que cet article de blog vous a permis d'en apprendre davantage sur le développement de plugins Contao.

Il est important de noter qu'il existe plusieurs façons de mettre en œuvre ce plugin et que cet article ne constitue qu'un exemple. Vous êtes entièrement libre de développer votre plugin Hello World comme vous le souhaitez, tant que la base est correcte et que le Contao Manager le reconnaît comme un plugin et l'installe.

Tu trouveras encore plus d'informations ici.

En outre, tu peux aussi télécharger directement le plugin via ce lien et bien sûr continuer à le développer.

Merci d'avoir lu cet article de blog! J'espère que tu t'es bien amusé et que tu as pu apprendre quelque chose. Continuez à vous amuser en développant !

  • Facebook
  • LinkedIn
  • WhatsApp
  • E-mail
  • Twitter
time4digital S.à r.l.

2C, op der Gare
L-6850 Manternach

Téléphone: + 352 29 20 21

Sur nous

La société time4digital S.à r.L. est specialisée sur le développement des solutions logicielles sous forme d'applications web et mobiles.

Contactez nous!
Juridique
  • Mentions légales
  • Protection des données
  • Cookie Consent

    Modifier les paramètres de confidentialité
Gehe zu
  • Home
  • Sur nous
  • Services
  • Portefeuille
  • Notre équipe
  • Contact

© time4digital S.à r.l.

Notre site web utilise des cookies.

Ces cookies sont essentiels pour la fonctionnalité du site.

Protège contre les attaques de type "cross-site request forgery".

Fournisseur: Time4Digital
Durée de conservation: Ce cookie n'est conservé que pendant la session de navigation en cours.

Sauvegarde la session PHP actuelle.

Fournisseur: Time4Digital
Durée de conservation: Ce cookie n'est conservé que pendant la session de navigation en cours.

Ces cookies sont facultatifs et n'affectent pas la fonctionnalité du site.

Ce cookie est lié à Google Universal Analytics - une mise à jour importante du service d'analyse plus fréquemment utilisé de Google. Ce cookie est utilisé pour distinguer les utilisateurs uniques en leur attribuant un numéro généré de manière aléatoire comme identifiant client. Il est inclus dans chaque demande de page sur un site web et est utilisé pour calculer les données relatives aux visiteurs, aux sessions et aux campagnes pour les rapports d'analyse du site web.

Fournisseur: Google
Durée de conservation: 1 année 1 mois

Ce cookie est utilisé par Google Analytics pour obtenir le statut de la session.

Fournisseur: Google
Durée de conservation: 1 année 1 mois