Let’s Learn Laravel Blade: Layouts and Partials (Part 3)

In the last post, we saw how easy it is to conditionally display markup and use inline logic in blade templates. Conditionals are a very useful tool and you will probably use them often. In this post, we will explore how to reduce repetitive code and help adhere to DRY(don’t repeat yourself) principals.

What’s one thing you notice about all pages across any website? They all have biolerplate code. Here’s a classic example:

<!doctype html>
<html>
    <body class="body-classes">
        <main class="content">
            @yield('content') // @yield is Laravel blade specific, we will get to it
        <main>
    </body>
</html>

Just about any page on a website will contain something like the above. We define our html and body tags, typical scripts and libraries, and probably a good amount of meta tags. Any good templating engine should have a way of defining this markup in one place. Luckily for us, blade makes it very easy and flexible.

Laravel Blade Partials

A blade partial is similar to an include or require in PHP. It’s an easy way to include contents of another file inside of a template. A PHP include would look something like 'include file.php' whereas a blade @include looks like @include('partials.file.php'). They serve the same purpose, blade just provides syntactic sugar to make it easier on you.

The reason we use partials.file is because our file resides in our partials directory which is in the resources/views base directory. In a typical Laravel app, resources/views is where an @include points to, so if you make a file.php file directly in that folder, it would look like @include('file').

Making a Generic Layout

A generic layout is page biolerplate that doesn’t fit into a specific type of page or “template”. For example, let’s say we have a user dashboard app that has authentication, dashboard, landing page, and generic views. The main generic layout is anything that doesn’t fall into a dashboard, authentication, or landing page layout. What would that look like exactly? Well, it should look similar to the basic example above.

<!doctype html>
<html>
    @include('partials.header')
    <body class="body-classes">
        <main class="content">
            @if(App\sidebar())
                @include('partials.sidebar')
            @endif

            <section class="body-content">
                @yield('content')
            </section>
        <main>
    </body>
    @include('partials.footer')
</html>

This layout provides the base header and footer partial, accounts for an optional sidebar, and has our main wrapper class which is <main>. In theory, most pages on a website would use the generic layout, so it’s typical to include all meta/favicon tags here. Blade layouts are most helpful when a project’s needs change and you need to make a global change to all pages.

Defining wrapper classes in the template allows you to edit the code in one place while applying it to most pages in your project. For example, what if you wanted to add a simple container class? Shouldn’t be too hard:

<main class="content">
    <div class="container">
        @if(App\sidebar())
            @include('partials.sidebar')
        @endif
    </div>
<main>

Now we have a “container” class and any page that @extends this layout will receive that change. How exactly do we have pages extend this layout?

Extending a Layout

Extending a layout is pretty easy and can be done from any template. Let’s create our home.php template.

@extends('layouts.main')

@section('content')
    <p>Home page content</p>
@endsection

Our layouts are typically stored in resources/views/layouts. If we name it main.blade.php then we refer to it as layouts.main. When we @extend it, the code from the layout is applied to the home.php template. How do we enter the unique home page content into the template? That’s where @section comes into play.

@section is a block that takes in any amount of content. It works similarly to slotted elements in something like Vue or React. The content in this block will be outputted where a @yield block is in the layout template. Let’s take another look at our main template:

<!doctype html>
<html>
    @include('partials.header')
    <body class="body-classes">
        <main class="content">
            @if(App\sidebar())
                @include('partials.sidebar')
            @endif

            <section class="body-content">
                {{-- This is where our @content block content is outputted --}}
                @yield('content')
            </section>
        <main>
    </body>
    @include('partials.footer')
</html>

You don’t have to name it content, it can be named anything. If you want to name it maincontent, you’d use @section('maincontent') and name your yield block @yield('maincontent'). Naturally, you can use multiple @yield statements as long as they have different names.

Using different types of layouts is the same process. If you make an auth layout, you’d extend it with something like @extend('layouts.auth'). You can make as many layouts as you wish. A layout can be as simple as the example above, or as complex as you need it to be. Though, layouts typically contain highly repeatable biolerplate code so they aren’t usually super complex.

Laying It Out

Now that you know how layouts work, you have the basis for creating any type of page in your project. When you consider partials, conditionals, and loops, there’s already a lot you can do! That’s the beauty of blade, it doesn’t take a lot of learning to start getting some real use out of it. I hope to delve even further in the next post and hope to see you there.

Leave a Comment