Blade — template engine
Blade dikompilasi jadi PHP polos dan di-cache, jadi tidak ada biaya runtime yang berarti. Yang perlu dipahami: mana yang di-escape, mana yang tidak, dan kapan sebuah potongan layak jadi komponen.
Intisari
{{ $x }}otomatis di-escape.{!! $x !!}tidak — dan hampir selalu salah.- Layout modern memakai komponen (
<x-layout>), bukan@extendsgaya lama. - Blade dikompilasi ke
storage/framework/views;php artisan view:cachemelakukannya di muka saat deploy. @csrfdi setiap form POST, dan@method('PUT')untuk PUT/PATCH/DELETE.- Direktif
@auth,@can,@errormenghubungkan template ke auth dan validasi tanpaifpanjang.
Sintaks yang perlu kamu kuasai
{{-- resources/views/produk/index.blade.php --}}
<h1>{{ $judul }}</h1> {{-- di-escape --}}
<p>{{ $deskripsi ?? 'Tidak ada' }}</p>
@if ($produk->isEmpty())
<p>Belum ada produk.</p>
@else
<ul>
@foreach ($produk as $p)
<li @class(['habis' => $p->stok === 0])>
<a href="{{ route('produk.show', $p) }}">{{ $p->nama }}</a>
<span>Rp{{ number_format($p->harga, 0, ',', '.') }}</span>
</li>
@endforeach
</ul>
@endif
{{ $produk->links() }} {{-- paginasi --}}
{!! !!} adalah satu-satunya cara memasukkan XSS ke aplikasi Blade. Ia mematikan escaping.
Kalau isinya datang dari pengguna — komentar, deskripsi produk, nama — penyerang bisa menyisipkan
<script>. Kalau kamu memang perlu menampilkan HTML dari pengguna, bersihkan dulu dengan
pustaka sanitizer, jangan langsung dicetak.
Form: dua direktif yang wajib
<form method="POST" action="{{ route('produk.update', $produk) }}">
@csrf {{-- tanpa ini: 419 Page Expired --}}
@method('PUT') {{-- HTML hanya bisa GET dan POST --}}
<input name="nama" value="{{ old('nama', $produk->nama) }}">
@error('nama')
<p class="galat">{{ $message }}</p>
@enderror
<button>Simpan</button>
</form>
old('nama', $default) mengembalikan nilai yang tadi dikirim pengguna kalau validasi gagal — supaya
form tidak kosong lagi setelah redirect. Menggabungkannya dengan @error memberi pengalaman form yang
benar tanpa satu baris JavaScript.
Komponen: cara membangun layout hari ini
{{-- resources/views/components/layout.blade.php --}}
<!doctype html>
<html lang="id">
<head>
<title>{{ $judul ?? 'Toko' }}</title>
@vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
<body>
@include('partials.nav')
<main>{{ $slot }}</main>
</body>
</html>
{{-- dipakai --}}
<x-layout judul="Daftar Produk">
<x-alert type="sukses">Produk tersimpan.</x-alert>
@foreach ($produk as $p)
<x-produk-kartu :produk="$p" />
@endforeach
</x-layout>
Awalan : pada :produk="$p" berarti "ini ekspresi PHP", bukan string literal. Komponen
bisa berupa file Blade saja (anonymous) atau punya kelas pendamping di
app/View/Components saat butuh logika.
| Cara | Kapan dipakai |
|---|---|
@include('partials.nav') | Potongan sederhana, mewarisi semua variabel pemanggil |
<x-kartu :produk="$p" /> | Potongan dengan antarmuka jelas — default yang lebih baik |
@extends / @section | Gaya lama; masih jalan, tapi jangan dipakai untuk proyek baru |
@fragment | Kirim sebagian halaman saja — berguna untuk pembaruan parsial |
Direktif yang menyambung ke fitur lain
@auth Halo, {{ auth()->user()->name }} @endauth
@guest <a href="{{ route('login') }}">Masuk</a> @endguest
@can('update', $produk)
<a href="{{ route('produk.edit', $produk) }}">Ubah</a>
@endcan
@session('sukses')
<div class="notif">{{ $value }}</div>
@endsession
@production <!-- skrip analitik --> @endproduction
@can menyembunyikan tombol, bukan mengamankan aksi. Menyembunyikan tautan tidak mencegah
siapa pun mengetik URL-nya. Otorisasi yang sesungguhnya tetap harus ada di controller atau middleware
(Fase 4). Anggap @can sebagai urusan tampilan.
Kompilasi dan performa
php artisan view:cache # kompilasi semua Blade — dijalankan saat deploy
php artisan view:clear # buang hasil kompilasi
Blade bukan interpreter runtime: @foreach menjadi foreach PHP biasa, dan hasilnya
disimpan di storage/framework/views. Karena itu biaya Blade praktis nol setelah kompilasi pertama —
dan karena itu pula folder tersebut wajib bisa ditulis, atau perlu di-cache di muka pada image yang
read-only (Fase 9).
Latihan: buat komponen <x-layout> dan <x-alert type="...">, lalu
pakai keduanya di halaman daftar produk. Setelah itu tampilkan sebuah string berisi
<b>tebal</b> memakai {{ }} dan {!! !!} secara berdampingan —
lihat sendiri perbedaannya, lalu hapus yang kedua.
Rangkuman ini sengaja dipangkas ke bagian yang dipakai di roadmap. Buka sumber aslinya saat kamu butuh detail lengkap atau referensi parameter.