Gifty #1 - Lancement de projet

Dans cet article

Cet article est le premier de la suite "10h pour créer un business en ligne". Je recommande évidemment d'avoir lu les articles précédents pour continuer. Pour rappel, ce défi consiste en la création d'une version alpha (ou POC - Proof Of Concept) d'un outil de gestion de liste-cadeaux en ligne, du type liste de mariage, de naissance ou de Noël et autres.

00:00:00

C'est parti ! Je démarre mon chronomètre en ligne, un site que j'ai l'habitude d'utiliser pour chronométrer mon temps lorsque que je travaille pour mes clients. Prendre cette habitude me permet de comparer mes estimations de temps et la durée réelle de ce que je fais. Je réfléchis généralement en point de vélocité plutôt qu'en temps pur. Mais évidemment les clients - eux - demanderont toujours une estimation de temps, qui deviendra dans leur tête une deadline contractuelle. C'est pas cool, mais c'est humain. Spoiler alert : dès qu'une tâche n'est pas triviale, un développeur aura tendance à se surestimer et ne pas prendre en compte le chaos dans son estimation ! Il convient donc généralement de doubler le temps auquel on pense d'instinct.

Un petit tour sur Spotify pour se mettre une playlist sympa. Cette première heure sera accompagnée par DoozKawa parce que je l'ai dans la tête à ce moment-là !

0 à 15 minutes

C'est parti pour les 15 premières minutes. Ce serait un projet réel, mon conseil aurait été de prendre un papier, un crayon, et de clarifier les choses. Quelles fonctionnalités souhaitent-on ? Lesquelles en must-have pour ce POC, en should-have ou en nice-to-have ? A partir de ces fonctionnalités et du scope du projet, étudier un minimum les technologies disponibles et leur intérêt pour le projet. Par exemple: pour ce genre de business, une application mobile associée paraît une bonne idée. Pour factoriser le code, une solution front en vue.js que l'on pourrait packager pour le web et pour le mobile (avec Ionic, PhoneGap, Vue Native, Cordova, peu importe) semblerait une idée pertinente. Dans cette perspective, un backend REST unique viendrait supporter le tout, en node.js pourquoi pas, histoire de rester dans la même technologie. Difficile d'en être sûr sans réellement étudier la chose, mais c'est probablement ce que j'aurais fait si c'était pour un client.

Mais là non ! Mon premier réflexe et quasi sans réflexion a été de créer un Drupal. Évidemment, avec des années d'expérience dessus je m'attends à une vélocité plus importante. Mais est-ce une bonne idée ?

Parler une certaine langue vivante plutôt qu'une autre influe-t-il sur votre manière de penser et voir le monde ? Je crois qu'il est très important de rester ouvert à de multiples technologies pour élargir son champ de vision et la manière que l'on a d'aborder un problème ou de construire un projet.

Sans la nécessité d'une application mobile accompagnatrice, un projet découplé semble certainement overkill ici et une application classique en PHP est toute indiquée. Avec framework ? Sans framework ? Drupal est un CMS, il gère du contenu, et nous allons ici gérer du contenu (les listes et leurs items), alors pourquoi pas. En tout cas, je constate que je n'ai pas beaucoup réfléchi puisqu'à la première minute mon terminal était ouvert et Drupal était en cours d'installation en local :

composer create-project drupal/recommended-project:^8 gifty

On remarquera que je pars ici sur un Drupal 8. Pour un vrai projet client, j'aurais poussé un Drupal 9 qui est plus future proof. Instinctivement, je ne vois aucune fonctionnalité vraiment avancée qui nous ferait nécessiter un module non disponible sur Drupal 9, ou qui serait dispo sur Drupal 8 et portable sur Drupal 9 autrement que trivialement. Mais dans le doute et pour ne pas perdre du temps avec de bêtes histoires de compatibilité, j'ai fait ici ce choix.

composer require drupal/devel drupal/admin_toolbar

Autre réflexe, installer le module Devel car je sais que j'aurais du code à écrire pour ce projet. Et Admin Toolbar parce que franchement… pourquoi ce module ne fait-il toujours pas partie de Drupal core ?!

En parallèle de ces commandes composer qui tournent, je cherche une image de cadeau sur Google Images. C'est inutile je le sais bien, mais trouver rapidement une icône pour ce projet le rend concret dans ma tête. C'est bête, mais c'est ainsi. Je tombe très rapidement sur cette icône libre de droit. C'est pas ouf, mais les couleurs sont tranchées et elles me serviront de base. Je garde aussi ce lien en tête au cas où.

Une fois les commandes composer terminées, j'importe mon projet nouvellement créé dans Acquia Dev Desktop et je l'ouvre en parallèle dans mon éditeur préféré à savoir PhpStorm: les choses vont pouvoir commencer !

15 à 30 minutes

Je lance mon site en local: http://gifty.dd:8083 et c'est parti pour l'installation de Drupal.

PhpStorm a terminé d'importer et indexer le projet. Drupal est reconnu automatiquement et il me suffit de valider D8 pour que tout soit configuré automatiquement.

Un petit coup dans le settings.php et l'on active settings.local.php, je passe Twig en mode debug et désactive tous les caches. Je crée également une configuration xdebug pour le projet dans PhpStorm, bref, je configure tout mon projet pour être prêt pour le développement et le debug.

Quand le tout est fini, j'installe dans Drupal les modules Devel et Admin Toolbar que j'ai précédemment récupérés.

Me voici donc face à un site Drupal fraîchement installé, parfaitement configuré pour le debug et désespérément vide.

30 minutes pour faire tout ça. Vous m'auriez demandé avant j'aurais dit que c'était l'affaire de 15 minutes. Toujours faire x2 sur ses estimations de temps : on y est ! Je crois que la recherche de logo m'a fait dériver un peu. Je suis passé par FontAwesome pour vérifier la tête de l'icône cadeau et j'ai regardé sur les sites "concurrents" du projet leur logo. Bref, internet m'a happé.

30 à 45 minutes

Bon, j'ai désormais un site Drupal vierge, ce qui signifie que techniquement, nous avons une base pas mal !

Seulement, il serait peut-être temps de réfléchir un peu maintenant parce que concrètement, je suis sur un magnifique "y'a qu'à, faut qu'on" faire des listes-cadeaux et aucun projet n'a jamais avancé ainsi ! C'est un peu léger.

Il est l'heure du papier, crayon.

Je suis vieux jeu sûrement, mais j'ai toujours un carnet et un stylo sous la main. A part cette fois où visiblement je me précipite, j'adore habituellement prendre des notes, faire des schémas, écrire les choses. Après… j'écris tellement mal que j'ai du mal à me relire, mais c'est un autre problème !

Notre site sera principalement un site type "intranet" au sens où il s'agit d'un service nécessitant majoritairement d'être connecté. Par recherche d'inspiration, j'ouvre ce genre de site en mode anonyme pour voir un peu les pages d'accueil. Spotify, Twitter, Facebook, Dropbox, etc.. J'en viens pour la page d'accueil à une idée de vue pleine page simple avec un header, un footer sous la ligne de flottaison, un formulaire de connexion à droite et une section à gauche avec un visuel attirant à définir : simple.

Il me faudra:

  • une landing principale pour l'utilisateur avec le listing de ses listes-cadeaux
  • une page profil pour éditer ses données personnelles
  • la page de la liste-cadeau en elle-même avec ses cadeaux, la possibilité d'en ajouter / éditer / supprimer
  • la définition de ce qu'est une liste-cadeaux et un élément au sein de cette liste avec leurs propriétés : Nom, Description, Lien, etc...

Il est également possible d'imaginer des tas de fonctions annexes:

  • un "mode" pour les listes-cadeau type ouvert (sans surprise) où son propriétaire voit les cadeaux réservés, et par qui, et reçoit des notifications pour le prévenir; semi-ouvert (semi-surprise) où l'on ne reçoit pas de notification et l'on ne sait pas qui a réservé le cadeau; ou encore fermé (surprise) où l'utilisateur ne sait rien.
  • les notifications du propriétaire de la liste
  • la possibilité de remercier le donateur du cadeau
  • et bien d'autres…
  • Design papier approximatif pour une frontpage
  • Brouillon d'une page de listing de liste-cadeaux
  • Brouillon de la définition des entités
Mes capacités au Pictionary sont devenues légendaires !

45 à 60 minutes

Voilà un bon quart d'heure que je griffonne et je commence à avoir plusieurs pages de croquis. En si peu de temps, c'est forcément très incomplet, mais cela me donnera une base pour la suite.

La logique aurait voulu que je commence par les fonctionnalités, mais non. Je ne sais pas trop ce qui m'a pris durant ce quart d'heure, mais j'ai voulu me faire une page blanche, je suis donc parti sur la création d'un thème custom personnalisé.

J'ai l'habitude d'écrire tout mon code moi-même. Manque de confiance dans les boilerplates ? Envies de conventions personnelles ésotérique ? Rien de tout ça, une habitude c'est tout. Pourtant ce coup-ci j'ai fait différemment, j'ai voulu accélérer en générant un maximum de choses, quittes à changer d'avis si cela devait se révéler inutile. Et pour cette génération de code, je me tourne vers Drupal Console que j'installe comme dépendance de développement via composer.

composer require --dev drupal/console

Pour le design, je vais créer un sous-thème de Classy.

Nous sommes sur une base Drupal 8 ici, donc étendre Classy ira très bien. Sur un nouveau projet Drupal 9, j'aurais tendance à partir sur une base de Stable9 voir entièrement from scratch si vous comptez fortement personnaliser votre projet. Classy a un avenir incertain pour Drupal 10, donc à voir si ce choix est réellement futureproof.
../vendor/bin/drupal generate:theme

Comme je ne sais pas tant que ça où je vais, je pars sur un thème que je nomme Gifty (gifty_theme) avec quelques régions classiques que j'affinerais ensuite: Header, Footer, Navigation, Content et deux Sidebar Left et Right.

Je rajoute un petit fichier config.rb pour mon compass et crée les dossiers associés à cette structure. C'est un bout de code dont je me sers à chaque projet de thème, donc copié/collé !

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
require 'compass/import-once/activate'
# Require any additional compass plugins here.
 
# Set this to the root of your project when deployed:
http_path = "/"
css_dir = "css"
sass_dir = "src/scss"
images_dir = "misc"
fonts_dir = "fonts"
javascripts_dir = "js"
 
# You can select your preferred output style here (can be overridden via the command line):
# output_style = :expanded or :nested or :compact or :compressed
 
# To enable relative paths to assets via compass helper functions. Uncomment:
relative_assets = true
 
# To disable debugging comments that display the original location of your selectors. Uncomment:
# line_comments = false
 
# If you prefer the indented syntax, you might want to regenerate this
# project again passing --syntax sass, or you can uncomment this:
preferred_syntax = :sass
# and then run:
# sass-convert -R --from scss --to sass sass scss && rm -rf sass && mv scss sass
 
# Compact the output
# output_style = :compressed
Structure basique de mon thème
Structure basique de mon thème

Ce fichier est directement à la racine de mon thème. Il importe un outil compass pour que les @include de fichiers présents dans ma structure scss n'importent qu'une seule fois chaque fichier au cours du projet. Ce sera très utile car je découpe mon dossier scss en multiples sous-fichiers, autant qu'il ne m'en faut. Mon CSS sera écrit en syntaxe SASS et chaque fichier src/scss/foo/bar/xxx.scss sera mappé vers un fichier css/foo/bar/xxx.css correspondant et que j'ajouterais à ma librairie global-styling au fur et à mesure.

Je crée déjà des fichiers scss vides pour mon header, mon footer et ma homepage. Je récupère mes snippets habituels sass et je me retrouve donc avec la structure de base de mon thème. 

  • Les modules préfixés d'un underscore sont des définitions ou des mixins que j'utilise habituellement. Je suis donc familier de leur nommage.
    • _colors.scss contient la définition de toutes mes couleurs. Je pars sur des tons piqués avec paint sur l'image du cadeau que j'ai choisi d'utiliser en logo. Nous avons donc un orange #E67E22, un jaune #F1C40F et un rouge #E74C3C. Mon texte sera en gris #777777 décliné en #CCCCCC et #222222. Pour l'instant, j'ai en tête un footer gris "material design" c'est à dire #303030.
      [astuce]
      Dans mes projets, j'utilise de plus en plus les variables CSS pour mes couleurs en remplaçant _colors.scss par un fichier palette.scss (ou décliné palette-light, palette-dark, palette-lemon, etc..) ce qui permet de jouer sur leur inclusion ou non dans le rendu final. Vivement que je n'ai plus aucun projet avec support IE pour m'y tourner définitivement sans avoir à gérer des polyfill IE:)
      [/astuce]
    • _fonts.scss contient des mixins en rapport avec la police d'écriture. En l'occurrence un mixin "rem" type celui-ci et quelques fonctions persos du genre.
    • _layout.scss se focalise sur les mixins relatifs à mon layout, notamment pour gérer mes breakpoint grâce à une seule et même fonction: je n'ai qu'à jouer sur mes variables de breakpoints mobile, small, medium, large etc.. J'ai les deux, une version breakpoint-down(variable) et breakpoint-up(variable) suivant que j'organise mon code en mobile first ou desktop first.
  • Le dossier base contient du css n'étant pas attribué à un composant en particulier
    • global.scss pour une sorte de fichier de normalisation des balises et de certains comportements selon mes habitudes. Du style
      * {
        box-sizing: border-box;
      }
    • layout.scss définit l'affichage de mon layout global: mes colonnes qui en mobile se stack les unes sous les autres et ce genre de chose
    • typography.scss définit la police et l'affichage de mon texte et mes titres. Bref, tout ce qui a trait à l'apparence du texte sur le site. Là encore, histoire de pas trop réfléchir, je pars sur une police que l'on retrouve dans la plupart des framework material: Roboto (la même que sur ce site).
  • Notez le découpage en sous-dossier de mon scss avec
    • components: pour un découpage du code par composants visuels
    • content: pour le css des entités de contenus. Par exemple node.scss, user.scss, view.scss, etc...
    • pages: pour du css spécifique à une page. J'ai déjà créé frontpage.scss vide car je sais que nous en aurons besoin
  • Le dossier css contient le css tel que généré par compass
  • Le dossier misc pour mes images
  • Le dossier templates que je n'ai pas encore crée ici qui contiendra mes templates d'affichage

Cette description est un peu fastidieuse et cela semble très long, mais entre deux lignes de commande pour l'installation de Console et la génération du thème, puis un peu de copier-coller de fichiers, tout cela se fait en quelques minutes à peine.

Drupal Console ne m'a pas généré le fichier gifty_theme.libraries.yml comme je m'y attendais. Erreur de ma part ou de celle de Console je ne sais pas, mais je dois donc le créer à la main.

J'ai alors le temps de créer manuellement mon fichier gifty_theme.libraries.yml contenant le code suivant: 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
global-styling:
  css:
    base:
      css/base/global.css: {}
      css/base/typography.css: {}
      css/base/layout.css: {}
    component:
      css/components/header.css: {}
      css/components/footer.css: {}
    theme:
      'https://fonts.googleapis.com/css?family=Poppins:100,200,400,300,500,600,700': { type: external, minified: true }
      'https://fonts.googleapis.com/css?family=Roboto:300,400,500,600,700,900': { type: external, minified: true }
  js:
    js/global.js: {}
  dependencies:
    - core/jquery
    - core/drupal
    - core/jquery.once
 
frontpage:
  css:
    theme:
      css/pages/frontpage.css: {}

Je poursuis par la création d'un fichier js/global.js. Je n'ai aucune idée de si j'en aurais besoin à ce stade, mais ce sera fait et il me suffira de le supprimer si non nécessaire:

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
 * Custom behavior for gifty theme.
 */
 
(function ($, Drupal) {
  'use strict';
 
  Drupal.behaviors.gifty_theme = {
    attach: function attach(context) {
 
    }
  };
})(jQuery, Drupal);
Même s'il m'arrive de gérer des projets en typescript ou ES6+ avec Babel, il faudrait vraiment que je m'y mette dans mes projets courants; d'autant que Drupal l'utilise depuis un moment ! C'est la raison pour laquelle scss est un sous-dossier de src. Il peut aussi y avoir js là-dedans !
Faute avouée à demi-pardonnée ?

Je finis sur quelques clics rapides pour me rendre dans l'administration des blocs et y glisser les éléments pré existants dans les bonnes régions de mon thème. Je supprime aussi les blocs qui ne me serviront évidemment pas à ce stade, du style la recherche, les menus admins et autres.

Bilan

Une heure de passée, déjà !

Quand je regarde ce que j'ai fait, je suis dépité. Tout cela, que j'ai fait des dizaines et des dizaines de fois dans ma vie pro, me prend encore une heure de temps. C'est impressionnant comme le temps passe vite. Suis-je si peu efficace ? J'ai bien peur que ce défi ne me fasse déchanter à ce sujet et que je finisse mes 10h avec rien.

Au cas où vous vous le demandiez, l'écriture de cet article m'a pris plus de temps encore ! Je serais sûrement plus succinct les prochaines fois, surtout si la production de code est plus importante, je ne décrirais pas tout autant, mais renverrais sur des tutos dédiés.

Vous vous demandez certainement à quoi ressemble maintenant le site ? A rien évidemment ! Nous n'avons pas encore de template avec nos régions, ni de CSS même basique, et l'on a désactivé le thème d'origine de Drupal à savoir Bartik. Visuellement, nous n'avons donc vraiment rien de plus qu'une page blanche avec un peu de texte, mais un énorme potentiel !

Visuel de notre page d'accueil toute vide
Visuel de notre page d'accueil: c'est vraiment vide !

Ajouter un commentaire

Votre nom sera affiché publiquement avec votre commentaire.
Votre email restera privé et n'est utilisé que pour vous notifier de l'approbation de ce commentaire.
Sur internet, vous pouvez être qui vous voulez. Soyez quelqu'un de bien :)