
Fatigué de jongler entre Node.jsServeur JavaScript, Webpack et un front-end JavaScriptLangage de scripting orienté objet lourd pendant que vous développez en PHPLangage de programmation s’exécutant côté serveur et permettant la création dynamique de pages web ou d'APIs. ? SymfonyFramework PHP permettant de développer des applications web. UXL'UX signifie "user experience" et définit l'ensemble des éléments permettant l'utilisation du site web de façon optimale. est la solution qui rapproche votre back-end Symfony de votre front-end moderne, sans sacrifier votre productivité ni votre confort avec Twig. Dans cet article, nous allons explorer Symfony UX étape par étape, avec des exemples concrets et directement applicables dans vos projets.
Voici notre feuille de route :
Introduit dans SymfonyFramework PHP permettant de développer des applications web. 6.3, AssetMapper transforme la façon dont vous gérez vos assets. Grâce aux Import Maps, il permet de charger vos modules ES directement dans le navigateur, sans étape de build, et souvent sans Node.js.
Note : pour des projets utilisant Sass, TypeScriptLangage de programmation basé sur JavaScript. , Vue/ReactReact est un framework de développement JavaScript populaire. ou ciblant de très anciens navigateurs, un build traditionnel peut rester nécessaire.
composer require symfony/asset-mapper symfony/asset
# si vous utilisez Stimulus
composer require symfony/stimulus-bundle
{% block javascripts %}
{% block importmap %}{{ importmap('app') }}{% endblock %}
{% endblock %}
php bin/console importmap:require bootstrap
php bin/console importmap:update
php bin/console importmap:outdated
Cette approche simplifie la maintenance et réduit la complexité de votre front-end Symfony.
Symfony Turbo (basé sur Hotwire) permet d'obtenir la vitesse d'une SPA sans écrire une ligne de JavaScriptLangage de scripting orienté objet.
La philosophie : le serveur reste la source de vérité et envoie du HTML, pas du JSON.
Les piliers de Turbo :
<body> de la page. C'est invisible et instantané.<turbo-frame>). Une action dans un frame ne rafraîchira que ce frame.Cas d'usage : une section de commentaires qui se met à jour sans recharger la page.
Étape 1 : Le template Twig (l'isolation)
Encapsulez la liste et le formulaire dans un seul <turbo-frame>.
{# templates/article/show.html.twig #}
...
<turbo-frame id="comments-section">
<h3>Commentaires ({{ article.comments|length }})</h3>
<div id="comment-list">
{% for comment in article.comments %}
<p><b>{{ comment.author }}</b> : {{ comment.content }}</p>
{% endfor %}
</div>
{# Le formulaire est DANS le même frame #}
{{ form_start(comment_form) }}
...
<button type="submit">Envoyer</button>
{{ form_end(comment_form) }}
</turbo-frame>
Étape 2 : le contrôleur PHP (standard)
Votre contrôleur reste un contrôleur Symfony standard, sans aucune modification.
// src/Controller/ArticleController.php
...
class ArticleController extends AbstractController
{
public function show(Article $article, Request $request, EntityManagerInterface $em): Response
{
//... (création du formulaire)
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
//... (sauvegarde en BDD)
$this->addFlash('success', 'Merci pour votre commentaire!');
// Important : on redirige vers la MÊME page
return $this->redirectToRoute('app_article_show', ['id' => $article->getId()]);
}
return $this->render('article/show.html.twig', [
'article' => $article,
'comment_form' => $form,
]);
}
}
La magie : Turbo intercepte la soumission. Il suit la redirection en arrière-plan, récupère la nouvelle page complète, mais n'extrait que le bloc <turbo-frame id="comments-section"> de la réponse pour remplacer l'ancien. Le résultat est une mise à jour instantanée, sans rechargement de page. Les erreurs de validation sont gérées de la même manière.
Pour les streams en temps réel, configurez Mercure ou un hub WebSocket.
Pour l'interactivité purement client-side (ex: afficher/cacher un élément), on utilise Stimulus, le "meilleur ami" de Turbo.
Sa philosophie est l'inverse de React : le HTML (écrit en Twig) pilote le JavaScript.
composer require symfony/stimulus-bundle
**data-controller**) : attache un fichier JS à un élément HTML. data-controller="hello" se lie à hello_controller.js.
-Les Actions (**data-action**) : déclenche une méthode JS depuis un événement. data-action="click->hello#greet" appelle la méthode greet() du contrôleur hello au clic.**data-target**) : permet au contrôleur JS de "trouver" des éléments. data-hello-target="output".Étape 1 : Le Twig (HTML-centric)
<div data-controller="toggle">
<div class="form-check">
{# L'action : sur "change", appelle la méthode "toggleField" #}
<input class="form-check-input"
type="checkbox"
data-action="change->toggle#toggleField"
data-toggle-target="checkbox"
>
<label>J'ai un code promo</label>
</div>
{# La cible : ce champ sera affiché/caché. #}
<div data-toggle-target="field" class="d-none mt-2">
<label>Code Promo</label>
<input type="text" class="form-control" />
</div>
</div>
Étape 2 : Le contrôleur Stimulus (générique)
Créez le fichier assets/controllers/toggle_controller.js :
import { Controller } from '@hotwired/stimulus';
// se connecte à data-controller="toggle"
export default class extends Controller {
// Définit les cibles
static targets = ["checkbox", "field"];
// Méthode appelée par data-action
toggleField() {
if (this.checkboxTarget.checked) {
this.fieldTarget.classList.remove('d-none');
} else {
this.fieldTarget.classList.add('d-none');
}
}
}
Remarque : assurez-vous que Stimulus est correctement référencé dans votre importmap si vous utilisez AssetMapper.
Ce contrôleur est 100% générique. Vous pouvez le réutiliser sur tout votre site.
Pour une UIL'UI signifie "user interface", et se compose de tous les éléments graphique d'une interface utilisateur. structurée (Alertes, Modales, Cartes), on utilise [symfony/ux-twig-component](https://ux.symfony.com/twig-component). Il apporte le "Component-Driven Development" à Twig.
Chaque composant est un couple :
src/Twig/Components/) pour la logique et les "props".templates/components/) pour le HTML.Étape 1 : Installation
composer require symfony/ux-twig-component
Étape 2 : La classe PHP
Créez src/Twig/Components/Alert.php :
// src/Twig/Components/Alert.php
namespace App\Twig\Components;
use Symfony\UX\TwigComponent\Attribute\AsTwigComponent;
class Alert
{
// Prop requis
public string $message;
// Prop optionnel
public string $type = 'success';
// Logique calculée, accessible via {{ this.icon }}
public function getIcon(): string
{
return match ($this.type) {
'danger' => 'bi:exclamation-circle-fill',
'warning' => 'bi:exclamation-triangle-fill',
default => 'bi:check-circle-fill',
};
}
}
Étape 3 : Le template Twig (le rendu)
Créez templates/components/Alert.html.twig :
{# templates/components/Alert.html.twig #}
<div class="alert alert-{{ type }} d-flex align-items-center" role="alert">
{# On appelle la méthode : {{ this.icon }} #}
<twig:ux:icon name="{{ this.icon }}" class="me-2" />
<div>
{# On affiche la prop : {{ message }} #}
{{ message }}
</div>
</div>
Étape 4 : L'Appel (la consommation)
Utilisez le dans n'importe quel template Twig :
{# Affiche une alerte de succès (type par défaut) #}
<twig:Alert message="Votre profil a été mis à jour!" />
{# Affiche une alerte d'erreur #}
<twig:Alert type="danger" message="Erreur : Le formulaire est invalide." />
Symfony UXL'UX signifie "user experience" et définit l'ensemble des éléments permettant l'utilisation du site web de façon optimale. permet de créer des applications modernes et interactives sans complexité excessive, tout en restant dans l'écosystème Symfony/Twig.
Envie de passer au niveau supérieur avec Symfony UX ? Commencez à intégrer AssetMapper, Turbo, Stimulus et Twig Components dès aujourd'hui et redonnez du rythme à votre développement Symfony !
Dans l'univers du développement mobile et multi-plateforme, difficile de passer à côté de Flutter. Ce framework signé Google a rapidement gagné en popularité grâce à sa flexibilité, ses performances et surtout son expérience de développement ultra-fluide. Vous cherchez une solution moderne pour créer des applications performantes sur plusieurs plateformes, sans multiplier les bases de code ? Flutter pourrait bien être votre meilleur allié.
3 techniques pour trouver le bon développeur pour votre projet !
Débugger en live un projet Ionic Android avec Visual Studio Code