Passing Data to Views in Laravel: 3 Simple Methods You Must Know
Learn different ways to pass data from controllers to your Blade views.
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:
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
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 -->
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
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
{{-- 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>
{{-- 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
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
{{-- 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')
{{-- 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>
<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>
{{-- For PUT, PATCH, DELETE methods --}}
<form action="/users/{{ $user->id }}" method="POST">
@csrf
@method('PUT') {{-- Spoofs PUT method --}}
<!-- Form fields -->
</form>
<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>
php artisan make:component Alert
php artisan make:component Form/Input
{{-- 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');
}
}
{{-- 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>
{{-- 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')" />
{{-- 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); ?>";
});
<p>Created at: @datetime($post->created_at)</p>
<p>Price: @money($product->price)</p>
{{-- 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
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.
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.