Setelah fondasinya siap, pekerjaan berikutnya adalah menyusun struktur data yang kuat tetapi tetap sederhana. Saya ingin artikel mudah ditulis, mudah dicari, dan mudah dikelompokkan. Dari kebutuhan itu lahir lima entitas utama: Article, Category, Tag, Comment, dan Menu.
Article sebagai pusat semuanya
Model Article menjadi inti blog ini. Di sana saya menyimpan judul, slug, ringkasan, isi lengkap, status publikasi, meta SEO, jumlah view, hingga referensi ke kategori dan penulis. Saya juga menambahkan SoftDeletes supaya artikel yang dihapus tidak langsung hilang permanen, serta accessor untuk menghitung estimasi waktu baca dari jumlah kata.
Slug otomatis untuk URL yang rapi
Saya memakai paket spatie/laravel-sluggable agar slug artikel dan kategori dibuat otomatis dari judul atau nama. Hasilnya URL menjadi lebih bersih, misalnya /artikel/seri-membangun-agusp-id-1-fondasi-laravel-11-dan-tailwind-css. Ini membantu SEO dan membuat tautan lebih mudah dipahami pembaca.
Kategori dan tag punya peran yang berbeda
Saya sengaja membedakan kategori dan tag. Kategori dipakai sebagai payung besar seperti Tutorial, sedangkan tag dipakai untuk konteks yang lebih spesifik seperti laravel, tailwindcss, atau seo. Struktur ini membuat halaman listing lebih fleksibel tanpa membuat navigasi utama jadi rumit.
Komentar dan menu saya anggap sebagai konten juga
Komentar di blog ini tidak hanya ditempelkan ke artikel, tetapi juga punya alur moderasi. Ada status approved dan pending, sehingga percakapan tetap terjaga kualitasnya. Sementara itu menu header dan footer juga saya simpan di database agar bisa diubah dari panel admin tanpa perlu menyentuh kode.
Status publish penting untuk workflow
Setiap artikel punya status draft, published, atau archived. Saya sengaja menambahkan tiga status ini karena alur menulis sering berubah. Kadang ide masih mentah, kadang artikel sudah layak tayang, dan kadang tulisan lama perlu disembunyikan tanpa dihapus.
$table->enum('status', ['draft', 'published', 'archived'])->default('draft');
$table->timestamp('published_at')->nullable();
$table->unsignedBigInteger('views')->default(0);
Dengan struktur seperti ini, saya tidak hanya mendapatkan blog yang bisa tayang, tetapi juga fondasi CMS kecil yang nyaman dipakai jangka panjang.