· 5 min read

Utiliser Tailwind en équipe avec Symfony

Je vous propose une approche pour utiliser Tailwind CSS en équipe dans un projet Symfony.

Je vous propose une approche pour utiliser Tailwind CSS en équipe dans un projet Symfony.

Objectifs

Dans cet article, je vais vous présenter une approche (en vrai, on va même en explorer trois !) pour utiliser Tailwind CSS en équipe, en utilisant des Twig Components réutilisables.

Comme nous l’avons vu dans l’article précédent, Tailwind CSS est un framework CSS qui permet de créer des interfaces web rapidement, en utilisant des classes utilitaires, mais la contre partie est que l’on perd en lisibilité du code, notaement pour nos templates Twig.

Point de départ

Cet article étant une suite logique de l’article précédent, nous allons partir du code source de ce dernier, c’est à dire un projet Symfony 6 vierge, avec Webpack Encore, Tailwind et Tailwind Elements installé.

Nous prendrons l’exemple de la création d’un composant card réutilisable dans notre application.

Première Approche : Utiliser les includes Twig

Pour commencer, nous allons utiliser les includes Twig pour créer nos composants réutilisables.

  • Créons un fichier _simple_card.html.twig dans le dossier templates/home de notre projet Symfony avec
<div class="block p-6 rounded-lg shadow-lg bg-white max-w-sm">
	<h5 class="text-gray-900 text-xl leading-tight font-medium mb-2">{{ title }}</h5>
	<p class="text-gray-700 text-base mb-4">
		{{ content }}
	</p>
	<a href="{{ buttonUrl }}" type="button" class=" inline-block px-6 py-2.5 bg-blue-600 text-white font-medium text-xs leading-tight uppercase rounded shadow-md hover:bg-blue-700 hover:shadow-lg focus:bg-blue-700 focus:shadow-lg focus:outline-none focus:ring-0 active:bg-blue-800 active:shadow-lg transition duration-150 ease-in-out">{{ buttonText }}</a>
</div>
  • Nous pouvons maintenant utiliser ce composant dans nos templates Twig en utilisant l’include Twig
{% extends 'base.html.twig' %}

{% block title %}Hello HomeController!{% endblock %}

{% block body %}
<div class="flex justify-center">
    {% include '_simple_card.html.twig' with {
        title: 'Titre de la carte',
        content: 'Contenu de la carte',
        buttonUrl: '#',
        buttonText: 'Cliquez ici'
    } %}
</div>

{% endblock %}

Cette approche est très simple à mettre en place, mais ne permet pas de typer les variables utilisées dans le composant.

Deuxième Approche : Embedding Controllers

Nous allons maintenant utiliser les Embedding Controllers pour créer nos composants réutilisables.

  • Dans notre fichier src/Controller/HomeController.php, nous allons créer une méthode simpleCard qui retournera le code HTML de notre composant
public function simpleCard(string $title, string $content, string $buttonUrl, string $buttonText): Response
{
    return $this->render('home/_simple_card.html.twig', [
        'title' => $title,
        'content' => $content,
        'buttonUrl' => $buttonUrl,
        'buttonText' => $buttonText,
    ]);
}
  • Utilisons ce contrôleur dans notre fichier templates/home/index.html.twig
{% extends 'base.html.twig' %}

{% block title %}Hello HomeController!{% endblock %}

{% block body %}
    <div class="flex justify-center">
        {{ render(controller('App\\Controller\\HomeController::simpleCard', {
            'title': 'Titre de la carte',
            'content': 'Contenu de la carte',
            'buttonUrl': '#',
            'buttonText': 'Cliquez ici'
        })) }}
    </div>
{% endblock %}

Cette approche est plus complexe à mettre en place, mais permet de typer les variables utilisées dans le composant. Cette méthode n’est pas vraiment recommandée pour notre cas, elle est réputée consommer plus de ressources.

Troisième Approche : Utiliser les Twig Components

  • Installez le bundle Twig Components avec la commande composer require symfony/ux-twig-component

  • Création d’un composant (partie PHP) src/Components/SimpleCardComponent.php.

<?php

namespace App\Components;

use Symfony\UX\TwigComponent\Attribute\AsTwigComponent;

#[AsTwigComponent('simple_card')]
class SimpleCardComponent
{
    public string $title;
    public string $content;
    public string $buttonText;
    public string $buttonUrl;
}

  • Création d’un composant (partie Twig) templates/components/simple_card.html.twig.
<div class="block p-6 rounded-lg shadow-lg bg-white max-w-sm">
	<h5 class="text-gray-900 text-xl leading-tight font-medium mb-2">{{ title }}</h5>
	<p class="text-gray-700 text-base mb-4">
		{{ content }}
	</p>
	<a href="{{ buttonUrl }}" type="button" class=" inline-block px-6 py-2.5 bg-blue-600 text-white font-medium text-xs leading-tight uppercase rounded shadow-md hover:bg-blue-700 hover:shadow-lg focus:bg-blue-700 focus:shadow-lg focus:outline-none focus:ring-0 active:bg-blue-800 active:shadow-lg transition duration-150 ease-in-out">{{ buttonText }}</a>
</div>
  • Utilisation du composant dans une vue Twig templates/home/index.html.twig
{% extends 'base.html.twig' %}

{% block title %}Hello HomeController!{% endblock %}

{% block body %}
<div class="flex justify-center">
    {{ component('simple_card',{
            title: 'Ceci est le titre de ma carte',
            content: 'Ceci est le contenu de ma carte',
            buttonUrl: 'https://www.google.fr',
            buttonText: 'Google'
        })
    }}
</div>

{% endblock %}

Cette approche est la plus simple et la plus cohérente à mettre en place. Elle permet de typer les variables utilisées dans le composant. C’est la méthode que je recommande, elle totalement adaptée à notre cas, et le bundle que nous utilisons est spécialement conçu pour cet usage.

Optimiser et centraliser les classes CSS

Nous allons maintenant centraliser les classes CSS utilisées dans notre composant afin de pouvoir les réutiliser dans d’autres composants. Nous allons profiter d’une possibilité offerte par TailwindCSS.

  • Modifions notre fichier assets/styles/app.scss afin de spécifier les classes CSS utilisées dans notre composant avec le @apply de TailwindCSS
@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";

@layer components {
    .yoandev-card {
        @apply block p-6 rounded-lg shadow-lg bg-white max-w-sm;
    }
    .yoandev-card-title {
        @apply text-gray-900 text-xl leading-tight font-medium mb-2;
    }
    .yoandev-card-content {
        @apply text-gray-700 text-base mb-4;
    }
    .yoandev-card-button {
        @apply inline-block px-6 py-2.5 bg-blue-600 text-white font-medium text-xs leading-tight uppercase rounded shadow-md hover:bg-blue-700 hover:shadow-lg focus:bg-blue-700 focus:shadow-lg focus:outline-none focus:ring-0 active:bg-blue-800 active:shadow-lg transition duration-150 ease-in-out;
    }
}
  • Modifions notre composant Twig templates/components/simple_card.html.twig afin d’utiliser les classes CSS centralisées
<div class="yoandev-card">
	<h5 class="yoandev-card-title">{{ title }}</h5>
	<p class="yoandev-card-content">
		{{ content }}
	</p>
	<a href="{{ buttonUrl }}" type="button" class="yoandev-card-button">{{ buttonText }}</a>
</div>
  • Et lancez la commande npm run build afin de compiler les fichiers SCSS

Conclusion

Nous avons vu comment créer un composant Twig avec TailwindCSS et Symfony avec trois approches différentes. L’approche avec les Twig Components est la plus simple et la plus cohérente à mettre en place et probablement la plus maintenable à long terme.

Avec cette méthode, nous sommes désormais en mesure de créer des composants réutilisables partout dans notre application.

Back to Blog