Advanced Laravel Blade Directives

0
1110
Advanced Blade Directives

Laravel presents a powerful templating engine called a laravel blade. Blade provides very helpful directives. It will compiled in plain PHP in views and cached until it’s modified. Everybody knows about the frequently used blade directives, but let’s learn some uncommon directives. To learn all about laravel blade click here.

First of all, install the laravel framework. Learn how to install Laravel framework . After installing Laravel create a new layout file resources > views > layouts > master.blade.php. After that, modify master.blade.php as below.

/* resources > views > layouts > master.blade.php */

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Laravel Blade Components</title>
</head>
<body>
<div class="container">
    @yield('content')
</div>
</body>
</html>

As you already know you can extend this layout it in any file. To do that, open welcome.blade.php and extend this layout. After that, we will dig deeper into the Blade template.

/* resources > views > welcome.blade.php */

@extends('layouts.master')

@section('content')
Welcome
@endsection

# Using @stack

Sometimes, you need to inject specific CSS or JS code into a specific page. What if you want to inject a jquery plugin or CSS framework into the header of the footer of a specific page? Using into master layout will load that code into all pages. You can use @stack directive instead. Using this directive will inject code into specific place using @push and @endpush directive. Let me explain you with an example. Add two @stack directives into master.blade.php as below.

/* resources > views > layouts > master.blade.php */

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Laravel Blade Components</title>
    @stack('header')
</head>
<body>
<div class="container">
    @yield('content')
</div>

@stack('footer')
</body>
</html>

As you can see, I’ve added two @stack directive header and footer into the master layout. Now, Let’s inject the bootstrap CSS file in the header and it’s JS in the footer in welcome.blade.php. For that, use @push('header') and @push('footer') directives as below.

/* resources > views > welcome.blade.php */

@extends('layouts.master')

@section('content')
Welcome
@endsection

@push('header')
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
@endpush

@push('footer')
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
@endpush

Now, check the page source with Ctrl + U. As you can see CSS and JS will automatically inject in header and footer. You can create @stack as many you want. Using this directive will improve your code performance by using the necessary code into specific pages.

Stack Directive View Source

# Using @prepend

Let’s extend @stack directive a bit more. Suppose you want to prepend some code before this directive. Let’s modify welcome.blade.php with @prepend directive. Keep in mind, that you need to declare @stack directive as above to use @prepend directive.

/* resources > views > welcome.blade.php */

@extends('layouts.master')

@section('content')
Welcome
@endsection

@push('header')
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
@endpush

@push('footer')
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
@endpush

@prepend('header')
<style>
    .prepending-css-header {
        background: blue;
    }
</style>
@endprepend

@prepend('header')
<script>
    console.log('Prepending JS in footer.')
</script>
@endprepend

Check the page source again you will get CSS prepended in the header and JS prepended in the footer.

Prepend Directive View Source

# Using @parent

Suppose, you have a @section directive to display sidebar. To extend or owerwrite that sidebar you can use @parent directive along with that @section. For example, modify master.blade.php file as below to define the default sidebar. I’m using the bootstrap list group to create a sidebar. Similary, clear welcome.blade.php too.

/* resources > views > layouts > master.blade.php */

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Laravel Blade Components</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>
<body>
<div class="container">
    <div class="row mt-5">
        <div class="col-md-4">
            <ul class="list-group">
                @section('sidebar')
                <li class="list-group-item">Master Sidebar 1</li>
                <li class="list-group-item">Master Sidebar 2</li>
                @show
            </ul>
        </div>
        <div class="col-md-8">
            <div class="container-fluid">
                @yield('content')
            </div>
        </div>
    </div>
</div>
</body>
</html>
/* resources > views > welcome.blade.php */

@extends('layouts.master')

@section('content')
Welcome
@endsection

As you can see, I declared the sidebar section into the master layout file. By default, I’ll be displayed on every extended page.

Parent Directive Default View

To overwrite the sidebar section you need to define @section directive into welcome.blade.php. To do that, open welcome.blade.php and modify it as below.

/* resources > views > welcome.blade.php */

@extends('layouts.master')

@section('content')
Welcome
@endsection

@section('sidebar')
<li class="list-group-item">Overwritten Sidebar 1</li>
<li class="list-group-item">Overwritten Sidebar 2</li>
@endsection
Parent Directive Overwritten View

In last, to extend the sidebar you need to define @parent directive inside @section directive into welcome.blade.php. Using @parent will inject the master sidebar along with the defined sidebar.

/* resources > views > welcome.blade.php */

@extends('layouts.master')

@section('content')
Welcome
@endsection

@section('sidebar')
@parent
<li class="list-group-item">Extended Sidebar 1</li>
<li class="list-group-item">Extended Sidebar 2</li>
@endsection
Parent Directive Extended

# Using @verbatim

Laravel blade template engine uses double curly braces {{ }} to print data. But some javascript frameworks also using double curly braces {{ }} to print data. Suppose, you are working on a laravel blade file that includes Vue js or some other framework that uses {{ }} to print. Let’s use an example. Modify master.blade.php and welcome.blade.php as below.

/* resources > views > layouts > master.blade.php */

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Laravel Blade Components</title>
</head>
<body>
<div class="container">
    <div class="row mt-5">
        @yield('content')
    </div>
</div>

@stack('footer')
</body>
</html>
/* resources > views > welcome.blade.php */

@extends('layouts.master')

@section('content')
<div id="app">
    @verbatim
    {{ message }}
    @endverbatim
</div>
@endsection

@push('footer')
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    var app = new Vue({
        el: '#app',
        data: {
            message: 'Hello Vue!'
        }
    })
</script>
@endpush

In welcome.blade.php I’ve used Vue JS CDN to explain to you. As you can see Vue JS has a message variable. If you print that variable without @verbatim directive, Laravel will assume that its a constant and throw an error. That’s why you need to wrap javascript content into @verbatim directive.

# Using @foreach vs $forelse

Every time, you need to count an array to check data availability before looping with @foreach directive. Suppose you have articles to loop with @foreach directive but every time you need an extra if condition to count it before looping. That will be solved with using @forelse directive instead of @foreach. It’s a good practice to use @forelse, because it will improve code readability and code structure. To do that, you need to modify @foreach into @forelse like below.

@if($posts->count())
    @foreach($posts as $post)
    // Looping through posts
    @endforeach
@else
    No Post found
@endif
@forelse($posts as $post)
    // Looping through posts
@empty
    No Post found
@endforelse

# Using @loop varialbe in @foreach and @forelse

Sometimes, you need to use the index of the @foreach loop. To simplify that you can use the $loop variable. The $loop variable will be automatically available inside your loop. Learn more about the $loop variable. I’m using $loop->iteration property, it will give me the current iteration starts with 1. Following code will explain you everything.

@extends('layouts.master')

@section('content')
<table>
    <tr>
        <th>#</th>
        <th>Title</th>
    </tr>
    @foreach($posts as $post)
    <tr>
        <td>{{ $loop->iteration }}</td>
        <td>{{ $post->title }}</td>
    </tr>
    @endforeach
</table>
@endsection

Learn more about Laravel Framework

LEAVE A REPLY

Please enter your comment!
Please enter your name here