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
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 :
Dans l'admin dans la partie contenu, je voulais un onglet menant à la liste de tous mes compétitions, comme cela :
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)
Cet article est vraiment inspirant. Moi, j’ai réussi à appréhender Rupal 8 grâce à des vidéos sur http://www.alphorm.com/tutoriel/formation-en-ligne-drupal-8-webmaster-c…. ça en valait le coup d’y jeter un coup d’œil. En tout cas, merci pour le partage.
Ajouter un commentaire