Traiter du Markdown avec league/commonmark

Publié le 9 mai 2022 par William Suppo
Couverture de l'article Traiter du Markdown avec league/commonmark

Découvrons ensemble comment ce paquet nous fait gagner beaucoup de temps lors de l’écriture de nos articles !

Préambule

Ce paquet est développé par The PHP League qui est à l’origine de nombreuses librairies à succès dans l’écosystème PHP.

Dans cette découverte on va installer notre paquet dans une application Laravel et la rendre disponible via un Service Provider.

Installation

Pour installer notre paquet, rien de plus simple :

1composer require league/commonmark

Ensuite, pour exploiter facilement notre service, nous allons l’injecter à notre application via un ServiceProvider que nous créons avec la commande :

1php artisan make:provider MarkdownServiceProvider

Lors de l’instanciation de notre service, nous allons lui injecter l’extension de base CommonMarkCoreExtension et nous reviendrons ensuite sur la config, voici à quoi ressemble notre ServiceProvider :

1 
2namespace App\Providers;
3 
4use Illuminate\Support\ServiceProvider;
5use League\CommonMark\Environment\Environment;
6use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
7use League\CommonMark\MarkdownConverter;
8 
9class MarkdownServiceProvider extends ServiceProvider
10{
11 public function register()
12 {
13 $this->app->singleton(MarkdownConverter::class, function ($app) {
14 $config = [];
15 
16 $environment = new Environment($config);
17 $environment->addExtension(new CommonMarkCoreExtension());
18 
19 return new MarkdownConverter($environment);
20 });
21 }
22}

Désormais, nous pouvons utiliser le service de cette manière n’importe où dans l’application :

1echo app(\League\CommonMark\MarkdownConverter::class)
2 ->convert('# Coucou'); // <h1>Coucou</h1>

Enfin, nous allons à enrichir notre service avec quelques configurations, en ajoutant un peu de couleur à notre notre balise h1 par exemple en éditant notre tableau $config :

1$config = [
2 'default_attributes' => [
3 Heading::class => [
4 'style' => 'color: red',
5 ],
6 ],
7];

Pour la prise en compte des attributs, il faut ajouter à notre $environment l’extension suivante :

1$environment->addExtension(new DefaultAttributesExtension());

Maintenant, lorsque nous utilisons notre service, on obtient :

1echo app(\League\CommonMark\MarkdownConverter::class)
2 ->convert('# Coucou'); // <h1 style="color: red">Coucou</h1>

Utilisation

On admet dans notre exemple qu’on dispose d’un modèle Post qui a une propriété content qui contient du Markdown.

Afin d’injecter proprement notre service dans un contrôleur, il est préférable de passer par le constructeur. Il nous suffit ensuite d’utiliser notre service comme dans la méthode show :

1namespace App\Http\Controllers;
2 
3use App\Models\Post;
4use League\CommonMark\MarkdownConverter;
5 
6class PostsController extends Controller
7{
8 public function __construct(protected MarkdownConverter $markdown) {}
9 
10 public function show(Post $post)
11 {
12 return $this->markdown->convert($post->content);
13 }
14}

Une autre utilisation du service peut être faite directement dans une vue.

Dans cet exemple on admet que la méthode show de notre contrôleur retourne désormais la vue posts.show dans laquelle on va injecter notre service :

1@inject('markdown', League\CommonMark\MarkdownConverter::class)
2 
3{!! $markdown->convert($post->content) !!}

En bonus, nous pouvons créer une directive Blade qui va nous simplifier l’utilisation du service dans nos vues. Pour cela on ajoute une méthode boot à notre MarkdownServiceProvider :

1public function boot()
2{
3 Blade::directive('markdown', function ($expression) {
4 return "<?php echo app(League\CommonMark\MarkdownConverter::class)->convert($expression); ?>";
5 });
6}

Ainsi dans la vue, voici comment nous pouvons dorénavant convertir le Markdown :

1@markdown($post->content)

Pour pousser la customisation du paquet en fonction de vos besoins, nous vous invitons à jeter un œil à la doc officielle.

William Suppo avatar
William Suppo
Je mange du PHP au p'tit dej', et vous ?

A lire

Autres articles de la même catégorie