Les CMS

Orchid

Orchid est un outil open source destiné à faire gagner du temps dans le développement de la partie administration avec Laravel. Il propose de simplifier la création de formulaires, interface, autorisations, menus, notifications…

Edit au 20/08/2020 : j’ai enrichi mon article en poursuivant les investigations dans Orchid.

Au niveau architectural on a une division en 3 niveaux :

Pourquoi pas ? Voyons ça d’un peu plus près…

Installation

Il faut commencer par créer une application classique Laravel :

composer create-project laravel/laravel orchid "7.*" --prefer-dist

Et évidemment une base de données associée avec une configuration correcte pour y accéder.

Et ensuite on installe Orchid :

composer require orchid/platform

Puis :

php artisan orchid:install

On a des copies de dossiers et fichiers et aussi des migrations, on se retrouve avec 10 tables :

Il faut ensuite créer un super administrateur :

php artisan orchid:admin admin admin@admin.com password

On lance un serveur local et avec l’url …/dashboard on arrive sur cette page de connexion à l’administration :

On accède alors à l’administration en se connectant :

Bon déjà l’installation s’est bien passée !

On se lance

Avec Orchid il faut comprendre la notion de classe Screen. Ça représente ce que l’utilisateur voit et ses possibilités d’interaction. On ne va plus avoir de contrôleur ou de vues mais des screens. Bon on va voir ça avec un exemple (je m’inspire largement du quick start de la documentation) …

On va imaginer un formulaire de contact, on commence par créer un screen :

php artisan orchid:screen ContactScreen

On a cette trame de code :

<?php

namespace App\Orchid\Screens;

use Orchid\Screen\Screen;

class ContactScreen extends Screen
{
    /**
     * Display header name.
     *
     * @var string
     */
    public $name = 'ContactScreen';

    /**
     * Display header description.
     *
     * @var string
     */
    public $description = 'ContactScreen';

    /**
     * Query data.
     *
     * @return array
     */
    public function query(): array
    {
        return [];
    }

    /**
     * Button commands.
     *
     * @return Action[]
     */
    public function commandBar(): array
    {
        return [];
    }

    /**
     * Views.
     *
     * @return Layout[]
     */
    public function layout(): array
    {
        return [];
    }
}

Pour accéder au screen on va créer une route, on ferait pareil pour un contrôleur. On a un fichier spécial pour ces routes :

use App\Orchid\Screens\ContactScreen;

...

Route::screen('contact', ContactScreen::class)->name('platform.contact');

Maintenant avec l’url …/dashboard/contact on arrive ici :

On peut changer les libellés dans la classe :

public $name = 'Prise de contact';
public $description = 'Formulaire de prise de contact rapide';

On va maintenant définir le contenu (ça se passe dans la fonction layout) :

use Orchid\Screen\Fields\Input;
use Orchid\Screen\Fields\Quill;
use Orchid\Screen\Layout;

...

public function layout(): array
{
    return [
      Layout::rows([
        Input::make('name')
            ->title('Nom du contact')
            ->required()
            ->placeholder('Nom du contact')
            ->help('Entrez ici le nom du contact'),

        Quill::make('message')
            ->title('Message')
            ->required()
            ->placeholder('Entrez votre message ici ...')
            ->help('Composez le message que vous voulez transmettre à cette personne')
      ])
    ];
}

Et là c’est magique :

On va ajouter un bouton de soumission (cette fois ça se passe dans la fonction commandBar) :

use Orchid\Screen\Actions\Button;

...

public function commandBar(): array
{
    return [
      Button::make('Envoyer le message')
        ->icon('icon-paper-plane')
        ->method('sendMessage')
    ];
}

Et il apparaît un bouton :

Il ne reste plus qu’à coder la fonction de traitement de la soumission (sendMessage) :

use Illuminate\Http\Request;
use Orchid\Support\Facades\Alert;

...

public function sendMessage(Request $request)
{
    $request->validate([
        'name'    => 'required',
        'message' => 'required|min:50'
    ]);
    
    // Ici on place le code pour envoyer effectivement ce message

    Alert::info('Votre message a bien été envoyé !');
    return back();
}

On vérifie la validation :

Et le message si ça fonctionne bien :

On peut ajouter facilement un lien vers ce formulaire de contact dans le menu latéral (on change dans App\Orchid\PlatformProvider) :

public function registerMainMenu(): array
{
    return [
        ItemMenu::label('Prise de contact')
            ->icon('icon-envelope-letter')
            ->route('platform.contact')
            ->title('Outils'),

...

On peut ainsi construire rapidement une administration !

On voit tout de suite l’avantage de cette approche : on n’a plus à se préoccuper de créer des vues et des contrôleurs, on a que du PHP dans une seule classe avec des fonctions prédéfinies.

J’ai regardé les fichiers de langues et apparemment il n’y a pas de français qui se soit penché dessus :

Alors on va garder ça en anglais !

Edit : j’ai envoyé un PR au projet pour la traduction française.

L’interface

Il y a des pages d’exemples avec l’installation. On peut voir qu’on dispose de nombreux contrôles pour les formulaires avec un aspect assez sobre :

Pour chaque contrôle on dispose d’une fonction, par exemple pour créer un select :

Select::make('select')
    ->options([
        'h'   => 'Homme',
        'f' => 'Femme',
    ])
    ->title('Faites un choix');

Mais on peut aussi dire d’aller chercher les informations dans la base :

Select::make('posts')->fromModel(Post::class, 'title');

On dispose d’un contrôle tout prêt par exemple pour les dates :

On peut aussi facilement créer une feuille modale :

public function layout(): array
{
    return [
        Layout::modal('maModale', [
            Layout::rows([]),
        ]),
    ];
}

Pour les éditeurs de texte on a le choix :

  • SimpleMDE
  • Quill
  • TinyMCE

On a des cartes toutes prêtes avec une construction également complète en PHP :

Les possibilités sont vraiment étendues et je ne vais pas toutes les évoquer ici.

Les tableaux

S’il est quelque chose qu’on utilise beaucoup dans une administration ce sont les tableaux. Voyons comment Orchid les gère…

Dans les exemples on a déjà un tableau défini pour les utilisateurs :

La table est définie dans une propriété :

public $target = 'users';

On définit les cellules du tableau avec une fonction TD, par exemple ici pour le nom :

TD::set('name', __('Name'))
    ->sort()
    ->cantHide()
    ->filter(TD::FILTER_TEXT)
    ->render(function (User $user) {
        return new Persona($user->presenter());
    }),

Là aussi on dispose de très nombreuses possibilités pour le tri, les filtres, les actions…

On accède à ce tableau avec l’url …/dashboard/users :

On a même la modification qui fonctionne et aussi la pagination !

Évidemment pour gérer cette page on a un screen :

C’est là qu’on définit les données qu’on utilise, les layouts, et aussi les fonctions pour la modification et la suppression des utilisateurs.

Le layout

Il y a quelque chose qui me gêne dans la perte d’espace horizontal sur les écrans larges, c’est un peu dommage, alors je me suis demandé quelle était la solution la plus simple pour intervenir sur la mise en page.

Les vues et les styles se trouvent dans les dossiers du vendor donc aucune possibilité de ce côté là.

En regardant dans la configuration (config/platform.php) par contre j’ai trouvé quelque chose d’intéressant ici :

/*
|--------------------------------------------------------------------------
| Dashboard Resource
|--------------------------------------------------------------------------
|
| Automatically connect the stored links.
|
| Example: '/application.js', '/style/classic/ui.css'
|
*/

'resource' => [
    'stylesheets' => [],
    'scripts'     => [],
],

On peut donc injecter du style ou du Javascript, alors j’ai créé un petit fichier CSS :

Avec ce code :

.container-lg {
    max-width: 100%;
}

Et évidemment j’informe la configuration :

'resource' => [
    'stylesheets' => ['/css/orchidfluid.css'],
    'scripts'     => [],
],

Et maintenant on occupe toute la largeur quelle que soit la résolution !

Tant qu’on y est on peut aussi changer le titre. On crée une vue :

Avec ce code :

<p class="h2 n-m font-thin v-center">
    <i class="icon-database"></i>
    <span class="m-l d-none d-sm-block">
        Mon Site
        <small class="v-top opacity">Le meilleur</small>
    </span>
</p>

On informe Orchid qu’elle existe (config.platform) :

'template' => [
    'header' => 'header',
    'footer' => null,
],

Et c’est fait :

Un gestionnaire de fichiers

Une chose qui est souvent très utile dans une administration c’est la gestion de fichiers, souvent d’images. Il n’y a rien de prévu par défaut dans Orchid. Alors je me suis demandé s’il était facile d’en glisser un…

Il existe plusieurs packages pour gérer des fichiers, personnellement j’aime bien celui-ci :

On va commencer par l’installer :

composer require unisharp/laravel-filemanager
php artisan vendor:publish --tag=lfm_config
php artisan vendor:publish --tag=lfm_public

Ensuite normalement on crée un lien symbolique pour utiliser le dossier storage. Personnellement je n’aime pas ces liens symboliques et je préfère mettre directement mes fichiers dans le dossier public, après tout c’est celui qui est… public.

Il faut alors changer la configuration du disque public (config/filesystems) :

'public' => [
    'driver' => 'local',
    'root' => public_path(),
    'url' => env('APP_URL'),
    'visibility' => 'public',
],

Pour terminer il faut créer les routes :

use UniSharp\LaravelFilemanager\Lfm;

...

Route::prefix('laravel-filemanager')->middleware('auth')->group(function () {
  Lfm::routes();
});

Maintenant notre gestionnaire de fichier est prêt mais comment l’inclure dans Orchid ?

On va créer un screen :

php artisan orchid:screen FilesScreen

Pour le layout on va créer notre propre fichier Blade :

Et dedans on met un i-frame :

<iframe id="files"
    title="files"
    frameborder="0"
    style="position:absolute;top:0;left:0;width:100%;height:100%;"
    src="{{ url('laravel-filemanager') }}">
</iframe>

Dans la fonction layout du screen (FilesScreen) on déclare cette vue :

use Orchid\Screen\Layout;

...

public function layout(): array
{
    return [
          Layout::view('files'),
    ];
}

On ajoute une route dans routes.platform :

use App\Orchid\Screens\FilesScreen;

...

Route::screen('fichiers', FilesScreen::class)->name('platform.files');

Et maintenant avec l’url ../dashboard/fichiers on a le gestionnaire qui s’affiche et qui fonctionne :

Il ne nous reste plus qu’à ajouter un élément dans le menu (PlatformProvider) :

ItemMenu::label('Fichiers')
    ->icon('icon-folder')
    ->route('platform.files'),

Et c’est terminé !

On voit qu’il est finalement facile d’ajouter un gestionnaire de fichier !

Mais en continuant à explorer les possibilités d’Orchid je me suis rendu compte qu’il gère déjà les images lorsqu’on intègre un éditeur de texte genre TniyMCE et qu’on insère une image. Ces images sont classées par date dans le dossier public :

C’est le même système de dossiers temporels utilisé par WordPress. Mais du coup ce n’est pas trop compatible avec le gestionnaire de fichier que j’ai installé…

Par défaut le gestionnaire de fichiers crée un dossier par utilisateur en prenant comme nom de dossier l’id dans la table users. On peut changer ce comportement en modifiant la configuration (config.lfm.php) :

//'private_folder_name'      => UniSharp\LaravelFilemanager\Handlers\ConfigHandler::class,
'allow_multi_user'         => false,

On va faire en sorte qu’Orchid et le gestionnaire utilisent le même dossier. Par exemple dans config.filesystems on peut créer un disque :

'files' => [
    'driver' => 'local',
    'root' => public_path('files'),
    'url' => env('APP_URL') . '/files',
    'visibility' => 'public',
],

Et on pointe dessus pour Orchid (config.platform) :

'attachment' => [
    'disk'      => 'files',
    'generator' => \Orchid\Attachment\Engines\Generator::class,
],

Maintenant tous les attachement d’Orchid (y compris les images téléchargées à partir des éditeurs de texte) iront dans ce dossier.

On charge une image par exemple avec Quill :

L’image se place bien dans le dossier prévu :

Et on peut la gérer avec le gestionnaire :

L’image est automatiquement référencée comme attachement dans la table attachments :

Orchid propose un trait Attachable à ajouter aux modèles pour relier les images à des enregistrements dans la table. Je n’ai pas exploré cette possibilité mais ça me rappelle le package laravel-medialibrary qui fait la même chose. La documentation est ici.

Conclusion

La plateforme Orchid est très bien faite et, si elle demande un peu de temps pour être prise en main et maîtrisée, peut faire gagner beaucoup de temps dans l’élaboration d’une administration de site.

Je suis loin d’avoir évoqué toutes les possibilités dans cet article, comme les permissions, les notifications, la recherche…

J’ai essayé de nombreux outils pour la réalisation d’une administration et chaque fois je me sentais trop limité ou trop dirigé. Avec Orchid je n’ai pas cette sensation. Il faudrait évidemment l’utiliser concrètement pour un projet pour m’en faire une idée précise. Mais ma première impression est très positive. Si quelqu’un utilise déjà cette plateforme et peut nous dire ce qu’il en pense !

 

Print Friendly, PDF & Email

4 commentaires

  • phildid

    Salut best Momo

    Ça m’a l’air pas mal du tout cette Orchid avec une admin qui a l’air du tonnerre. Naturellement peut être un peu grand pour moi mais je trouve que c’est peut être l’avenir et que çà vaut le coup de se pencher dessus pour une installation future sur un serveur de production. Hostinger propose l’install de Laravel ( d’après eux 450 M) c’est quand même lourd. Donc avec une admin sûre et des automatisations de formulaires, çà peut devenir intéressant. Donc peut être nous en reparleras-tu. Pour ma part, pas trop le temps en ce moment; des déménagements en vue et bientôt la rentrée des classes, mais je suis abonné. Je viens de me remettre au SVG sur inkscape pour changer un peu A+

    PhilDid

Leave a Reply