Tutoriel pour apprendre à créer une application avec Laravel 5

L'interface

Dans le développement d'une application, l'interface représente toujours une grosse partie du travail. Que nous propose Laravel 5 à ce sujet ? À vrai dire pas grand-chose. Pour les linuxiens il existe Elixir qui permet d'utiliser Gulp. Je ne vous en parlerai pas parce que j'utilise Windows et je n'ai donc aucune expérience sur le sujet.

3 commentaires Donner une note à l'article (5)

Article lu   fois.

L'auteur

Site personnel

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

I. Introduction

J'ai choisi pour l'application d'utiliser Bootstrap en employant ses fichiers LESS pour adapter le visuel. D'autre part, j'ai adopté l'approche de html5boilerplate pour l'organisation.

Laravel 5 a un dossier de ressources et des sous-dossiers :

Image non disponible

On a trois catégories de données :

  • assets : ici on va mettre nos fichiers LESS de Bootstrap ;
  • lang : ici c'est pour les fichiers de langue, pour l'application on va ajouter le français à l'anglais préexistant ;
  • views : ici on a toutes les vues de l'application.

Un autre aspect concerne le choix de l'éditeur en ligne et du gestionnaire de médias. Le choix est assez vaste. J'ai opté pour CKEditor (avec le plugin codesnippet) pour l'éditeur et Filemanager pour la gestion des médias. On va voir dans cet article comment s'effectue leur intégration.

Pour les templates j'en ai choisi deux gratuits sur le site startbootstrap. Pour le front-end : Business Casual avec cet aspect :

Image non disponible

Je l'ai prévu en deux langues : français et anglais.

Pour le back-end : SB Admin avec cet aspect :

Image non disponible

II. Bootstrap

J'aime bien Bootstrap, il est simple et puissant. Il est devenu quasiment un standard. J'ai créé un cours que je maintiens régulièrement à jour.

La meilleure manière d'adapter Bootstrap à ses besoins est d'utiliser LESS. J'ai rassemblé tous les fichiers utiles dans le dossier resources/assets :

Image non disponible

Dans le dossier bootstrap figure l'original du dossier less du framework. Il contient donc tous les fichiers originaux non modifiés :

Image non disponible

Il est ainsi facile de faire une mise à jour.

De la même façon on trouve les fichiers LESS des icônes de Font Awesome dans un dossier spécifique :

Image non disponible

On trouve ensuite deux dossiers, un pour le front-end et un pour le back-end :

Image non disponible

C'est là que figure l'adaptation de Bootstrap pour l'application. Les fichiers _main.less sont des copies modifiées du fichier boostrap.less. La compilation du framework s'effectue avec ces fichiers. Pour le front-end on ajoute deux fichiers :

 
Sélectionnez
@import "business.less";
@import "final.less";

Le fichier business.less est le template du front-end et final.less comporte quelques adaptations.

De la même façon on importe le template pour le back-end :

 
Sélectionnez
@import "sb-admin.less";

Il suffit ensuite de placer les fichiers compilés dans le dossier public :

Image non disponible

On les appelle directement des templates, par exemple pour le front-end (resources/views/front/template.blade.php) :

 
Sélectionnez
{!! HTML::style('css/main_front.css') !!}

Pour le Javascript html5boilerplate prévoit un fichier plugins.js. Il suffit d'ajouter le code de Bootstrap :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
// Évitez les erreurs `console` dans les navigateurs qui n'ont pas de console.
(function() {
    var method;
    var noop = function () {};
    var methods = [
        'assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error',
        'exception', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log',
        'markTimeline', 'profile', 'profileEnd', 'table', 'time', 'timeEnd',
        'timeStamp', 'trace', 'warn'
    ];
    var length = methods.length;
    var console = (window.console = window.console || {});
 
    while (length--) {
        method = methods[length];
 
        // Seulement des méthodes non définies.
        if (!console[method]) {
            console[method] = noop;
        }
    }
}());
 
/*!
 * Bootstrap v3.2.0 (http://getbootstrap.com)
 * Copyright 2011-2014 Twitter, Inc.
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 */
if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires 
 
// Tout le code Bootstrap 

Il faut placer ce fichier dans le dossier public :

Image non disponible

Le fichier main.js comporte un peu de code particulier pour l'application.

Le dossier js/vendor comporte les scripts préconisés par html5boilerplate ainsi que jQuery :

Image non disponible

Avec cette organisation il est facile d'apporter des modifications et de mettre à jour avec une nouvelle version de Bootstrap. Ce n'est évidemment pas la seule manière de procéder, mais je l'ai trouvée efficace à l'usage.

III. CKEditor

CKEditor est un éditeur très puissant, fiable, facile à paramétrer, et qui comporte une multitude de plugins. Pour l'utiliser j'ai opté pour une configuration particulière parce que je voulais ajouter le plugin codesnippet :

Image non disponible

Il suffit ensuite d'ajouter les langues que l'on veut :

Image non disponible

Et on a plus qu'à charger le tout ! Ensuite on place tout ça dans le dossier public :

Image non disponible

On peut aussi employer un CDN pour utiliser CKEditor, mais je n'ai pas trouvé l'intégration de plugins vraiment explicite dans ce cas, alors j'ai préféré tout charger.

L'intégration dans une vue s'effectue en chargeant la librairie :

 
Sélectionnez
{!! HTML::script('ckeditor/ckeditor.js') !!}

Puis en prévoyant un textarea :

 
Sélectionnez
{!! Form::control('textarea', 0, 'content', $errors, trans('back/blog.content')) !!}

Il faut ensuite prévoir la configuration :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
var config = {
    codeSnippet_theme: 'Monokai',
    language: '{{ config('app.locale') }}',
    height: 100,
    filebrowserBrowseUrl: '{!! url($url) !!}',
    toolbarGroups: [
        { name: 'clipboard',   groups: [ 'clipboard', 'undo' ] },
        { name: 'editing',     groups: [ 'find', 'selection', 'spellchecker' ] },
        { name: 'links' },
        { name: 'insert' },
        { name: 'forms' },
        { name: 'tools' },
        { name: 'document',    groups: [ 'mode', 'document', 'doctools' ] },
        { name: 'others' },
        //'/',
        { name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ] },
        { name: 'paragraph',   groups: [ 'list', 'indent', 'blocks', 'align', 'bidi' ] },
        { name: 'styles' },
        { name: 'colors' }
    ]
};
 
config['height'] = 400;     
 
CKEDITOR.replace( 'content', config);

Le résultat est sympathique :

Image non disponible

On trouve le bouton pour insérer du code du plugin codesnippet :

Image non disponible

Je ne vais pas entrer dans le détail de la configuration. Vous pouvez trouver toutes les explications sur le site.

IV. Filemanager

Pour utiliser Filemanager on pourrait charger tous les fichiers sur le site et les placer dans le dossier public comme on l'a fait pour CKEditor. C'est ce que j'avais fait dans un premier temps puis je me suis dit qu'il serait peut-être judicieux de créer un package. C'est ce que j'ai fait :

Image non disponible

Du coup l'intégration devient très facile, il suffit dans un premier temps de prévoir la référence dans composer.json :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
"require": {
    "php": ">=5.5.9",
    "laravel/framework": "5.2.*",
    "laravelcollective/html": "5.2.*",
    "bestmomo/filemanager": "1.1.*"
},

Ensuite il faut faire un composer update.

Il faut ensuite ajouter la référence du service provider dans la configuration (config/app.php) :

 
Sélectionnez
1.
2.
3.
App\Providers\RouteServiceProvider::class,
App\Services\Html\HtmlServiceProvider::class,
Bestmomo\Filemanager\FilemanagerServiceProvider::class,

Pour terminer il faut tout publier avec php artisan vendor:publish. On se retrouve avec un nouveau dossier :

Image non disponible

Si vous voulez comprendre comment ça fonctionne regardez le fichier filemanager.config.js  :

Image non disponible

Toute la configuration se trouve dans ce fichier. Toutes les informations concernant ce fichier se trouvent ici. Pour l'application j'ai juste modifié ces lignes :

 
Sélectionnez
"serverRoot": true,
"fileRoot": "/",
"baseUrl": false,

La chose la plus importante à gérer avec ce genre d'outil est la sécurité. Regardez le fichier filemanager/connectors/php/default.config.php :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
// Laravel init
require getcwd() . '/../../../../bootstrap/autoload.php';
$app = require_once getcwd() . '/../../../../bootstrap/app.php';
 
$kernel = $app->make('Illuminate\Contracts\Http\Kernel');
 
$response = $kernel->handle(
  $request = Illuminate\Http\Request::capture()
);
 
$id = $app['encrypter']->decrypt($_COOKIE[$app['config']['session.cookie']]);
$app['session']->driver()->setId($id);
$app['session']->driver()->start();
 
// Chemin du dossier
$folderPath = config('filemanager.folder_path');   
 
// Vérifier si l'utilisateur est authentifié
if(!$app['auth']->check()) 
{
  $laravelAuth = false;
} 
else
{
  // Vérifier si l'utilisateur a tous les droits 
  if($app['auth']->user()->accessMediasAll())
  {
    $laravelAuth = true; 
  } 
  elseif(method_exists($app['auth']->user(), 'accessMediasFolder'))
  {
    // Vérifier si l'utilisateur a accès à un dossier
    if($app['auth']->user()->accessMediasFolder())
    {
      // Nom du dossier avec identifiant utilisateur
      $folderPath .= 'user' . $app['auth']->id();
      $laravelAuth = true;  
    } 
    else
    {
      $laravelAuth = false;
    }    
  }
  else
  {
    $laravelAuth = false;
  } 
}
 
/**
 *  Vérifier si l'utilisateur est autorisé.
 *  
 *
 *  @return boolean true if access granted, false if no access
 */
function auth() 
{
  return $GLOBALS['laravelAuth'];
}
 
$fm = new Filemanager();
 
$fm->setFileRoot($folderPath, true);
 
?>

En gros on crée une application, on crée le kernel, on récupère le cookie, on lance les sessions. On a alors tout ce qu'il faut pour vérifier l'utilisateur.

On fait appel à des méthodes présentes dans le modèle User pour les droits d'accès :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
/**
 * Vérifier tous les accès aux médias
 *
 * @return bool
 */
public function accessMediasAll()
{
    return $this->role->slug == 'admin';
}
 
/**
 * Vérifier les accès aux médias d'un dossier
 *
 * @return bool
 */
public function accessMediasFolder()
{
    return $this->role->slug != 'user';
}

On va ainsi renseigner la variable $laravelAuth. On a deux cas :

  • si c'est un utilisateur qui a accès à tout (un administrateur), on se contente de mettre la valeur true ;
  • si c'est un utilisateur seulement autorisé dans son dossier personnel (un rédacteur), on détermine le nom de son dossier à partir de son id. On vérifie si ce dossier existe et si ce n'est pas le cas on le crée. Il suffit ensuite d'informer Filemanager du dossier avec la méthode setFileRoot. Ainsi chaque rédacteur sera bien cantonné à son dossier personnel.

Vous pouvez vérifier que la sécurité fonctionne bien en supprimant tous les cookies de votre navigateur et en lançant l'URL …/filemanager/index.html :

Image non disponible

L'intégration dans CKEditor est d'une grande facilité puisqu'il suffit de déclarer la bonne URL :

 
Sélectionnez
1.
2.
3.
var config = {
    ...
    filebrowserBrowseUrl: '{!! url($url) !!}',

L'URL est récupérée dans la vue avec la variable $url.

Si vous regardez dans le dossier des images de Filemanager :

Image non disponible

Vous voyez un dossier user2 qui contient les images de ce rédacteur (avec l'id 2) qui ne doit avoir accès qu'à ce dossier.

Le gestionnaire est accessible avec le bouton « Explorer le serveur » de la fenêtre de CKEditor :

Image non disponible

Pour l'accès direct aux médias à partir de l'administration, j'ai inclus Filemanager dans une i-frame :

 
Sélectionnez
1.
2.
3.
4.
<div class="iframe-responsive-wrapper">
    <img class="iframe-ratio" src="data:image/gif;base64,R0lGODlhEAAJAIAAAP///wAAACH5BAEAAAAALAAAAAAQAAkAAAIKhI+py+0Po5yUFQA7"/>
    <iframe scrolling="no" src="{!! url($url) !!}" width="640" height="360" frameborder="2" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>
</div>

Avec un visuel plutôt sympathique :

Image non disponible

Vous avez là les grandes lignes de la création de l'interface de l'application. Nous aurons sans doute l'occasion dans les prochains articles de détailler certains points…

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Copyright © 2017 Laravel. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.