À la découverte de drupal 8 - #1 : Ma première entité

À la découverte de drupal 8 - #1 : Ma première entité

Ayant l'envie de tester Drupal 8, sans prendre trop de risques, je me suis décidé à prendre comme prétexte la création d'un site de pronostics pour l'euro 2016 (oui je m'y prends tôt).

Un petit coup de modélisation de mon schéma de données, et hop c'est parti.

Pour info, je vais tenter de faire plusieurs notes comme celle là, et autant en faire profiter tout le monde, mon code sera sur Github, au fur et à mesure, car cela évitera d'avoir des posts de 4km de long, l'adresse du projet sur Github : https://github.com/mespronos/mespronos

Le contexte

Installation du Drupal, je suis parti sur la beta 2.

Petites modifications dans le fichier settings.php pour sortir les dossiers de configurations de Drupal en dehors du docroot (donc non accessible via le web) :

$config_directories['active'] = '../config/active';
$config_directories['staging'] = '../config/staging';

Ensuite on rentre dans le vif du sujet avec la création de ma première entité drupal 8.

Je vous présente l'entité "League" qui contiendra les différentes compétitions de sport sur lesquelles des concours de pronostics seront organisés.

  • lid : Clé primaire
  • name : le nom de la compétition. Ex : "Ligue 1 2014-2015"
  • classement : doit-on calculer le classement pour ce concours ? (oui pour un championnat, non pour un mondial ou un euro)
  • status : archivé, en cours, terminé...

Mon entité sera contenue dans un module qui s’appellera "mespronos_leagues", car j'aime bien avoir un module par fonctionnalité.

Let's generate !

Pour la génération du module ainsi que de l'entité j'ai utilisé le super projet "console", que j'ai installé via composer. Je vous invite à découvrir l'installation et l'utilisation de ce module via ce tutoriel à l'adresse suivante : Créer un module Drupal 8 en 30 secondes | Flocon de toile.

J'ai donc crée mon module à l'aide de la commande suivantes

bin/console generate:module

une fois le module généré, il est temps de créer l'entité, toujours avec console, via la commande suivante : 

bin/console generate:entity:content

et là c'est magique, le contrôleur, les routes, l'entité, l'arborescence des dossiers... tout est généré automatiquement :

Encore une fois, sur la génération d'entités, tout est encore superbement expliqué sur ce site : Créer une entité Drupal 8 en 10 secondes top chrono | Flocon de toile

[scald=9:sdl_editor_representation]
 

il ne reste plus qu'à personnaliser selon nos besoins.

Ajout de propriétés

Une entité est "fieldable" c'est à dire que l'on peut très bien lui ajouter des champs via l'interface d'administration, comme l'on ferai avec un type de contenu. Mais comme vous le savez sûrement l'ajout d'un champ entraîne la création de deux tables (une pour la valeur, et une pour les révisions) ainsi une baisse de performance lors de l'affichage de notre contenu car cela génère forcement des jointures.

Une autre possibilité offerte par les entités est de définir des propriétés, c'est à dire des attributs qui seront présents directement dans la même table que notre entité.

Il faut pour cela modifier la méthode baseFieldDefinitions de notre entité (dans le fichier src/Entity/League.php)

Voici un exemple de code pour ajouter mon attribut "classement", qui est un booléen non affiché en front, mais présent sur le formulaire d'administration.

$fields['classement'] = BaseFieldDefinition::create('boolean')
  ->setLabel(t('Classement activé'))
  ->setDescription(t('Doit-on calculer le classement entre les équipes pour cette competitions'))
  ->setDisplayConfigurable('form', TRUE)
  ->setDisplayConfigurable('view', TRUE)
  ->setDefaultValue(TRUE)
  ->setDisplayOptions('form', array(
    'type' => 'boolean_checkbox',
    'settings' => array(
      'display_label' => TRUE,
    )
  ))
  ->setDisplayOptions('view', array(
    'type' => 'hidden',
  ));

Pour voir l'intégralité de mes modifications, vous pouvez consulter le fichier sur github : https://github.com/mespronos/mespronos/blob/8.x-1.x/src/Entity/League.p…

Personnalisation des routes et du menu

Dernier point que je souhaiter modifier, les routes et le menu. Dans drupal 8 le HOOK_menu n'existe plus, tout à été remplacé par de la configuration dans des fichiers YAML (welcome Symfony)

Les routes sont les chemins d'accès, et sont défini dans le fichier mespronos_leagues.routing.yml.

Les éléments de menu sont eux dispatchés dans plusieurs fichiers suivant leur type :

[scald=10:sdl_editor_representation]
drupal7menutodrupal8.png, par https://www.drupal.org/node/2118147

Dans l'admin dans la partie contenu, je voulais un onglet menant à la liste de tous mes compétitions, comme cela :

[scald=11:sdl_editor_representation]
 

J'ai donc pour cela modifié le fichier mespronos_leagues.routing.yml et ajouté les lignes suivantes :

league.list:
  title: 'Compétitions'
  route_name: league.list
  description: 'Liste de toutes les compétitions'
  base_route: system.admin_content

C'est tout pour aujourd'hui, n'hésitez pas à consulter mon code sur github, j'ai mis l'intégralité de ce module, et j'ajouterai au fur et à mesure la suite. Si vous voyez des erreurs, des améliorations, n'hésitez-pas à me faire des push-request.

Le projet sur github : https://github.com/kgaut/mespronos

Quelques liens qui m'ont beaucoup servis :

Commentaires

Avec cette facon de faire, en utilisant BaseFieldDefinition donc,
il n'est plus possible d'avoir de système de versionning pour cette entité ?

Bonjour,

Si il est toujours possible de définir une entité comme "revisionable" via les annotations.

Hey KGaut,

Question naïve de débutant, quel est l'intérêt d'une entité par rapport à un contenu ("Node") ? J'ai l'impression que, tant que tu n'as pas besoin de mettre en place des méthodes custom dans l'entité, la création de Node est plus adaptée et permet plus de choses. De plus les modules type Token, PathAuto & co semblent gérer automatiquement les éléments de contenu, mais nécessitent la mise en place de hook pour les ContentEntity.
Si c'est le cas, c'est étonnant que drupalconsole ne propose pas de méthode generate:entity:node. Il me manque peut-être une info ?

En fait le type d'entité node amène son lot de paradigmes : une url, une page pour voir le contenu et d'autres qui ne sont pas forcement nécessaires pour tous les besoins.

Si on imagine un contenu de type "article de blog", pour lui effectivement, on veut une url, un affichage sur une page... donc on va créer un bundle d'entitée node : en gros, un type de contenu.

Si maintenant on envisage un témoignage, que l'on veut afficher en slider en bas d'un site de vente en ligne par exemple. (un nom, quelques lignes de texte et une photo...) pour cela pas besoin d'url, on veut juste le gerer comme un contenu annexe, et donc pour cela on ira plus utiliser une entitée custom. (même si effectivement au début on va avoir tendance à utiliser des nodes quand même).

est-ce que c'est plus clair ?

D'accord, c'est bien la conclusion à laquelle j'étais arrivée. En gros, si l'objet doit disposer d'une page propre accessible par URL, il vaut mieux s'orienter vers un Node.
Mais ça m'étonnait que tu créée direct une entité sans préciser comment ça se traduirait en front, et pourquoi tu n'expliquais pas ton choix Entity vs. Node.

Je ne sais pas si tu as vu, mais la dernière version de Drupal Console permet de générer des types de contenus avec `generate:contenttype` (https://github.com/hechoendrupal/DrupalConsole/releases/tag/0.8.4)

Ajouter un commentaire

Ne sera pas publié
CAPTCHA
Désolé, pour ça, mais c'est le seul moyen pour éviter le spam...