· 5 min read
Des notifications Symfony au top avec Notyf
Vous avez un projet Symfony, et vous voulez des "flash messages" au top !? La librairie Notyf est là pour vous !
Objectifs
Dans ce court article nous allons découvrir la librairie Notyf, et comment la mettre en place dans un projet Symfony. A l’issue de ces quelques exemples, nous serons capable d’emettre de belles notifications, et de les gérer facilement.
Création d’un “mini projet” Symfony
Histoire d’avoir un support à notre démonsration, nous allons créer un projet Symfony.
- Création du projet et mise en place de Webpack Encore.
symfony new notyf --webapp
cd notyf
npm install
npm run build
symfony serve -d
- Création d’un Controlleur
symfony console make:controller NotyfController
- Modifions notre Controlleur pour pouvoir lui passer des paramètres par son URL
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class NotyfController extends AbstractController
{
#[Route('/{notyf}', name: 'app_notyf')]
public function index(?string $notyf = null): Response
{
return $this->render('notyf/index.html.twig', [
'notyf' => $notyf,
]);
}
}
-
Supprimons le contenu du fichier
assets/styles/app.css
et lançons le modenpm run watch
-
Modifions notre fichier
templates/base.html.twig
pour y utiliser pico.css
<!DOCTYPE html>
<html data-theme="dark">
<head>
<meta charset="UTF-8">
<title>{% block title %}Welcome!{% endblock %}</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://unpkg.com/@picocss/pico@latest/css/pico.min.css">
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 128 128%22><text y=%221.2em%22 font-size=%2296%22>⚫️</text></svg>">
{# Run `composer require symfony/webpack-encore-bundle` to start using Symfony UX #}
{% block stylesheets %}
{{ encore_entry_link_tags('app') }}
{% endblock %}
{% block javascripts %}
{{ encore_entry_script_tags('app') }}
{% endblock %}
</head>
<body>
<main class="container">
{% block body %}{% endblock %}
</main>
</body>
</html>
- Modifions également notre fichier
templates/notyf/index.html.twig
pour pouvoir afficher notre message et un petit menu.
{% extends 'base.html.twig' %}
{% block title %}Notyf 🚀
{% endblock %}
{% block body %}
<nav>
<ul>
<li>
<strong>Notyf 🚀</strong>
</li>
</ul>
<ul>
<li><a href="{{ path('app_notyf', {'notyf': 'success'}) }}" role="button">Success</a></li>
<li><a href="{{ path('app_notyf', {'notyf': 'info'}) }}" role="button">Info</a></li>
<li><a href="{{ path('app_notyf', {'notyf': 'warning'}) }}" role="button">Warning</a></li>
<li><a href="{{ path('app_notyf', {'notyf': 'error'}) }}" role="button">Error</a></li>
</ul>
</nav>
<article>
<h1>{{ notyf }}</h1>
</article>
{% endblock %}
Installation de la librairie Notyf et mise en place avec Webpack Encore
- Installons la librairie Notyf
npm i notyf
- Créons un fichier
assets/notyf.js
et y mettons le code suivant (pour tester !) :
import { Notyf } from 'notyf';
import 'notyf/notyf.min.css'; // for React, Vue and Svelte
// Create an instance of Notyf
const notyf = new Notyf();
// Display an error notification
notyf.error('Please fill out the form');
- Puis, apellons notre fichie dans la configuration de Webpack Encore
webpack.config.js
// ...
.addEntry('app', './assets/app.js')
.addEntry('notyf', './assets/notyf.js')
// ...
- Et enfin, utilons notre notyf dans notre fichier
templates/base.html.twig
{% block stylesheets %}
{{ encore_entry_link_tags('app') }}
{{ encore_entry_link_tags('notyf') }
{% endblock %
{% block javascripts %}
{{ encore_entry_script_tags('app') }}
{{ encore_entry_script_tags('notyf') }}
{% endblock %}
Amélioration de notre gestion des notifications
- Améliorons notre fichier
assets/notyf.js
import { Notyf } from 'notyf';
import 'notyf/notyf.min.css';
// Create an instance of Notyf
const notyf = new Notyf({
duration: 5000,
position: {
x: 'right',
y: 'top',
},
types: [
{
type: 'info',
background: '#00bfff',
icon: false
},
{
type: 'warning',
background: '#ffd700',
icon: false
},
]
});
let messages = document.querySelectorAll('#notyf-message');
messages.forEach(message => {
if (message.className === 'success') {
notyf.success(message.innerHTML);
}
if (message.className === 'error') {
notyf.error(message.innerHTML);
}
if (message.className === 'info') {
notyf.open({
type: 'info',
message: '<b>Info</b> - ' + message.innerHTML,
});
}
if (message.className === 'warning') {
notyf.open({
type: 'warning',
message: '<b>Warning</b> - ' + message.innerHTML
});
}
});
- Puis adaptons notre fichier
templates/notyf/index.html.twig
{% extends 'base.html.twig' %}
{% block title %}Notyf 🚀
{% endblock %}
{% block body %}
<nav>
<ul>
<li>
<strong>Notyf 🚀</strong>
</li>
</ul>
<ul>
<li><a href="{{ path('app_notyf', {'notyf': 'success'}) }}" role="button">Success</a></li>
<li><a href="{{ path('app_notyf', {'notyf': 'info'}) }}" role="button">Info</a></li>
<li><a href="{{ path('app_notyf', {'notyf': 'warning'}) }}" role="button">Warning</a></li>
<li><a href="{{ path('app_notyf', {'notyf': 'error'}) }}" role="button">Error</a></li>
</ul>
</nav>
<article>
<h1>{{ notyf }}</h1>
</article>
<div id="notyf-message" class={{ notyf }}>{{ notyf }}</div>
{% endblock %}
Refactoring de notre code
- Créons un fichier
templates/_notyf.html.twig
{% for message in app.flashes('success') %}
<div id="notyf-message" class="success">{{ message }}</div>
{% endfor %}
{% for message in app.flashes('info') %}
<div id="notyf-message" class="info">{{ message }}</div>
{% endfor %}
{% for message in app.flashes('warning') %}
<div id="notyf-message" class="warning">{{ message }}</div>
{% endfor %}
{% for message in app.flashes('error') %}
<div id="notyf-message" class="error">{{ message }}</div>
{% endfor %}
- Appellons ce fichier dans notre fichier
templates/base.html.twig
<body>
<main class="container">
{% include '_notyf.html.twig' %}
{% block body %}{% endblock %}
</main>
</body>
- Nettoyage de notre fichier
templates/notyf/index.html.twig
{% extends 'base.html.twig' %}
{% block title %}Notyf 🚀
{% endblock %}
{% block body %}
<nav>
<ul>
<li>
<strong>Notyf 🚀</strong>
</li>
</ul>
<ul>
<li><a href="{{ path('app_notyf', {'notyf': 'success'}) }}" role="button">Success</a></li>
<li><a href="{{ path('app_notyf', {'notyf': 'info'}) }}" role="button">Info</a></li>
<li><a href="{{ path('app_notyf', {'notyf': 'warning'}) }}" role="button">Warning</a></li>
<li><a href="{{ path('app_notyf', {'notyf': 'error'}) }}" role="button">Error</a></li>
</ul>
</nav>
<article>
<h1>{{ notyf }}</h1>
</article>
{% endblock %}
- Adapatons notre controlleur
src/Controller/NotyfController.php
pour utiliser le sytème de “Flash message” de Symfony
class NotyfController extends AbstractController
{
#[Route('/{notyf}', name: 'app_notyf')]
public function index(?string $notyf = null): Response
{
if (null != $notyf) {
$this->addFlash($notyf, 'This is a '.$notyf.' flash message.');
}
return $this->render('notyf/index.html.twig', [
'notyf' => $notyf,
]);
}
}
- Et enfin, cachons le message en dehors du toast en ajoutant un bout de css dans
assets/styles/app.css
#notyf-message {
display: none;
}
Code source
Share: