This blog post continues from my Hello World tutorial and adds a master layout that you can use to add a consistent HTML structure to all pages. This is very similar, in a Rails context, to application.html.erb.

Step 1: Create a layouts Directory

In your application directory, start my creating the directory:

mkdir resources/views/layouts

Step 2: Create a master.blade.php Layout

In your application directory, create the layout file:

touch resources/views/layouts/master.blade.php

Step 3: Add the HTML Boilerplate

Start by adding to the master.blade.php file, your basic HTML stuff:

<html>
<head>
  <title>
  </title>
</head>
<body>
</body>
</html>

Step 4: Add Yield Directives

Just as in Rails, Laravel uses a yield directive during template processing to indicate where things go. Here is the HTML boilerplate marked up using yield directives:

<html>
<head>
  <title>
    @yield('title')
  </title>
</head>
<body>
  @yield('content')
</body>
</html>

These yield statements indicate that two named sections of stuff, title and content, will be inserted at their respective locations.

Adding Bootstrap

Given that we have a master template, we can also use it to add Bootstrap to our Hello World app. Go to the Get Bootstrap site, click Getting Started, and copy the main CSS url. And add it below as follows:

<html>
<head>
  <title>
    @yield('title')
  </title>
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x" crossorigin="anonymous">
</head>
<body>
  @yield('content')
</body>
</html>

Now we need to add the JavaScript so scroll down in the above Get Boostrap page and copy the JavaScript script tag. And add it below as follows:

<html>
<head>
  <title>
    @yield('title')
  </title>
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x" crossorigin="anonymous">
</head>
<body>
  @yield('content')
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-gtEjrD/SeCtmISkJkNUaaKMoLD0//ElJ19smozuHV6z3Iehds+3Ulb9Bn9Plx0x4" crossorigin="anonymous"></script>
</body>
</html>

Using the Layout

In our previous tutorial, we had a view file called hello_index.blade.php. We are going to modify that file as follows:

@extends('layouts.master')
@section('title','Home Page')
@section('content')

<div class='container'>
  <div class='row'>
    <div class='col-md-12'>
      <h1>Hello World</h1>
    </div>
  </div>
</div>

@endsection

And let's create a second file to use the layout in:

touch resources/views/about.blade.php

And here are the contents for about.blade.php:

@extends('layouts.master')
@section('title','About Page')
@section('content')

<div class='container'>
  <div class='row'>
    <div class='col-md-12'>
      <h1>About</h1>
    </div>
  </div>
</div>

@endsection

Adding a Route for the About Page

Add the following route to web.php:

Route::get('/about', function() {
  return view('about')
  })

Check your routes with:

php artisan route:list
+--------+----------+----------+------+--------------------------------------------+------------+
| Domain | Method   | URI      | Name | Action                                     | Middleware |
+--------+----------+----------+------+--------------------------------------------+------------+
|        | GET|HEAD | /        |      | Closure                                    | web        |
|        | GET|HEAD | about    |      | Closure                                    | web        |
|        | GET|HEAD | api/user |      | Closure                                    | api        |
|        |          |          |      |                                            | auth:api   |
|        | GET|HEAD | hello    |      | App\Http\Controllers\HelloController@index | web        |
+--------+----------+----------+------+--------------------------------------------+------------+

Testing This

Start the server with:

php artisan serve

And then visit:

https://localhost:8000/hello
https://localhost:8000/about

And you should see the bootstrap derived layout in place. Do a view source or look closely at the tab title and you should see the title variable set correctly.

Moving Bootstrap Tags from the View to the Layout

As you look at the views above you likely noticed that the container divs are in the view rather than in the layout. This can be addressed by changing the layout as follows:

<html>
<head>
  <title>
    @yield('title')
  </title>
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x" crossorigin="anonymous">
</head>
<body>
  <div class='container'>
    <div class='row'>
      <div class='col-md-12'>
        @yield('content')
      </div>
    </div>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-gtEjrD/SeCtmISkJkNUaaKMoLD0//ElJ19smozuHV6z3Iehds+3Ulb9Bn9Plx0x4" crossorigin="anonymous"></script>
</body>
</html>

You will also need to remove the container divs from each of the views. Here's an example for about:

@extends('layouts.master')
@section('title','About Us')
@section('content')

      <h1>About Us</h1>

@endsection

Conclusion

Overall Laravel blade templates are conceptually similar to Rails html.erb templates and hopefully this tutorial helps you see how to work with them.

See Also