Skip to content

Structure d'un Module

This content is not available in your language yet.

Un module Drupal nécessite au minimum un fichier .info.yml :

  • Directorymodules/
    • Directorycustom/
      • Directorytailstore_cart/
        • tailstore_cart.info.yml

C’est la carte d’identité du module. Sans ce fichier, Drupal ne reconnaît pas le module.

# tailstore_cart.info.yml
name: TailStore Cart
type: module
description: 'Gestion du panier et checkout pour TailStore'
core_version_requirement: ^10 || ^11
package: TailStore
version: 1.0.0
# Dépendances (modules requis)
dependencies:
- drupal:node # Pour charger les produits
- drupal:user # Pour gérer les utilisateurs
# Dépendances de test (optionnel)
test_dependencies:
- drupal:phpunit
# Page de configuration (optionnel)
configure: tailstore_cart.settings
PropriétéDescriptionObligatoire
nameNom affiché dans l’interface admin
typemodule, theme, ou profile
descriptionDescription courte (< 255 caractères)Recommandé
core_version_requirementVersions Drupal compatibles
packageGroupe dans la liste des modulesOptionnel
versionVersion du module (x.y.z)Optionnel
dependenciesModules requisSi nécessaire
configureRoute de configurationSi applicable

Format : [project]:[module]

dependencies:
# Modules core
- drupal:node
- drupal:user
- drupal:field
# Modules contrib
- pathauto:pathauto
- token:token
# Modules custom
- tailstore_base:tailstore_base
  • Directorytailstore_cart/
    • tailstore_cart.info.yml Déclaration du module
    • tailstore_cart.module Hooks PHP
    • tailstore_cart.install Installation/désinstallation
    • tailstore_cart.routing.yml Routes
    • tailstore_cart.services.yml Services
    • tailstore_cart.permissions.yml Permissions
    • tailstore_cart.libraries.yml CSS/JS
    • tailstore_cart.links.menu.yml Liens de menu
    • tailstore_cart.links.task.yml Onglets
    • tailstore_cart.links.action.yml Boutons d’action
    • Directoryconfig/
      • Directoryinstall/
        • tailstore_cart.settings.yml Configuration par défaut
      • Directoryschema/
        • tailstore_cart.schema.yml Schéma de config
    • Directorysrc/
      • DirectoryController/ Controllers
      • DirectoryService/ Services
      • DirectoryForm/ Formulaires
      • DirectoryPlugin/ Plugins (blocs, champs…)
      • DirectoryEventSubscriber/ Écouteurs d’événements
    • Directorytemplates/ Templates Twig
    • Directorytests/ Tests PHPUnit

Contient les hooks et fonctions PHP :

<?php
/**
* @file
* Primary module hooks for TailStore Cart module.
*/
declare(strict_types=1);
use Drupal\Core\Routing\RouteMatchInterface;
/**
* Implements hook_help().
*/
function tailstore_cart_help(string $route_name, RouteMatchInterface $route_match): string {
if ($route_name === 'help.page.tailstore_cart') {
return '<p>' . t('Provides cart and checkout functionality for TailStore.') . '</p>';
}
return '';
}
/**
* Implements hook_theme().
*/
function tailstore_cart_theme(): array {
return [
'cart_page' => [
'variables' => [
'items' => [],
'total' => 0,
],
],
'cart_item' => [
'variables' => [
'product' => NULL,
'quantity' => 1,
'subtotal' => 0,
],
],
'mini_cart' => [
'variables' => [
'count' => 0,
'total' => 0,
'items' => [],
],
],
];
}
/**
* Implements hook_page_attachments().
*/
function tailstore_cart_page_attachments(array &$attachments): void {
// Attacher htmx sur toutes les pages
$attachments['#attached']['library'][] = 'tailstore_cart/htmx';
}

Gère l’installation, la mise à jour et la désinstallation :

<?php
/**
* @file
* Install, update and uninstall functions for TailStore Cart.
*/
declare(strict_types=1);
/**
* Implements hook_schema().
*/
function tailstore_cart_schema(): array {
$schema['tailstore_cart_items'] = [
'description' => 'Stores cart items for users.',
'fields' => [
'id' => [
'type' => 'serial',
'not null' => TRUE,
],
'session_id' => [
'type' => 'varchar',
'length' => 128,
'not null' => TRUE,
],
'user_id' => [
'type' => 'int',
'unsigned' => TRUE,
'default' => 0,
],
'product_id' => [
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
],
'quantity' => [
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 1,
],
'created' => [
'type' => 'int',
'not null' => TRUE,
],
],
'primary key' => ['id'],
'indexes' => [
'session_id' => ['session_id'],
'user_id' => ['user_id'],
],
];
return $schema;
}
/**
* Implements hook_install().
*/
function tailstore_cart_install(): void {
\Drupal::messenger()->addStatus(t('TailStore Cart has been installed.'));
}
/**
* Implements hook_uninstall().
*/
function tailstore_cart_uninstall(): void {
// Supprimer les variables de configuration
\Drupal::configFactory()->getEditable('tailstore_cart.settings')->delete();
}
/**
* Add quantity column to cart_items table.
*/
function tailstore_cart_update_9001(): void {
$schema = \Drupal::database()->schema();
if (!$schema->fieldExists('tailstore_cart_items', 'quantity')) {
$schema->addField('tailstore_cart_items', 'quantity', [
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 1,
]);
}
}

Définit les permissions du module :

# tailstore_cart.permissions.yml
access cart:
title: 'Access shopping cart'
description: 'Allows users to view and manage their cart'
access checkout:
title: 'Access checkout'
description: 'Allows users to proceed to checkout'
administer tailstore cart:
title: 'Administer TailStore Cart'
description: 'Configure cart settings and view all carts'
restrict access: true

Déclare les assets CSS et JavaScript :

# tailstore_cart.libraries.yml
htmx:
version: 2.0
js:
https://unpkg.com/htmx.org@2.0.4/dist/htmx.min.js:
type: external
minified: true
attributes:
defer: true
cart:
version: 1.0
js:
js/cart.js: {}
css:
component:
css/cart.css: {}
dependencies:
- core/drupal
- tailstore_cart/htmx
# config/install/tailstore_cart.settings.yml
stripe_public_key: ''
stripe_secret_key: ''
stripe_webhook_secret: ''
currency: 'EUR'
success_redirect: '/checkout/success'
cancel_redirect: '/cart'
# config/schema/tailstore_cart.schema.yml
tailstore_cart.settings:
type: config_object
label: 'TailStore Cart settings'
mapping:
stripe_public_key:
type: string
label: 'Stripe public key'
stripe_secret_key:
type: string
label: 'Stripe secret key'
stripe_webhook_secret:
type: string
label: 'Stripe webhook secret'
currency:
type: string
label: 'Currency code'
success_redirect:
type: path
label: 'Success redirect path'
cancel_redirect:
type: path
label: 'Cancel redirect path'
  1. Créer le dossier

    Fenêtre de terminal
    mkdir -p web/modules/custom/tailstore_cart/{src/{Controller,Service,Form,Plugin/Block},templates,config/{install,schema}}
  2. Créer le fichier .info.yml

    Fenêtre de terminal
    cat > web/modules/custom/tailstore_cart/tailstore_cart.info.yml << 'EOF'
    name: TailStore Cart
    type: module
    description: 'Gestion du panier et checkout pour TailStore'
    core_version_requirement: ^10 || ^11
    package: TailStore
    version: 1.0.0
    dependencies:
    - drupal:node
    - drupal:user
    EOF
  3. Activer le module

    Fenêtre de terminal
    ddev drush en tailstore_cart -y
  4. Vérifier

    Fenêtre de terminal
    ddev drush pm:list --filter=tailstore_cart

Drupal utilise l’autoloading PSR-4 :

Chemin du fichierNamespace
src/Controller/CartController.phpDrupal\tailstore_cart\Controller
src/Service/CartService.phpDrupal\tailstore_cart\Service
src/Form/SettingsForm.phpDrupal\tailstore_cart\Form
src/Plugin/Block/MiniCartBlock.phpDrupal\tailstore_cart\Plugin\Block
<?php
declare(strict_types=1);
namespace Drupal\tailstore_cart\Controller;
use Drupal\Core\Controller\ControllerBase;
/**
* Controller for cart operations.
*/
class CartController extends ControllerBase {
/**
* Display the cart page.
*/
public function index(): array {
return [
'#theme' => 'cart_page',
'#items' => [],
'#total' => 0,
];
}
}
Fenêtre de terminal
# Vérifier que le module est bien listé
ddev drush pm:list --filter=tailstore_cart
# Activer
ddev drush en tailstore_cart -y
# Vérifier les tables créées
ddev drush sqlq "SHOW TABLES LIKE 'tailstore%'"
# Désactiver pour test
ddev drush pm:uninstall tailstore_cart -y
  • Dossier du module créé
  • Fichier .info.yml valide
  • Fichier .module avec hooks
  • Fichier .install avec schéma
  • Permissions définies
  • Configuration par défaut
  • Module activable sans erreur

La structure est en place ! Créons les routes et controllers.