8. Tujuan Pembelajaran
Pada bagian ini, aplikasi web berita dikembangkan dengan fitur upload gambar thumbnail, sehingga setiap berita memiliki tampilan visual yang lebih menarik dan profesional.
8.1 Pastikan Struktur Awal Sudah Berjalan
Sebelum menambahkan fitur lanjutan, pastikan fitur CRUD dasar berita (Post) dari tahap sebelumnya sudah berjalan dengan baik, meliputi:
- Menambah berita
- Menampilkan daftar berita
- Mengedit berita
- Menghapus berita
Jika semua fungsi tersebut sudah berjalan normal, barulah kita lanjutkan ke fitur upload gambar.
8.2 Menambahkan Kolom Thumbnail pada Tabel Posts
Kolom thumbnail digunakan untuk menyimpan path/lokasi file gambar yang diupload oleh pengguna.
Membuat Migration Baru
a. Tambah kolom di tabel posts
php artisan make:migration add_thumbnail_to_posts_table --table=posts
Edit file migration:
public function up(): void
{
Schema::table('posts', function (Blueprint $table) {
$table->string('thumbnail')->nullable()->after('content');
});
}
Jalankan migrasi:
php artisan migrate
8.3 Konfigurasi Storage Laravel
Laravel menyimpan file upload di folder storage. Agar file tersebut dapat diakses melalui browser, perlu dibuat symbolic link ke folder public.
Jalankan perintah:
php artisan storage:link
Lalu ubah local menjadi public di .env :
FILESYSTEM_DISK=public
8.4 Update Model Post
Kolom thumbnail harus ditambahkan ke properti $fillable agar dapat disimpan melalui proses input form.
tambahkan kolom thumbnail di model Post.php :
protected $fillable = [ 'title', 'content', 'author', 'thumbnail', ];
8.5 Update Controller (Upload & Update File)
Controller dimodifikasi agar dapat:
- Memvalidasi file gambar
- Menyimpan file ke storage
- Menghapus thumbnail lama jika diganti
Method store()
Ubah PostController method store dan update agar menangani upload file.
public function store(Request $request)
{
$request->validate([
'title' => 'required',
'content' => 'required',
'thumbnail' => 'image|mimes:jpeg,png,jpg|max:2048'
]);
$data = $request->all();
if ($request->hasFile('thumbnail')) {
$file = $request->file('thumbnail');
$path = $file->store('thumbnails', 'public');
$data['thumbnail'] = $path;
}
Post::create($data);
return redirect()->route('posts.index')->with('success', 'Berita berhasil ditambahkan!');
}
Dan pada Method update() :
public function update(Request $request, Post $post)
{
$request->validate([
'title' => 'required|string|max:255',
'content' => 'required',
'thumbnail' => 'nullable|image|mimes:jpeg,png,jpg|max:2048',
]);
$data = $request->only(['title', 'content', 'author']);
// Jika user upload thumbnail baru
if ($request->hasFile('thumbnail')) {
// Hapus file lama jika ada
if ($post->thumbnail && \Storage::disk('public')->exists($post->thumbnail)) {
\Storage::disk('public')->delete($post->thumbnail);
}
// Simpan file baru
$path = $request->file('thumbnail')->store('thumbnails', 'public');
$data['thumbnail'] = $path;
}
$post->update($data);
return redirect()->route('posts.index')->with('success', 'Berita berhasil diperbarui!');
}
8.6 Update View (Blade Template)
a. Form Tambah Berita (create.blade.php)
Tambahkan atribut enctype agar form dapat mengirim file.
Tambahkan input thumbnail:
<form action="{{ route('posts.store') }}" method="POST" enctype="multipart/form-data">
@csrf
...
<div class="mb-3">
<label>Thumbnail</label>
<input type="file" name="thumbnail" class="form-control">
</div>
...
</form>
b. Tampilkan Thumbnail (show.blade.php)
Lalu tampilkan gambar di show.blade.php:
@if($post->thumbnail)
<img src="{{ asset('storage/'.$post->thumbnail) }}" class="img-fluid mb-3" alt="Thumbnail">
@endif
c. Daftar Berita (index.blade.php)
Tambahkan kolom thumbnail:
<th>Thumbnail</th>
Isi data:
<td>
@if($post->thumbnail)
<img src="{{ asset('storage/'.$post->thumbnail) }}" width="80">
@endif
</td>
Dan di edit.blade.php, bisa ditambahkan input upload:
d. Edit Berita (edit.blade.php)
<form action="{{ route('posts.update', $post) }}" method="POST" enctype="multipart/form-data">
@csrf
...
{{-- Thumbnail lama --}}
<div class="mb-3">
<label class="form-label d-block">Thumbnail Sekarang:</label>
@if ($post->thumbnail)
<img src="{{ asset('storage/' . $post->thumbnail) }}" alt="Thumbnail" class="img-thumbnail mb-2" width="200">
@else
<p><em>Belum ada thumbnail</em></p>
@endif
</div>
{{-- Upload Thumbnail baru --}}
<div class="mb-3">
<label for="thumbnail" class="form-label">Ganti Thumbnail (Opsional)</label>
<input type="file" name="thumbnail" id="thumbnail" class="form-control">
<small class="text-muted">Kosongkan jika tidak ingin mengubah gambar.</small>
</div>
...
</form>
8.7 Menjalankan Aplikasi
php artisan serve
Lalu buka di browser:
👉 localhost:8000/posts atau http://127.0.0.1:8000/posts