Post Management
The blog system provides an admin panel for creating, editing, and managing posts. Posts support markdown content, images, and multi-language translations.
Creating Posts
To create a new post, navigate to /admin/posts/create. You can create posts manually or use AI generation (see AI Content Generation).
Post Fields
- Title - The title of the post. This is required and will be used to generate a unique slug.
- Description - A summary/teaser of the post.
- Image - You have two options, you can use Cloudinary to upload an image or you can use a URL of an image. When generating a post with AI, the image will be generated automatically and uploaded to cloudinary.
- Author - The author of the post.
- Content - The content of the post. This will be in markdown format.
- Active - Controls post visibility on public blog. If the post is not active, it will not be visible to the public.
- Promoted - Featured posts appear prominently on blog index. If the post is promoted, it will be featured on the blog index.
Automatic Slug Generation
The Post model automatically generates URL-friendly slugs from titles. The generation handles edge cases:
// Automatically called when creating/updating a post
Post::createUniqueSlug(string $title, ?string $language = null, ?string $referenceNumber = null): string
Slug Generation Rules
- Titles are converted to URL-friendly slugs using
Str::slug() - Non-English posts append the language code (e.g.,
my-post-es) - If a title doesn't generate a valid slug (e.g., Korean, Chinese), the system:
- First tries to use the English version's slug + language code
- Falls back to a hash-based slug:
post-{hash}-{lang}
- If a slug already exists, a counter is appended (e.g.,
my-post-1)
Reference Numbers
Each post automatically receives a unique reference number (format: REF-000001) that groups all translations of the same post. Reference numbers are:
- Auto-generated when creating the first post
- Shared across all translations via the
reference_numberfield - Used to link related posts in different languages
// Automatically called when creating a post
Post::createUniqueReferenceNumber(): string
Admin Interface
Posts Table
The PostsTable Livewire component displays all posts with:
- Search functionality (searches title and description)
- Pagination (8 posts per page)
- Delete functionality
- Links to edit pages
Edit Form
The EditPost Livewire component provides:
- Markdown editor for content
- Image preview
- AI generation integration
- Translation management
Public Blog Views
Blog Index
The public blog index (/blog) displays:
- Most recent promoted post (featured)
- Other promoted posts
- Regular posts (non-promoted)
- All filtered by current locale
Post Show Page
The post show page (/blog/{slug}) shows:
- Full post content (rendered from Markdown using prose classes)
- Related posts (same language, excluding current)
Related Routes
| Method | Path | Route name | Description |
|---|---|---|---|
| GET | /blog | blog | Public blog index |
| GET | /blog/{slug} | posts.show | Public post view |
| GET | /admin/posts | admin.posts.index | Admin posts listing |
| GET | /admin/posts/create | admin.posts.create | Create new post |
| GET | /admin/posts/{post}/edit | admin.posts.edit | Edit existing post |
Read Next
- AI Content Generation for generating posts with AI
- Translations for multi-language support