Laravel Blade Templating Engine
Tags: laravel, webdev
Published: 2024-03-25 11:15:37

Laravel's Blade templating engine is a powerful tool for web developers, allowing for clean separation of concerns between presentation and logic. This article delves into the core concepts of Blade, equipping you to craft dynamic and maintainable Laravel user interfaces.

## Understanding Blade Syntax

Blade offers a concise syntax that seamlessly integrates PHP code within your HTML templates. Key elements include:

- _Directives_: These begin with @ and control logic flow. Common examples include `@if, @foreach`, and `@while` for conditional statements and loops.
- _Templating Statements_: These statements manipulate data and control template flow. Examples include `{{ $variable }}` for displaying variables and `@include('viewName')` for including partial views.

Here's some code to illustrate the key elements of Blade syntax:

**Directives - Conditional Statements:**

```
@if ($user->isAdmin())
  <p>Welcome, Administrator {{ $user->name }}!</p>
@else
  <p>Hello, {{ $user->name }}!</p>
@endif
```

This code checks if the `$user` has an `isAdmin` method that returns true. If so, it displays a welcome message with "`Administrator`". Otherwise, it displays a regular welcome message.

**Directives - Loops:**

```
@foreach ($products as $product)
  <div class="product">
    <h2>{{ $product->name }}</h2>
    <p>Price: ${{ $product->price }}</p>
  </div>
@endforeach
```
This code iterates through a collection named `$products`. For each product, it creates a product div with the product name and price.

**Templating Statements - Displaying Variables:**

```
<p>Your email address is: {{ $email }}</p>
```

This code simply displays the value of the `$email` variable within a paragraph tag.

**Templating Statements - Including Partials:**

```
<header>
  @include('partials.header')
</header>

<h1>My Laravel Application</h1>
<nav>
  <a href="/">Home</a>
  <a href="/about">About</a>
</nav>
```



## Essential Blade Components

_Sections and Layouts:_ [Laravel blade](https://spacema-dev.com/understanding-laravel-blade-and-how-to-use-it/) promotes code reusability through layouts and sections. Layouts define the overall page structure (`header, footer`, etc.), while sections within the layout are designated for content specific to each view.
_Slots:_ Slots provide a more flexible approach to inheritance. Child views can define content placeholders using named slots, which can then be filled by the parent layout.

**Sections and Layouts:**

Layout (layouts/app.blade.php):

```
<!DOCTYPE html>
<html>
<head>
  <title>@yield('title') - My Laravel App</title>
</head>
<body>
  <header>
    @include('partials.header')
  </header>

  <main>
    @yield('content')
  </main>

  <footer>
    @include('partials.footer')
  </footer>
</body>
</html>
```

This layout defines the overall page structure with a title, header, main content area, and footer. It uses `@yield` directives to specify where child views can inject their specific content.

**Child View (views/home.blade.php):**

```
@extends('layouts.app')

@section('title', 'Home Page')

@section('content')
  <h1>Welcome to My Laravel App!</h1>
  <p>This is the home page content.</p>
@endsection
```

This child view extends the layouts.app layout. It defines specific content for the title and content sections using @section directives.

**Slots:**

Parent Layout (layouts/app.blade.php):

```
<!DOCTYPE html>
<html>
<head>
  <title>@yield('title') - My Laravel App</title>
</head>
<body>
  <header>
    @include('partials.header')
  </header>

  <main>
    @yield('content')

    {{-- Define a named slot for sidebar content --}}
    <aside>
      @yield('sidebar')
    </aside>
  </main>

  <footer>
    @include('partials.footer')
  </footer>
</body>
</html>
```

This layout introduces a named slot called sidebar. This allows child views to define specific content for the sidebar section.

Child View (views/blog/post.blade.php):

```
@extends('layouts.app')

@section('title', $post->title)

@section('content')
  <h1>{{ $post->title }}</h1>
  <p>{{ $post->content }}</p>
@endsection

@section('sidebar')
  <h2>Recent Posts</h2>
  <ul>
    {{-- Loop through recent posts and display titles --}}
  </ul>
@endsection
```

This child view defines content for the title and main content sections. Additionally, it defines content for the `sidebar` slot, allowing it to populate the sidebar with recent posts.



## Effective Blade Usage for Dynamic UIs

_1. Conditionals and Loops:_ Leverage Blade's control flow directives to conditionally render content based on data or user interactions. Loops iterate through collections, dynamically generating HTML elements.
_2. Components:_ Break down complex UI elements into reusable Blade components. This promotes code maintainability and consistency.
_3. Partials:_ Create reusable view snippets (partials) for common UI elements like navigation bars or sidebars. Partials can be easily included across multiple views.

Conditionals and Loops:

```
@if (count($errors) > 0)
  <div class="alert alert-danger">
    <ul>
      @foreach ($errors->all() as $error)
        <li>{{ $error }}</li>
      @endforeach
    </ul>
  </div>
@endif

<form method="POST" action="{{ route('post.store') }}">
  @csrf

  <div class="form-group">
    <label for="title">Title</label>
    <input type="text" name="title" id="title" class="form-control" value="{{ old('title') }}">
  </div>

  <div class="form-group">
    <label for="body">Body</label>
    <textarea name="body" id="body" class="form-control">{{ old('body') }}</textarea>
  </div>

  <button type="submit" class="btn btn-primary">Create Post</button>
</form>
```



## Beyond the Basics

_Blade Directives:_ Laravel offers a rich set of built-in directives for common tasks like form protection (CSRF tokens) and user authentication checks.


Form Protection with CSRF Token:

```
<form method="POST" action="{{ route('login') }}">
  @csrf

  <div class="form-group">
    <label for="email">Email Address</label>
    <input type="email" name="email" id="email" class="form-control" required>
  </div>

  <div class="form-group">
    <label for="password">Password</label>
    <input type="password" name="password" id="password" class="form-control" required>
  </div>

  <button type="submit" class="btn btn-primary">Login</button>
</form>
```

The `@csrf` directive automatically generates a hidden form field with a CSRF token, protecting your form from security vulnerabilities.

User Authentication Check:

```
@if (Auth::check())
  <p>Welcome, {{ Auth::user()->name }}!</p>
  <a href="{{ route('logout') }}">Logout</a>
@else
  <a href="{{ route('login') }}">Login</a>
  <a href="{{ route('register') }}">Register</a>
@endif
```

This code utilizes Laravel's built-in authentication functionalities. It checks if a user is logged in (`Auth::check()`) and displays a welcome message or login/register links accordingly.

Pagination
Laravel provides directives for handling pagination of large datasets within your Blade templates. Here's an example:

```
@if ($posts->count() > 0)
  <ul class="pagination">
    {{-- Previous Page Link (if applicable) --}}
    @if ($posts->currentPage() > 1)
      <li class="page-item"><a class="page-link" href="{{ $posts->previousPageUrl() }}">Previous</a></li>
    @endif

    {{-- Pagination Links for a few pages around the current page --}}
    @for ($i = max(1, $posts->currentPage() - 2); $i <= min($posts->lastPage(), $posts->currentPage() + 2); $i++)
      <li class="page-item {{ $i === $posts->currentPage() ? 'active' : '' }}">
        <a class="page-link" href="{{ $posts->url($i) }}">{{ $i }}</a>
      </li>
    @endfor

    {{-- Next Page Link (if applicable) --}}
    @if ($posts->hasMorePages())
      <li class="page-item"><a class="page-link" href="{{ $posts->nextPageUrl() }}">Next</a></li>
    @endif
  </ul>

  <div class="row">
    @foreach ($posts as $post)
      <div class="col-md-4">
        </div>
    @endforeach
  </div>
@else
  <p>No posts found.</p>
@endif
```

This code demonstrates using pagination directives:

It checks if there are any posts (`$posts->count() > 0`).
It displays pagination links only if there are multiple pages.
The `@if ($posts->currentPage() > 1)` block creates a link to the previous page if applicable.
The `@for` loop iterates through a limited range of pages around the current page, displaying page numbers as links.
The `$posts->url($i)` method generates the URL for each page number.
The `@if ($posts->hasMorePages())` block creates a link to the next page if applicable.
Within the loop of posts, you can display individual post details.