Laravel Blade Templating: Master the Basics of Laravel's View Engine

Published on November 06, 2025
Laravel Blade Templating PHP Frontend InterviewPrep

What is Blade Templating?

Blade is Laravel's simple yet powerful templating engine. Unlike plain PHP templates, Blade provides elegant syntax that makes your views cleaner and more readable, while compiling down to plain PHP code for optimal performance.

Key Advantages of Blade:

  • Elegant, readable syntax
  • Template inheritance
  • Built-in security features
  • No performance overhead
  • Extensible with custom directives

Blade File Structure and Basics

File Location and Naming

Blade templates are stored in the resources/views/ directory with .blade.php extension.

resources/views/
├── layouts/
│   ├── app.blade.php
│   └── admin.blade.php
├── components/
│   ├── alert.blade.php
│   └── card.blade.php
├── pages/
│   ├── home.blade.php
│   ├── about.blade.php
│   └── contact.blade.php
└── partials/
    ├── header.blade.php
    └── footer.blade.php

Basic Blade Syntax

Displaying Data

// Basic variable output
<h1>Welcome, {{ $username }}!</h1>

// HTML escaping (default behavior)
<p>{{ $userInput }}</p> // Safe - HTML is escaped

// Unescaped output (use carefully!)
{!! $htmlContent !!} // Unsafe - HTML is rendered

// Default values
<title>{{ $title ?? 'Default Title' }}</title>

Blade Comments

{{-- This comment won't appear in rendered HTML --}}
<!-- This regular HTML comment will be visible -->

Control Structures

Conditional Statements

If Statements

@if(count($users) === 1)
    <p>There is one user.</p>
@elseif(count($users) > 1)
    <p>There are {{ count($users) }} users.</p>
@else
    <p>There are no users.</p>
@endif

Unless Statement

@unless($user->isAdmin())
    <p>You do not have admin access.</p>
@endunless

Isset and Empty

@isset($records)
    <p>Records are available: {{ count($records) }}</p>
@endisset

@empty($records)
    <p>No records found.</p>
@endempty

Loops

Foreach Loop

<ul>
@foreach($users as $user)
    <li>{{ $user->name }} - {{ $user->email }}</li>
@endforeach
</ul>

For Loop

@for($i = 0; $i < 10; $i++)
    <p>Current value: {{ $i }}</p>
@endfor

While Loop

@while($item = array_pop($items))
    <p>Processing: {{ $item->name }}</p>
@endwhile

Loop Variables

@foreach($users as $user)
    @if($loop->first)
        <p>First user in the list:</p>
    @endif
    
    <div class="{{ $loop->even ? 'bg-gray-100' : 'bg-white' }}">
        <p>User #{{ $loop->iteration }} of {{ $loop->count }}</p>
        <p>Index: {{ $loop->index }}</p>
        <p>Remaining: {{ $loop->remaining }}</p>
        <p>Depth: {{ $loop->depth }}</p>
    </div>
    
    @if($loop->last)
        <p>End of user list.</p>
    @endif
@endforeach

Template Inheritance

Master Layout Template

{{-- resources/views/layouts/app.blade.php --}}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>@yield('title', 'My Application')</title>
    
    {{-- Stack for CSS --}}
    @stack('styles')
</head>
<body>
    {{-- Header Partial --}}
    @include('partials.header')
    
    {{-- Main Content --}}
    <main class="container">
        @yield('content')
    </main>
    
    {{-- Footer Partial --}}
    @include('partials.footer')
    
    {{-- Stack for Scripts --}}
    @stack('scripts')
</body>
</html>

Child Template

{{-- resources/views/pages/home.blade.php --}}
@extends('layouts.app')

@section('title', 'Home Page - Welcome to Our Site')

{{-- Push to styles stack --}}
@push('styles')
    <link rel="stylesheet" href="/css/home.css">
@endpush

@section('content')
    <div class="jumbotron">
        <h1>Welcome to Our Application</h1>
        <p>This is the home page content.</p>
    </div>
    
    <div class="row">
        <div class="col-md-6">
            <h2>Feature One</h2>
            <p>Description of feature one.</p>
        </div>
        <div class="col-md-6">
            <h2>Feature Two</h2>
            <p>Description of feature two.</p>
        </div>
    </div>
@endsection

{{-- Push to scripts stack --}}
@push('scripts')
    <script src="/js/home.js"></script>
@endpush

Section Directives

Yield vs Section

{{-- Layout file --}}
<head>
    <title>@yield('title', 'Default Title')</title>
    
    {{-- Required section --}}
    @yield('styles')
</head>

{{-- Child template --}}
@section('title', 'Custom Title')

@section('styles')
    <link rel="stylesheet" href="custom.css">
@endsection

Show Parent Content

{{-- Layout --}}
@section('sidebar')
    <p>This is the master sidebar.</p>
@endsection

{{-- Child template --}}
@section('sidebar')
    @parent {{-- Includes parent sidebar content --}}
    
    <p>This is appended to the sidebar.</p>
@endsection

Includes and Partials

Basic Includes

{{-- Include a partial --}}
@include('partials.header')

{{-- Include with data --}}
@include('partials.user-card', ['user' => $currentUser])

{{-- Include if file exists --}}
@includeIf('partials.custom-widget', ['data' => $widgetData])

{{-- Include with different name --}}
@includeWhen($user->isAdmin(), 'admin.partials.nav')

@includeUnless($user->isGuest, 'user.partials.profile')

Header Partial Example

{{-- resources/views/partials/header.blade.php --}}
<header class="bg-blue-600 text-white">
    <nav class="container mx-auto p-4">
        <div class="flex justify-between items-center">
            <a href="/" class="text-xl font-bold">MyApp</a>
            
            <ul class="flex space-x-6">
                <li><a href="/" class="hover:text-blue-200">Home</a></li>
                <li><a href="/about" class="hover:text-blue-200">About</a></li>
                <li><a href="/contact" class="hover:text-blue-200">Contact</a></li>
                
                @auth
                    <li>
                        <form method="POST" action="/logout">
                            @csrf
                            <button type="submit" class="hover:text-blue-200">Logout</button>
                        </form>
                    </li>
                @else
                    <li><a href="/login" class="hover:text-blue-200">Login</a></li>
                @endauth
            </ul>
        </div>
    </nav>
</header>

Forms and CSRF Protection

Basic Form with CSRF

<form method="POST" action="/contact">
    @csrf {{-- CSRF Protection --}}
    
    <div class="form-group">
        <label for="name">Name:</label>
        <input type="text" name="name" id="name" value="{{ old('name') }}" class="form-control">
        @error('name')
            <span class="text-red-500 text-sm">{{ $message }}</span>
        @enderror
    </div>
    
    <div class="form-group">
        <label for="email">Email:</label>
        <input type="email" name="email" id="email" value="{{ old('email') }}" class="form-control">
        @error('email')
            <span class="text-red-500 text-sm">{{ $message }}</span>
        @enderror
    </div>
    
    <button type="submit" class="btn btn-primary">Submit</button>
</form>

Form Method Spoofing

{{-- For PUT, PATCH, DELETE methods --}}
<form action="/users/{{ $user->id }}" method="POST">
    @csrf
    @method('PUT') {{-- Spoofs PUT method --}}
    
    <!-- Form fields -->
</form>

File Uploads

<form action="/upload" method="POST" enctype="multipart/form-data">
    @csrf
    
    <input type="file" name="avatar">
    
    @error('avatar')
        <span class="text-red-500">{{ $message }}</span>
    @enderror
    
    <button type="submit">Upload</button>
</form>

Blade Components

Creating Components

php artisan make:component Alert
php artisan make:component Form/Input

Class-Based Component

{{-- app/View/Components/Alert.php --}}
namespace App\View\Components;

use Illuminate\View\Component;

class Alert extends Component
{
    public $type;
    public $message;
    
    public function __construct($type = 'info', $message = null)
    {
        $this->type = $type;
        $this->message = $message;
    }
    
    public function backgroundClass()
    {
        return [
            'success' => 'bg-green-100',
            'error' => 'bg-red-100',
            'warning' => 'bg-yellow-100',
            'info' => 'bg-blue-100',
        ][$this->type] ?? 'bg-gray-100';
    }
    
    public function render()
    {
        return view('components.alert');
    }
}

Component Template

{{-- resources/views/components/alert.blade.php --}}
<div class="p-4 rounded {{ $backgroundClass() }}">
    <div class="flex">
        <div class="flex-shrink-0">
            @if($type === 'success')
                <svg class="h-5 w-5 text-green-400">...</svg>
            @elseif($type === 'error')
                <svg class="h-5 w-5 text-red-400">...</svg>
            @endif
        </div>
        <div class="ml-3">
            <p class="text-sm font-medium text-{{ $type }}-800">
                {{ $message ?? $slot }}
            </p>
        </div>
    </div>
</div>

Using Components

{{-- Basic usage --}}
<x-alert type="success" message="Operation completed successfully!" />

{{-- With slot content --}}
<x-alert type="warning">
    <strong>Warning!</strong> This action cannot be undone.
</x-alert>

{{-- Form components --}}
<x-form.input name="email" type="email" label="Email Address" />
<x-form.textarea name="bio" label="About You" :value="old('bio')" />

Blade Directives

Custom Directives

{{-- In AppServiceProvider boot method --}}
use Illuminate\Support\Facades\Blade;

Blade::directive('datetime', function ($expression) {
    return "<?php echo ($expression)->format('m/d/Y H:i'); ?>";
});

Blade::directive('money', function ($expression) {
    return "<?php echo '$' . number_format($expression, 2); ?>";
});

Using Custom Directives

<p>Created at: @datetime($post->created_at)</p>
<p>Price: @money($product->price)</p>

Practical Examples

User Dashboard View

{{-- resources/views/dashboard.blade.php --}}
@extends('layouts.app')

@section('title', 'Dashboard')

@section('content')
<div class="container mx-auto px-4 py-8">
    <h1 class="text-3xl font-bold mb-8">Dashboard</h1>
    
    {{-- Welcome Alert --}}
    <x-alert type="success">
        Welcome back, <strong>{{ auth()->user()->name }}</strong>!
    </x-alert>
    
    {{-- Stats Grid --}}
    <div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8">
        <div class="bg-white rounded-lg shadow p-6">
            <h3 class="text-lg font-semibold mb-2">Total Posts</h3>
            <p class="text-3xl font-bold text-blue-600">{{ $stats['total_posts'] }}</p>
        </div>
        <div class="bg-white rounded-lg shadow p-6">
            <h3 class="text-lg font-semibold mb-2">Published</h3>
            <p class="text-3xl font-bold text-green-600">{{ $stats['published_posts'] }}</p>
        </div>
        <div class="bg-white rounded-lg shadow p-6">
            <h3 class="text-lg font-semibold mb-2">Drafts</h3>
            <p class="text-3xl font-bold text-yellow-600">{{ $stats['draft_posts'] }}</p>
        </div>
    </div>
    
    {{-- Recent Posts --}}
    <div class="bg-white rounded-lg shadow">
        <div class="px-6 py-4 border-b">
            <h2 class="text-xl font-semibold">Recent Posts</h2>
        </div>
        
        @if($recentPosts->count())
            <div class="divide-y">
                @foreach($recentPosts as $post)
                    <div class="px-6 py-4">
                        <div class="flex justify-between items-start">
                            <div>
                                <h3 class="text-lg font-medium">
                                    <a href="{{ route('posts.show', $post) }}" 
                                       class="text-blue-600 hover:text-blue-800">
                                        {{ $post->title }}
                                    </a>
                                </h3>
                                <p class="text-gray-600 text-sm mt-1">
                                    {{ $post->excerpt }}
                                </p>
                                <div class="flex items-center mt-2 text-sm text-gray-500">
                                    <span>Created: {{ $post->created_at->diffForHumans() }}</span>
                                    <span class="mx-2">•</span>
                                    <span>Status: 
                                        <span class="font-medium 
                                            {{ $post->is_published ? 'text-green-600' : 'text-yellow-600' }}">
                                            {{ $post->is_published ? 'Published' : 'Draft' }}
                                        </span>
                                    </span>
                                </div>
                            </div>
                            <div class="flex space-x-2">
                                <a href="{{ route('posts.edit', $post) }}" 
                                   class="text-blue-600 hover:text-blue-800">Edit</a>
                                <form action="{{ route('posts.destroy', $post) }}" 
                                      method="POST" 
                                      onsubmit="return confirm('Are you sure?')">
                                    @csrf
                                    @method('DELETE')
                                    <button type="submit" class="text-red-600 hover:text-red-800">
                                        Delete
                                    </button>
                                </form>
                            </div>
                        </div>
                    </div>
                @endforeach
            </div>
        @else
            <div class="px-6 py-8 text-center text-gray-500">
                <p>No posts yet. <a href="{{ route('posts.create') }}" class="text-blue-600 hover:underline">Create your first post</a></p>
            </div>
        @endif
    </div>
</div>
@endsection

Common Interview Questions & Answers

1. What is Blade templating?
Blade is Laravel's templating engine that provides elegant syntax for writing views, with features like template inheritance, components, and built-in security.

2. How do you prevent XSS attacks in Blade?
Use double braces {{ }} which automatically escape HTML content. Only use {!! !!} when you're sure the content is safe.

3. What's the difference between @yield and @section?
@yield defines a placeholder in layouts, while @section defines content in child templates. @section can also capture content for later use.

4. How do you create reusable components?
Use php artisan make:component ComponentName to create class-based components, or create inline components in the resources/views/components/ directory.

5. What are Blade stacks used for?
Stacks allow you to push content to named stacks in layouts, commonly used for CSS and JavaScript files that need to be loaded in specific locations.

6. How do you handle conditional classes?
Use the @class directive: <div @class(['p-4', 'bg-red' => $hasError])> or ternary operators within class attributes.

Best Practices

  • Keep logic in controllers: Minimize PHP logic in Blade templates
  • Use components: Create reusable components for common UI elements
  • Organize views: Use subdirectories for better organization
  • Escape output: Always use {{ }} unless you specifically need unescaped output
  • Use template inheritance: Create base layouts for consistent design
  • Leverage partials: Break down complex views into manageable parts

Blade Performance Tips

  • Blade templates are compiled to plain PHP and cached
  • Compiled views are stored in storage/framework/views/
  • Clear view cache with php artisan view:clear
  • Cache views for production with php artisan view:cache

Now you have a solid foundation in Laravel Blade templating! In our next post, we'll explore Passing Data to Views in Laravel: 3 Simple Methods You Must Know to learn different ways to send data from controllers to views.