5 min de lecture

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 !

Vous avez un projet Symfony, et vous voulez des "flash messages" au top !? La librairie Notyf est là pour vous !
Mode de lecture :
Voir la vidéo

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 mode npm 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

Back to Blog

Comments (0)

Loading comments...

Leave a Comment