DRY thanks to Blade framework

Don’t repeat yourself thanks to Blade framework

So far, we’ve already create a few views and each time we’re coding again and again the same content: the header block f.i. is always the same.

Table des matières

1. The master template

The look & feel of our pages will be:

<!DOCTYPE html>
<html lang="{{ app()->getLocale() }}">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <meta name="csrf-token" content="{{ csrf_token() }}">
  <title>Some stupid Todos application</title>
  <link media="screen" rel="stylesheet" type="text/css" href="/css/app.css" />
</head>
<body>
  <main role="main">
    <div class="jumbotron">
      <div class="container">
        <h1 class="display-3">Some stupid Todos application</h1>
        <p>A simple Laravel application</p>
      </div>
    </div>
  </main>
  <div class="container">
    @yield('content')
    <hr/>
    @yield('navigation')
  </div>
</body>
</html>

Use app()->getLocale() to retrieve the langage for the .env.

We’ll have two variables part: the content of the page and the navigation.

Already add the Laravel token in the template to protect form’s submissions.

2. The todos view

List all todos (http://127.0.0.1:8000/todos)

Edit /resources/views/todos.blade.php:

@extends('master')

@section('content')
  @isset($data)
    @foreach($data as $post)
      <h3><a href="todo/{{ $post->id }}">{{ $post->title }}</a></h3>
      <p>{{ $post->description }}</p>
      <small>Author: {{ $post->user->name }}</small>
      <hr/>
    @endforeach
  @endisset
@endsection

@section('navigation')
  <a href="/todo" >Add new item</a>
@endsection

We’ll use the master template then inject our two contents.

The content will be the list of todos, one h3 by Todo followed by his description and the name of the todo’s author.

3. The detail view

Show the detail of a given todo (http://127.0.0.1:8000/todo/1)

Edit /resources/views/show.blade.php:

@extends('master')

@section('content')
  @isset($data)
    <h3>{{ $data->title }}</h3>
    <p>{{ $data->description }}</p>
    <small>
      Created at: {{ $data->created_at }}
      <br/>
      Last updated: {{ $data->updated_at }}
      <br/>
      Author: {{ $data->user->name }}
    </small>
    <hr/>
  @endisset
@endsection

@section('navigation')
  <a href="/todo" >Add new item</a> - <a href="/todos">Show all</a>
@endsection

4. The todo_ok view

Displayed after the submission of a new Todo

Edit /resources/views/todo_ok.blade.php:

@extends('master')

@section('content')
  <div class="alert alert-success" role="alert">Successfully stored in the database</div>
@endsection

@section('navigation')
  <a href="/todo" >Add new item</a> - <a href="/todos">Show all</a>
@endsection

5. The form view

Edit /resources/views/form.blade.php:

@extends('master')

@section('content')
  <div class="panel-heading">Hi {{ Auth::user()->name }}, please add your new Todo below</div>  
  <div class="panel-body">
    {!! Form::open(['route' => 'storeTodo']) !!}
      <div class="form-group {!! $errors->has('todo') ? 'has-error' : '' !!}">
        {!! Form::text('title', null, array('size' => '100', 'class' => 'form-control', 'placeholder' => 'Enter Todo\'s title')) !!}
        {!! $errors->first('title', '<div class="alert alert-danger">:message</div>') !!}
      </div>
      <div class="form-group ">
        {!! Form::checkbox('completed', 1, 0)  !!}
        {!! Form::label('completed', 'Completed'); !!}
      </div>
      <div class="form-group ">
        {!! Form::label('description', 'Description (optional)'); !!}
        {!! Form::textarea('description', null, array('class' => 'form-control')) !!}
      </div>
      {!! Form::submit('Submit !') !!}
    {!! Form::close() !!}
  </div>
@endsection

@section('navigation')
  <a href="/todos">Show all</a>
@endsection

5.1. Tips:

https://laravel-news.com/five-useful-laravel-blade-directives

We can replace

@if(auth()->user())
  // The user is authenticated.
@endif

by the @auth directive; more powerful.

@auth
  // The user is authenticated.
@endauth

Same for @guest.

6. Test

Now, you can test each view, no change will be visible by visiting the site.

But views are now easier to manage; we can update the master view and the change will be visible everywhere.