Sejauh ini setiap file blade kita (about.blade.php, contact.blade.php) menulis ulang seluruh struktur HTML dari <!DOCTYPE html> sampai </html>. Kalau nanti kita punya puluhan halaman, itu artinya puluhan copy-paste navbar yang sama. Blade templating menyelesaikan masalah ini lewat tiga alat: layout, include, dan component.
Halaman About memakai master layout, navbar include, dan alert component.
Master layout
Layout adalah kerangka HTML yang dipakai bersama oleh banyak halaman. Kita simpan di resources/views/layouts/app.blade.php:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>@yield('title', 'Blog Dasar') - Laravel 13 Dasar</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
@include('partials.navbar')
<main class="container py-4">
@yield('content')
</main>
</body>
</html>
@yield('content') adalah "lubang" yang nanti diisi oleh halaman spesifik. @yield('title', 'Blog Dasar') sama, tapi dengan default value kalau halaman tidak menyediakan title sendiri.
Menggunakan layout di halaman
Halaman about.blade.php sekarang jadi jauh lebih ringkas:
@extends('layouts.app')
@section('title', 'About')
@section('content')
<h1>About This Page</h1>
<p>This page is accessed through a named route: <code>route('about')</code>.</p>
@endsection
@extends bilang "pakai layout ini", lalu @section('content') ... @endsection mengisi bagian @yield('content') di layout dengan konten di antaranya.
Include untuk partial
Navbar dipakai di semua halaman, jadi kita pisah ke file sendiri, resources/views/partials/navbar.blade.php:
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container">
<a class="navbar-brand" href="{{ url('/') }}">Blog Dasar</a>
<div class="navbar-nav">
<a class="nav-link" href="{{ route('posts.index') }}">Posts</a>
<a class="nav-link" href="{{ route('about') }}">About</a>
<a class="nav-link" href="{{ route('contact.form') }}">Contact</a>
</div>
</div>
</nav>
Lalu di layout, cukup @include('partials.navbar'). Bedanya dengan layout: include tidak punya konsep "isi lubang" — dia cuma menyisipkan file blade lain apa adanya di titik itu.
Blade component
Kalau include cocok untuk potongan HTML statis, component cocok untuk elemen yang punya "parameter" — misalnya alert box dengan warna berbeda-beda. Kita buat resources/views/components/alert.blade.php:
@props(['type' => 'info'])
<div {{ $attributes->merge(['class' => "alert alert-{$type}"]) }}>
{{ $slot }}
</div>
@props mendefinisikan "parameter" yang bisa di-pass ke component, dengan default value. $slot adalah konten di antara tag pembuka dan penutup saat component dipakai:
<x-alert type="info">
This page uses a blade layout, an include, and a blade component.
</x-alert>
Laravel otomatis mengenali file di resources/views/components/ sebagai component yang bisa dipanggil lewat tag <x-nama-file> — tidak perlu registrasi manual.
Kenapa ini penting
Ketiga alat ini punya use case berbeda:
- Layout — kerangka halaman yang dipakai berulang dengan "lubang" konten
- Include — potongan HTML statis yang dipakai di banyak tempat
- Component — elemen reusable yang punya parameter/props
Menguasai ketiganya adalah dasar mutlak sebelum bikin aplikasi Laravel yang lebih besar — hampir semua project production memakai kombinasi ketiganya.
Selanjutnya
Tampilan sudah rapi. Sekarang saatnya bikin data sungguhan — episode berikutnya kita bikin migration untuk tabel posts dan categories.