Traiter du Markdown avec league/commonmark

Publié par William

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 :

composer 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 :

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


namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use League\CommonMark\Environment\Environment;
use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
use League\CommonMark\MarkdownConverter;

class MarkdownServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->singleton(MarkdownConverter::class, function ($app) {
            $config = [];

            $environment = new Environment($config);
            $environment->addExtension(new CommonMarkCoreExtension());

            return new MarkdownConverter($environment);
        });
    }
}

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

echo app(\League\CommonMark\MarkdownConverter::class)
    ->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 :

$config = [
    'default_attributes' => [
        Heading::class => [
            'style' => 'color: red',
        ],
    ],
];

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

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

Maintenant, lorsque nous utilisons notre service, on obtient :

echo app(\League\CommonMark\MarkdownConverter::class)
    ->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 :

namespace App\Http\Controllers;

use App\Models\Post;
use League\CommonMark\MarkdownConverter;

class PostsController extends Controller
{
    public function __construct(protected MarkdownConverter $markdown) {}

    public function show(Post $post)
    {
        return $this->markdown->convert($post->content);
    }
}

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 :

@inject('markdown', League\CommonMark\MarkdownConverter::class)

{!! $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 :

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

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

@markdown($post->content)

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