Laravel

Un framework qui rend heureux

Voir cette catégorie
Vers le bas
Laravel 4 : chapitre 8 : Blade
Dimanche 20 janvier 2013 14:54

Mis à jour avec Bootstrap 3.

Pour le moment nous avons utilisé du PHP pur dans nos vues pour générer le code HTML qui va bien. C'est une méthode simple et efficace mais certains lui reprochent sa lourdeur syntaxique. On peut aussi arguer du fait que PHP a après tout été conçu à la base pour ça et qu'il le fait très bien avec des performances louables. Pour ceux qui s'en contentent c'est parfait, pour les autres des moteurs de template ont été créés. Laravel n'échappe pas à la règle et propose aussi son moteur : Blade. Je vous propose de le découvrir aujourd'hui.

Syntaxe de base

Lorsqu'on veut insérer une donnée avec PHP on utilise cette syntaxe :

<?php echo $valeur ; ?>

On peut aussi utiliser la syntaxe  courte (avec PHP 5.4 ou si short_open_tag est activé) :

<?= $valeur ?>

Avec Blade on a cette syntaxe :

{{ $valeur }}
Blade va gentiment transformer ça en :
<?php echo $valeur ; ?>

Pour "échapper" (application de htmlentities) le texte il faut utiliser la triple accolade (il y a eu de chaudes discussions sur les forums pour définir cela) :

{{{ $valeur }}}

Les conditions

Heureusement Blade ne s'arrête pas à cette substitution. Il permet aussi de simplifier l'écriture de conditions. Prenons le cas très fréquent du foreach. Créez une vue avec ce code, nommez-la conditions :

<?php
	foreach($data as $element) {
		echo $element.'<br>';
	}
?>
Créez cette route :
Route::get('/', function()
{
	$data = array('un','deux','trois','quatre');
	return View::make('conditions')->with('data', $data);
});
Si vous entrez l'URL http://localhost/laravel/public/ vous devez voir s'afficher : un deux trois quatre

Voyons l'équivalent avec Blade. Renommez votre vue conditions.blade.php et entrez ce code :

@foreach ($data as $element)
	{{ $element }}<br>
@endforeach

Normalement vous devez obtenir le même résultat. Voyons d'autres syntaxes maintenant que vous avez compris le principe. Remplacez le code de la vue avec celui-ci :

@for ($i =0; $i < count($data); $i++)
	{{ $data[$i] }}<br>
@endfor

Le résultat est évidemment le même. Entrez maintenant  ce code :

@foreach ($data as $element)
	@if ($element == 'un')
		<p>Je suis le premier et je suis {{$element}} !</p>
	@else
		<p>Je ne suis pas le premier et je suis {{$element}} !</p>
	@endif
@endforeach

Cette fois le résultat est :

Je suis le premier et je suis un ! Je ne suis pas le premier et je suis deux ! Je ne suis pas le premier et je suis trois ! Je ne suis pas le premier et je suis quatre ! Je pense que vous avez compris le principe Wink.

 Mise en page

Tout cela est déjà bien pratique et rend notre code plus propre. Mais Blade va encore plus loin en nous proposant de puissantes possibilités de mise en page. Prenons un exemple pour voir ça. Créez une vue app/view/mon_template.blade.php avec ce code :

<html>
    <body>
    	<h1>@yield('titre')</h1>
        @section('contenu')
            <p>Contenu principal.</p>
        @show
    </body>
</html>

Créez une seconde vue app/view/page.blade.php avec ce code :

@extends('mon_template')

@section('titre')
	Mon titre
@stop

@section('contenu')
    @parent
    <p>Contenu de la page</p>
@stop
Créez enfin cette route :
Route::get('/', function()
{
	return View::make('page');
});
Si vous entrez l'URL http://localhost/laravel/public/ vous obtenez :

img29Je suppose que ce simple exemple vous a montré le principe. On crée un template avec du code HTML et deux catégories de champs : @yield pour réserver la place pour une information et @section pour quelque chose de plus fourni avec une information déjà présente. Attention à la syntaxe ! La section se termine par @show.

Pour utiliser le template on doit d'abord le référencer avec @extends. Ensuite on référence les zones réservées avec @section. Et cette fois une section se clôt avec @stop. On inclut le contenu parent avec @parent. On peut ainsi constituer facilement des pages complexes.

Un exemple

Je vais prendre le même exemple que celui du fil précédent avec un site statique mais cette fois en utilisant Blade. Voilà le template que vous appelez template_page.blade.php :

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>Mon beau site</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css">
<link href="assets/css/main.css" rel="stylesheet" type="text/css">
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
  <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
  <script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
<![endif]-->
</head>
 
<body>
<div class="container">
  <header class="jumbotron">
    <h1>Mon beau site !</h1>
  </header>
  <div class="navbar navbar-default">
    <div class="navbar-header">
      <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <a class="navbar-brand" href="#">Mon beau site</a>
    </div>
    <div class="collapse navbar-collapse">
      <ul class="nav navbar-nav">
          @for ($i = 0; $i < count($data['menu']); $i++)
           <li{{ ($i == $data['page'])? ' class="active"': ''; }}><a href="{{ $i }}">{{ $data['menu'][$i] }}</a></li>
          @endfor
      </ul>
    </div>
  </div>
  <div class="col-md-12"> @yield('content') </div>
  <hr>
  <footer class="col-md-12" id="bas"> © Mon beau site... </footer>
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.2/js/bootstrap.min.js"></script>
</body>

Je me suis contenté d'utiliser la syntaxe de Blade pour générer le menu et j'ai créé une section pour le contenu. Maintenant il faut modifier les pages en les nommant page0.blade.php, page1.blade.php, page2.blade.php et page3.blade.php :

@extends('template_page')
@section('content')
   Contenu de l'accueil
@stop
@extends('template_page')
@section('content')
   Contenu de la page 1
@stop
@extends('template_page')
@section('content')
   Contenu de la page 2
@stop
@extends('template_page')
@section('content')
   Contenu de la page 3
@stop
Et enfin la route :
Route::get('/{page?}', function($page = 0)
{
	$data = array(
		'menu' => array('Accueil','Page1','Page2','Page3'),
		'page' => $page
	);
	return View::make('page'.$page)->with('data', $data);
})->where('page', '[0-3]');

App::missing(function($exception)
{
	return 'Oups ! Je ne connais pas cette page !';
});
Je rappelle aussi le contenu du fichier CSS :
@charset "utf-8";
body {
    padding-top: 20px;
    min-height: 2000px;
    color: #252;
}
body, .jumbotron, .navbar {
    background: -moz-radial-gradient(top left, rgba(0,160,0,.5), rgba(0,240,0,0));
    background: -webkit-radial-gradient(top left, rgba(0,0,255,.5), rgba(0,240,0,0));
    background: -ms-radial-gradient(top left, rgba(0,160,0,.5), rgba(0,240,0,0));
    background: -o-radial-gradient(top left, rgba(0,160,0,.5), rgba(0,240,0,0));
    filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#8383FF', endColorstr='#D8D8FF', GradientType=0);
    background: radial-gradient(top left, rgba(0,160,0,.5), rgba(0,240,0,0));  
}
#bas {
    text-align: center;
}
p {
    text-align: justify;
}
.jumbotron {
    padding: 30px;
    border-radius:20px;
    color:#90d;
    text-shadow: 0 2px 0 #FFFFFF;
}
.jumbotron p {
    text-shadow: 0 1px 0 #FFFFFF;
}
.jumbotron, .navbar {
    box-shadow: 3px 3px 3px #059;
}
.navbar .nav > li > a {
    color: #90d;
    font-size: 16px;
}
.navbar .nav > .active > a, .navbar .nav > .active > a:hover, .navbar .nav > .active > a:focus {
    background-color: #4c4;
    box-shadow: 1px 1px 1px 1px #059;
}

La syntaxe est bien plus simple avec Blade Wink.



Par bestmomo

Nombre de commentaires : 10