Kita akan membuat Modul Kategori sebagai bagian dari CMS sederhana ini. Modul ini memungkinkan pengguna untuk menambahkan, mengedit, dan menghapus kategori serta tag yang dapat digunakan dalam artikel atau post.
Berikut adalah roadmap untuk Modul Kategori dan Tag:
Roadmap Modul Kategori
- Membuat Tabel dan Model untuk Kategori
- Membuat CRUD untuk Kategori
1. Membuat Tabel dan Model untuk Kategori
Mulai dengan membuat migrasi untuk tabel categories dan tags menggunakan perintah Artisan.
php artisan make:model Category -m
Buka file migrasi yang telah dibuat di folder database/migrations dan tambahkan kolom yang diperlukan.
Kategori Migration
Di dalam file migrasi create_categories_table.php, tambahkan kolom sebagai berikut:
public function up()
{
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->string('name')->unique();
$table->string('slug')->unique();
$table->timestamps();
});
}
Lalu jalankan migrasi ini:
php artisan migrate
2. Membuat Model Kategori
Buka file model Category.php di folder app/Models. Tambahkan pengaturan berikut:
Category.php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
use HasFactory;
protected $fillable = ['name', 'slug'];
}
3. Membuat CRUD untuk Kategori
Membuat Controller Kategori
Gunakan perintah Artisan untuk membuat CategoryController:
php artisan make:controller CategoryController --resource
Kemudian tambahkan fungsi CRUD di dalamnya:
namespace App\Http\Controllers;
use App\Models\Category;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
class CategoryController extends Controller
{
public function index()
{
$categories = Category::all();
return view('admin.categories.index', compact('categories'));
}
public function create()
{
return view('admin.categories.create');
}
public function store(Request $request)
{
$request->validate([
'name' => 'required|unique:categories,name',
]);
Category::create([
'name' => $request->name,
'slug' => Str::slug($request->name),
]);
return redirect()->route('categories.index')->with('success', 'Category created successfully');
}
public function edit(Category $category)
{
return view('admin.categories.edit', compact('category'));
}
public function update(Request $request, Category $category)
{
$request->validate([
'name' => 'required|unique:categories,name,' . $category->id,
]);
$category->update([
'name' => $request->name,
'slug' => Str::slug($request->name),
]);
return redirect()->route('categories.index')->with('success', 'Category updated successfully');
}
public function destroy(Category $category)
{
$category->delete();
return redirect()->route('categories.index')->with('success', 'Category deleted successfully');
}
}
Membuat View untuk Kategori
Di folder resources/views/admin/categories, buat file berikut:
index.blade.php(Menampilkan daftar kategori)create.blade.php(Form tambah kategori)edit.blade.php(Form edit kategori)
Untuk index.blade.php:
@extends('layouts.admin')
@section('content')
<h2>Categories</h2>
<a href="{{ route('categories.create') }}" class="btn btn-primary">Add Category</a>
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Slug</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
@foreach($categories as $category)
<tr>
<td>{{ $category->name }}</td>
<td>{{ $category->slug }}</td>
<td>
<a href="{{ route('categories.edit', $category->id) }}" class="btn btn-sm btn-warning">Edit</a>
<form action="{{ route('categories.destroy', $category->id) }}" method="POST" style="display:inline-block;">
@csrf
@method('DELETE')
<button type="submit" class="btn btn-sm btn-danger">Delete</button>
</form>
</td>
</tr>
@endforeach
</tbody>
</table>
@endsection
create.blade.php (Form Tambah Kategori)
File ini digunakan untuk menambahkan kategori baru ke database.
@extends('layouts.admin')
@section('content')
<div class="container">
<h2>Create Category</h2>
<a href="{{ route('categories.index') }}" class="btn btn-secondary mb-3">Back to Categories</a>
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<form action="{{ route('categories.store') }}" method="POST">
@csrf
<div class="mb-3">
<label for="name" class="form-label">Category Name</label>
<input type="text" name="name" class="form-control" id="name" placeholder="Enter category name" value="{{ old('name') }}" required>
</div>
<button type="submit" class="btn btn-primary">Create Category</button>
</form>
</div>
@endsection
edit.blade.php (Form Edit Kategori)
File ini digunakan untuk mengedit kategori yang sudah ada di database.
@extends('layouts.admin')
@section('content')
<div class="container">
<h2>Edit Category</h2>
<a href="{{ route('categories.index') }}" class="btn btn-secondary mb-3">Back to Categories</a>
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<form action="{{ route('categories.update', $category->id) }}" method="POST">
@csrf
@method('PUT')
<div class="mb-3">
<label for="name" class="form-label">Category Name</label>
<input type="text" name="name" class="form-control" id="name" placeholder="Enter category name" value="{{ old('name', $category->name) }}" required>
</div>
<button type="submit" class="btn btn-primary">Update Category</button>
</form>
</div>
@endsection
Menambahkan Route
Tambahkan route untuk Kategori di web.php:
use App\Http\Controllers\CategoryController;
Route::resource('admin/categories', CategoryController::class)->middleware('auth');
Layout Admin
Tambahkan template layout halaman admin sederhana dengan sidebar di sebelah kiri dan konten utama di sebelah kanan. buat folder layouts di view, kemudian buat file admin.blade.php dan isi code berikut:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Admin Dashboard</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css" rel="stylesheet">
<style>
/* Sidebar styling */
#sidebar {
width: 250px;
height: 100vh;
position: fixed;
top: 0;
left: 0;
background-color: #1e3d59;
color: #fff;
padding-top: 20px;
z-index: 1000;
transition: all 0.3s;
}
#sidebar .nav-link {
color: #cdd3d8;
font-size: 16px;
padding: 15px 20px;
display: flex;
align-items: center;
}
#sidebar .nav-link .fa {
margin-right: 10px;
font-size: 18px;
}
#sidebar .nav-link.active, #sidebar .nav-link:hover {
background-color: #0b2638;
color: #fff;
}
/* Content area */
#content {
margin-left: 250px;
padding: 20px;
background-color: #f8f9fa;
min-height: 100vh;
transition: margin-left 0.3s;
}
/* Sidebar toggle button for mobile */
#sidebarToggle {
display: none;
}
@media (max-width: 768px) {
#sidebar {
left: -250px;
}
#sidebar.active {
left: 0;
}
#content {
margin-left: 0;
}
#content.active {
margin-left: 250px;
}
#sidebarToggle {
display: block;
position: fixed;
top: 10px;
left: 10px;
z-index: 1100;
font-size: 24px;
color: #1e3d59;
background-color: #fff;
border: none;
}
}
</style>
</head>
<body>
<!-- Sidebar Toggle Button (visible on mobile) -->
<button id="sidebarToggle" class="btn">
<i class="fa fa-bars"></i>
</button>
<!-- Sidebar -->
<div id="sidebar">
<h4 class="text-center mt-3">Admin Panel</h4>
<nav class="nav flex-column mt-4">
<a class="nav-link {{ request()->is('dashboard') ? 'active' : '' }}" href="{{ route('admin.dashboard') }}">
<i class="fa fa-tachometer-alt"></i> Dashboard
</a>
<a class="nav-link {{ request()->is('categories*') ? 'active' : '' }}" href="{{ route('categories.index') }}">
<i class="fa fa-tags"></i> Categories
</a>
<a class="nav-link" href="{{ route('logout') }}">
<i class="fa fa-sign-out-alt"></i> Logout
</a>
</nav>
</div>
<!-- Main Content -->
<div id="content">
<div class="container-fluid">
@yield('content')
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
// Toggle sidebar visibility on mobile
document.getElementById('sidebarToggle').addEventListener('click', function() {
document.getElementById('sidebar').classList.toggle('active');
document.getElementById('content').classList.toggle('active');
});
</script>
</body>
</html>
Testing CRUD Kategori.
Silahkan buka http://localhost:8000/admin/categories/ lalu lakukan CRUD (Create, Update dan Delete) untuk kategori.
Selamat Mencobaaa!!!