---
title: "Des notifications Symfony au top avec Notyf"
excerpt: "Vous avez un projet Symfony, et vous voulez des \"flash messages\" au top !? La librairie Notyf est là pour vous !"
publishDate: 2022-04-19T16:42:03.000Z
tags: ["symfony"]
canonical: "https://yoandev.co/des-notifications-symfony-au-top-avec-notyf"
---

<YouTube id="Txneiw0sVjc" />

## 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.

```bash
symfony new notyf --webapp
cd notyf
npm install
npm run build
symfony serve -d
```

* Création d'un Controlleur

```bash
symfony console make:controller NotyfController
```

* Modifions notre Controlleur pour pouvoir lui passer des paramètres par son URL

```php
<?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](https://picocss.com/)

```twig
<!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.

```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 %}

```

## Installation de la librairie Notyf et mise en place avec Webpack Encore

* Installons la librairie Notyf

```bash
npm i notyf
```

* Créons un fichier ```assets/notyf.js``` et y mettons le code suivant (pour tester !) :

```js

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```

```js
// ...
.addEntry('app', './assets/app.js')
.addEntry('notyf', './assets/notyf.js')
// ...
```

* Et enfin, utilons notre **notyf** dans notre fichier ```templates/base.html.twig```

```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```

```js

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```

```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```
    
```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```

```twig
<body>
    <main class="container">
        {% include '_notyf.html.twig' %}
        {% block body %}{% endblock %}
    </main>
</body>
```

* Nettoyage de notre fichier ```templates/notyf/index.html.twig```

```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

```php
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```

```css
#notyf-message {
    display: none;
}
```

## Code source

- [GitHub](https://github.com/yoanbernabeu/notyf-with-symfony)
