Skip to main content

Overview

The Blog feature in LaraCMS provides a complete content management system for creating, organizing, and publishing blog posts. Posts support rich text content, featured images, categorization, and tagging.

Database Structure

The posts table stores all blog content with the following structure:
posts
  - id: bigint (primary key)
  - user_id: bigint (foreign key to users)
  - title: string
  - post_image: text (nullable)
  - slug: string (unique)
  - body: text
  - status: string (default: 'draft')
  - is_published: boolean (default: false)
  - published_at: timestamp (nullable)
  - view_count: integer (default: 0)
  - like_count: integer (default: 0)
  - dislike_count: integer (default: 0)
  - comment_count: integer (default: 0)
  - created_at: timestamp
  - updated_at: timestamp
Reference: database/migrations/2025_03_31_154815_create_posts_table.php:14

Model Relationships

Post Model

The Post model defines relationships with users, categories, and tags:
class Post extends Model
{
    protected $fillable = [
        'user_id', 'title', 'body', 'slug', 'post_image'
    ];

    // Each post belongs to one user (author)
    public function user()
    {
        return $this->belongsTo(User::class);
    }

    // Posts can have multiple categories
    public function blogCategories()
    {
        return $this->belongsToMany(BlogCategory::class, 'blog_category_post');
    }

    // Posts can have multiple tags
    public function tags()
    {
        return $this->belongsToMany(Tag::class);
    }
}
Reference: app/Models/Post.php:7

User Workflows

Admin Workflow

  1. Navigate to Blog Management
    • Go to /admin/blog/posts to view all posts
    • Click “Create New Post” or navigate to /admin/blog/create
  2. Fill Post Details
    • Title: Enter a descriptive title (min 8 characters, max 255)
    • Slug: Auto-generated URL-friendly identifier (must be unique)
    • Body: Rich text content for the post
    • Featured Image: Upload an optional post image (stored in storage/images/)
  3. Organize Content
    • Select one or more categories from the dropdown
    • Add relevant tags for searchability
  4. Publish or Save as Draft
    • Status defaults to draft
    • Set is_published to true when ready to go live
    • published_at timestamp records when post goes live
Route: POST /admin/blog/posts
Controller: BlogController@store
Reference: app/Http/Controllers/BlogController.php:63

Edit Workflow

  1. Access Edit Screen
    • From the posts list at /admin/blog/posts
    • Click “Edit” on any post to go to /admin/blog/posts/{post}/edit
  2. Update Content
    • Modify title, body, or featured image
    • Change categories or tags as needed
    • Update validation ensures title uniqueness (except for current post)
  3. Save Changes
    • Form submits to PATCH /admin/blog/posts/{post}/update
    • System syncs categories and tags relationships
    • Flash message confirms successful update
Route: PATCH /admin/blog/posts/{post}/update
Controller: BlogController@update
Reference: app/Http/Controllers/BlogController.php:104

Delete Workflow

  1. Initiate Delete
    • Click “Delete” button on post list or edit screen
  2. Authorization Check
    • System verifies user has delete permission via Gate
  3. Cascade Deletion
    • Post record is removed
    • Related pivot table entries (categories, tags) are automatically deleted
    • Featured image remains in storage (manual cleanup may be needed)
Route: DELETE /admin/blog/posts/{post}
Controller: BlogController@destroy
Reference: app/Http/Controllers/BlogController.php:133

Frontend Display

Blog Index

Route: GET /blogDisplays paginated list of all published posts ordered by published_at (newest first).
  • Shows 8 posts per page
  • Accessible to all visitors
  • Links to individual post pages
Controller: PostController@index
Reference: routes/web.php:58

Single Post

Route: GET /blog/{slug}Displays full post content including:
  • Title and featured image
  • Author information (via user relationship)
  • Post body content
  • Categories and tags
  • Engagement metrics (views, likes, comments)
Controller: PostController@show
Reference: routes/web.php:59

Validation Rules

When creating or updating posts, the system enforces:
[
    'title' => 'required|unique:posts|min:8|max:255',
    'post_image' => 'file',
    'body' => 'required',
    'slug' => 'required|unique:posts,slug',
    'category_id' => 'nullable|exists:blog_categories,id',
    'tags' => 'nullable|array',
    'tags.*' => 'exists:tags,id'
]
Reference: app/Http/Controllers/BlogController.php:67

Permissions

Blog management requires specific permissions:
  • View Posts: access.admin.panel middleware required
  • Create Posts: create gate authorization on Post class
  • Update Posts: update gate authorization on specific post
  • Delete Posts: delete gate authorization on specific post

File Storage

Featured images are stored using Laravel’s Storage system:
// Images stored in public disk under 'images' directory
Storage::disk('public')->put('images', $request->file('post_image'));
Storage Path: storage/app/public/images/
Public URL: /storage/images/{filename}
Reference: app/Http/Controllers/BlogController.php:80

Key Routes

MethodURIActionDescription
GET/admin/blog/postsBlogController@indexList all posts
GET/admin/blog/createBlogController@createShow create form
POST/admin/blog/postsBlogController@storeStore new post
GET/admin/blog/posts/{post}/editBlogController@editShow edit form
PATCH/admin/blog/posts/{post}/updateBlogController@updateUpdate post
DELETE/admin/blog/posts/{post}BlogController@destroyDelete post
GET/blogPostController@indexFrontend post list
GET/blog/{slug}PostController@showFrontend single post
Reference: routes/web.php:93-99

Build docs developers (and LLMs) love