Laravel

Un framework qui rend heureux

Voir cette catégorie
Vers le bas
Créer un blog - social, erreurs, traductions et événement
Mardi 9 février 2021 19:20

Nous avons dans le précédent article mis en place le formulaire de contact et les pages. Maintenant on va compléter le blog en gérant les liens sociaux. Nous allons aussi harmoniser les pages d'erreur (404 et autres) pour qu'elles conviennent à l'esthétique du blog. D'autre part on va prévoir un événement commun pour la création d'un utilisateur, un article, un contact ou un commentaire pour ensuite pouvoir notifier les personnes concernées. Enfin on va passer tous les textes en français.

Vous pouvez télécharger le code final de cet article ici.

Les liens sociaux

Dans notre blog on trouve les liens sociaux en deux emplacements :

On va rendre tout ça modifiable par l'administrateur parce que ça peut évoluer.

Pour ces liens on prévoit ces données :
  • une url
  • un titre
Et on se passera de date.

La migration

Comme on l’a fait déjà plusieurs fois on crée simultanément le modèle et la migration (on n'aura pas besoin de factory et de contrôleur) :

php artisan make:model Follow -m
On code la migration :
public function up()
{
    Schema::create('follows', function (Blueprint $table) {
        $table->id();
        $table->string('href');
        $table->string('title');
    });
}

Le modèle Follow

Dans le modèle on ajoute la propriété $fillable, on précise l'absence de date et on enlève le trait pour le factory :

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Follow extends Model
{
    protected $fillable = ['href', 'title'];

    public $timestamps = false;
}

La population

Dans DatabaseSeeder on génère 4 enregistrements :
// Social
DB::table('follows')->insert([
    ['title' => 'Twitter', 'href' => '#'],
    ['title' => 'Facebook', 'href' => '#'],
    ['title' => 'Dribbble', 'href' => '#'],
    ['title' => 'Instagram', 'href' => '#'],
]);
Vous pouvez régénérer toute la base (on est obligé pour avoir la population) :
php artisan migrate:fresh –seed
Vérifiez que vous avez bien généré les 4 enregistrements :

L'envoi des données

On va compléter HomeComposer pour envoyer systématiquement les liens sociaux :

use App\Models\{ Category, Page, Follow };

...

public function compose(View $view)
{
    $view->with([
        'categories' => Category::has('posts')->get(),
        'pages'      => Page::select('slug', 'title')->get(),
        'follows'    => Follow::all(),
    ]);
}

Les vues

On va maintenant mettre à jour le layout (font.layout) pour afficher dans le footer les liens à partir des données de la table :

<div class="column large-2 medium-3 tab-6 s-footer__social-links">
    
    <h5>@lang('Follow Us')</h5>

    <ul>
        @foreach($follows as $follow)
            <li><a href="{{ $follow->href }}">{{ $follow->title }}</a></li>
        @endforeach
    </ul>

</div>
Pour ce qui concerne le diaporama (heros) ça se passe dans la vue front.index :
<div class="s-hero__social hide-on-mobile-small">
    <p>@lang('Follow')</p>
    <span></span>
    <ul class="s-hero__social-icons">
    @foreach($follows as $follow)
        <li>
            <a href="{{ $follow->href }}">
                <i 
                    class="fab fa-{{ $follow->title === 'Facebook' ? 'facebook-f' : lcfirst($follow->title) }}" 
                    aria-hidden="true">
                </i>
            </a>
        </li>
    @endforeach
    </ul>
</div>

Vérifiez que les liens aux deux emplacements correspondent bien à ceux de la base.

Les traductions

Pour le moment notre blog est en anglais mais on a prévu les traductions de façon systématique. Il est temps de franciser les textes. Pour vous simplifier la vie je vous propose d'aller chercher les fichiers de traduction directement dans le ZIP à télécharger :

Récupérez tout, même les versions anglaises parce que j'ai ajouté des choses.

Dans le fichier config.app passez au français :

'locale' => 'fr',
Vérifiez que ça fonctionne partout :

Normalement on a tout jusqu'à la fin de ce projet...

Les pages d'erreur

On ne pense pas toujours aux pages d'erreur mais il est judicieux d'éviter d'afficher une page trop sommaire ou carrément laide. Par défaut Laravel en propose des très épurées :

On va améliorer ça en commençant par créer un layout dans un dossier dédié :
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="{{ asset('css/vendor.css') }}">
    <link rel="stylesheet" href="{{ asset('css/styles.css') }}">
    <style>
        html,
        body {
            background-color: #ccc;
        }
        body {
            text-align: center;
            text-shadow: 0 1px 3px rgba(0,0,0,.5);
        }
        .site-wrapper {
            display: table;
            width: 100%;
            height: 100%; /* For at least Firefox */
            min-height: 100%;
            -webkit-box-shadow: inset 0 0 100px rgba(0,0,0,.5);
            box-shadow: inset 0 0 100px rgba(0,0,0,.5);
        }
        .site-wrapper-inner {
            display: table-cell;
            vertical-align: middle;
        }
    </style>

</head>

<body>

    <div class="site-wrapper">
        <div class="site-wrapper-inner">
              @yield('content')
        </div>
    </div>

</body>
</html>
On ajoute une vue partielle :
<h1>{{ __('errors.error-' . $number) }}</h1>
<p class="lead">{{ __('errors.error-' . $number . '-info') }}</p>
@if($number != '503')
    <p class="lead">
        <a href="{{ url('/') }}" class="btn btn--primary">{{ __('Home') }}</a>
    </p>
@endif

On complète avec les 3 erreurs les plus classiques :

On y retrouve le même code avec juste le numéro de l'erreur qui change :

@extends('errors.layout')

@section('content')
    @include('errors.partial', ['number' => '403'])
@endsection
On a un nouvel aspect :

C'est en français grâce aux fichiers de traductions copiés précédemment.

Un événement

Le blog va vivre alors l'administrateur et les rédacteurs ont besoin d'être informés s'il se passe quelque chose. En particulier s'il y a un nouveau :

  • utilisateur
  • article
  • commentaire
  • contact

Plutôt que de créer quelque chose on va un peu détourner l'utilisation classique du système de notification de Laravel. Par défaut seul le modèle User est concerné mais on a vu dans les précédents articles que les modèles Post, Contact et Comment utilisent aussi ce système. On va ajouter un événement qui va surveille la création de l'une de ces entités et, si c'est le cas, mémoriser cette création dans la table des notifications.

Si on regarde dans EventServiceProvider on voit déjà un événement déclaré :

protected $listen = [
    Registered::class => [
        SendEmailVerificationNotification::class,
    ],
];

Comme on n'a pas prévu la vérification des emails cet événement ne nous sert à rien mais on peut le garder au cas où... On va en ajouter un autre :

use App\Events\ModelCreated;
use App\Listeners\ModelCreated as ModelCreatedListener;

...

protected $listen = [
    ...
    ModelCreated::class => [
        ModelCreatedListener::class,
    ],
];

On déclare un événement et une écoute qu'on n'a pas encore créés mais comme Laravel est très gentil on va lancer une commande Artisan :

php artisan event:generate
Et on va avoir nos classes automatiquement générées : Pour l'événement on va prévoir ce code :
<?php

namespace App\Events;

use Illuminate\ {
    Queue\SerializesModels,
    Database\Eloquent\Model,
    Foundation\Events\Dispatchable
};

class ModelCreated
{
    use Dispatchable, SerializesModels;

    public $model;

    public function __construct(Model $model)
    {
        $this->model = $model;
    }
}

Donc on se contente de transmettre le modèle concerné.

Et pour l'écoute :
<?php

namespace App\Listeners;

use App\Events\ModelCreated as EventModelCreated;
use App\Notifications\ModelCreated as ModelCreatedNotification;

class ModelCreated
{
    /**
     * Handle the event.
     *
     * @param  EventModelCreated  $event
     * @return void
     */
    public function handle(EventModelCreated $event)
    {
        $event->model->notify(new ModelCreatedNotification);
    }
}
On crée une notification pour le modèle. On crée la notification :
php artisan make:notification ModelCreated
Là on va juste préciser qu'on veut une notification dans la base :
public function via($notifiable)
{
    return ['database'];
}

Mais pour que ça fonctionne il faut déclencher l'événement, donc dans chacun des modèles User, Post, Comment et Contact on ajoute ce code :

use App\Events\ModelCreated;

...

class User extends Authenticatable
{
    ...

    protected $dispatchesEvents = [
        'created' => ModelCreated::class,
    ];
Laravel comporte un certain nombre d'événements par défaut, ici on utilise created pour le modèle.

Pour voir si ça fonctionne on va créer un utilisateur à partir du formulaire d'enregistrement. Normalement on doit avoir un enregistrement dans la table notifications :

On a les noms de l'événement et du modèle, ça nous suffira pour l'administration !

Pour un commentaire on aura :

Conclusion

Et voilà notre frontend totalement codé ! Dans le prochain article on commencera à s'occuper du backend...

 


Par bestmomo

Nombre de commentaires : 15