Les CMS

Voyager : un exemple

J’ai continué à explorer les possibilités de Voyager dont je vous ai parlé dans le précédent article. La meilleure façon de procéder était de prendre un exemple, ce que j’ai fait. J’ai imaginé, puisqu’il s’agit de voyage, un site avec possibilité d’authentification, avec des descriptions de pays avec catégories et aussi de produits sur une page.

L’application

L’application est récupérable sur Github. Pour l’installation c’est du grand classique et c’est expliqué sur Github. Il ne faut surtout pas utiliser la commande d’installation de Voyager au risque de tout casser !

Si tout se passe bien vous devriez aboutir à cette page d’accueil :

Le design est issu d’un template (Editorial) de l’excellent site Html5 up!. Je l’ai pris tel quel en lui ajoutant juste quelques règles CSS pour avoir des alertes, ce qui n’est pas prévu par défaut. Il est parfaitement responsive.

Sur l’accueil on a donc un simple page de présentation et un menu. Dans ce menu on a les classiques de l’authentification. On peut donc se connecter :

S’enregistrer :

Récupérer son mot de passe :

Il y a un utilisateur administrateur avec ces données :

  • admin@admin.com
  • password

Evidemment une fois connecté le menu change :

Pour les voyages on a un sous-menu  avec deux continents :

Histoire de tester les catégories.

Quand on choisit un continent on affiche l’image et le résumé de chacun :

On a un bouton « MORE » pour avoir le détail du pays sur une seule page :

Pour les produits j’ai prévu de tout mettre sur une seule page, sans catégories :

Le bouton « ADD TO CART » se contente d’ouvrir une fenêtre modale de confirmation et ça ne va pas plus loin.

La page d’accueil

Pour la page d’accueil j’ai utilisé les pages de Voyager :

L’édition est facile et on dispose d’un éditeur « riche » :

Ca permet de bien régler le HTML.

Au niveau du contrôleur le code est tout simple :

use TCG\Voyager\Models\Page;

...

public function __invoke()
{
    $page = Page::whereSlug('homepage')->firstOrFail();

    return view('home', compact('page'));
}

Les voyages (travels)

Les catégories

Pour les catégories j’ai utilisé l’infrastructure prévue :

On a une catégorie principale « Travels » et deux enfants « Africa » et « Europa ».

Le choix de la catégorie parente apparaît dans une boîte déroulante :

Le tout fonctionne très bien.

Les posts

Pour les pays j’ai utilisé les posts :

Le seul souci que j’ai eu c’est au départ la catégorie ne se mémorisait pas dans la base. Il a fallu que je raffraichisse le BREAD pour que ça fonctionne.

Pour l’affichage en frontend le code est facile au niveau du contrôleur :

use TCG\Voyager\Models\Category;

...

public function index($category)
{
    $category = Category::whereSlug($category)->with('posts')->firstOrFail();

    return view('posts', compact('category'));
}

Donc avec une URl de la forme …/posts/africa on obtient le résumé de tous les pays d’Afrique.

Pour simplifier je n’ai pas demandé de pagination.

Pour l’affichage d’un pays en particulier c’est tout aussi aisé :

use TCG\Voyager\Models\Post;

...

public function show($slug)
{
    $post = Post::whereSlug($slug)->firstOrFail();
    
    return view('post', compact('post'));
}

Donc avec une URL de la forme …/post/algeria on obtient l’article pour l’Algérie.

Les produits

Pour les produits, l’entité n’existait pas. Je me suis inspiré de cette vidéo très bien faite.

Il faut utiliser le bouton « Create New Table » et se laisser guider :

Le formulaire est très bien fait :

On peut ajouter toutes les colonnes qu’on veut. La table se crée sans autre intervention ! On a aussi le modèle créé automatiquement.

Il faut ensuite bien régler la visibilité de chaque colonne et le contrôle de saisie pour les différentes opérations :

Et surtout ne pas oublier les permissions pour l’administrateur :

J’ai été un peu déçu de ne pas retrouver automatiquement un widget sur l’accueil de l’administration pour mes produits :

Les widgets sont codés « en dur » dans le package.

Ca aurait quand même plus d’allure :

On devrait pouvoir paramétrer ce qu’on veut sur la page d’accueil de l’administration. J’ai d’ailleurs envoyé un PR pour ça et une discussion est en cours.

Edit : c’est désormais fait avec ce commit.

Le menu

Le menu m’a donné un peu plus de mal. Pour le créer c’est facile :

Pour l’organiser aussi :

Mais pour l’intégration, quand on sort de Bootstrap avec un sous-menu on galère un peu. Ce que j’ai fait relève un peu du bricolage :

<li>
    @foreach($items as $menu_item)
        @if($loop->first)
            <span class="opener">{{ $menu_item->title }}</span>
            <ul>   
        @else
            @if(!$menu_item->parent_id)
                </ul>
            @endif 
            <li><a href="{{ url($menu_item->url) }}">{{ $menu_item->title }}</a></li>
        @endif
    @endforeach

Mais ça fonctionne…

Je pense qu’il y aurait une amélioration à apporter ici pour bien pouvoir distinguer les niveaux des menus.

Conclusion

Le système est pratique et plutôt séduisant. On peut faire une mise en place rapide de l’administration. Il faudrait voir avec une situation plus complexe. Il faut voir également l’évolution du projet…

 

Print Friendly, PDF & Email

6 commentaires

  • carruno

    Tout d’abord bravo pour votre site, on y trouve tout ce qu’on cherche sur Laravel, et les explications sont claires.

    J’ai suivi ce tuto et j’avais un soucis avec la gestion du menu sur la gauche. Dans l’admin il s’affichait correctement, et dans l’ordre alors que sur le front l’ordre était différent, du coup les sous menu n’étaient pas à leur place.

    J’ai remanié le fichier resources\views\menu.blade.php qui s’occupe de l’affichage de ce menu, avec une méthode assez bourin mais qui fonctionne sur les tests que j’ai pu faire.

    L’idéal serait je pense, de surcharger la fonction Menu::display (vendor\tcg\voyager\src\Models\Menu.php pour y ajouter par exemple BuildEditorialOutput qui gèrerait proprement la sortie de ce menu, mais j’avoue que je ne connais pas assez Laravel pour écrire cette surcharge.

    Pour ceux que ça intéresse, je partage ma méthode bourin :


    @php
    $tab_items = [];
    foreach($items as $menu_item){
    if(!$menu_item->parent_id){
    $tab_items[$menu_item->id] = array(
    'title' => $menu_item->title,
    'url' => $menu_item->url,
    'order' => $menu_item->order
    );
    }
    }
    foreach($items as $menu_item){
    if($menu_item->parent_id){
    $tab_items[$menu_item->parent_id]['sub_items'][$menu_item->order] = array(
    'title' => $menu_item->title,
    'url' => $menu_item->url
    );
    }
    }
    @endphp

    @foreach($tab_items as $menu_item)
    @if(!isset($menu_item['sub_items']))
    {{ $menu_item['title'] }}
    @else

    {{ $menu_item['title'] }}

    @foreach($menu_item['sub_items'] as $sub_items)
    {{ $sub_items['title'] }}
    @endforeach

    @endif
    @endforeach

      • carruno

        Le code apparaît mal sur WordPress, j’ai pourtant mis des balises « code » mais c’est pas terrible, pour la prochaine fois si y’à une astuce, je suis preneur.

        Sinon t’aurais une idée sur l’override dans Laravel? J’aurais aimer faire évoluer le script vendor\tcg\voyager\src\Models\Menu.php mais sans toucher au core

  • rexdj

    Bonjour Bestmomo et merci infiniment pour les découvertes de Laravel.
    J’ai essayé ce CMS(?) et grace à ton exemple, je l’ai immédiatement adopté: Une vraie merveille.
    Par contre une question:
    J’ai créé une entite qui contient un champ image.
    en base, le chemin est enregistré vers cette image.
    Quelle pourrait etre la meilleure facon de récupérer l’url vers cette image en front ? L’idéal serait de pouvoir ecrire $monentite->image_1 par exemple.
    Merci d’avance

      • rexdj

        En fait, en affichant juste l’image avec $entite->image, il ne tient pas compte du dossier défini dans les options de voyager. J’ai donc ajouté un accesseur dans mon modèle et le problème est résolu.

        Je continue donc mon exploration de cet outil fantastique. Et Merci encore pour tes articles.

Laisser un commentaire