A flexible and extensible Content Management System package for Laravel applications. Built with support for custom post types, hierarchical categories, and rich content editing with Editor.js.
- 🎯 Custom Post Types: Define unlimited custom post types with configurable features
- 📁 Hierarchical Categories: Nested category support using Nestedset
- ✍️ Rich Content Editor: Integrated Editor.js support for modern content editing
- 🔐 Permission System: Built-in permission management for CMS operations
- 🌐 Multi-language Ready: Translation support for content
- 📱 Responsive Admin: Modern admin interface
- 🔌 Extensible: Easy to extend with custom controllers, views, and policies
- 🚀 Easy Setup: Artisan command for quick installation
- PHP ^8.2
- Laravel ^11.0 or ^12.0
- MySQL/PostgreSQL database
Install the package via Composer:
composer require javaabu/cmsRun the setup command:
php artisan cms:setupThis will:
- Publish the configuration file
- Publish and run migrations
- Optionally install default post types and categories
- Seed CMS permissions
To get started quickly with pre-configured post types and categories:
php artisan cms:setup --with-defaultsThis installs 10 ready-to-use post types (News, Blog, Downloads, Announcements, Publications, Jobs, Galleries, Tenders, Reports, Pages) with their category types and sample categories.
You can customize these defaults in config/cms.php before running setup.
After installation, configure your post types in config/cms.php:
'post_types' => [
'news' => [
'label' => 'News',
'singular_label' => 'News Article',
'features' => ['categories', 'featured_image', 'excerpt'],
'category_types' => ['news-categories'],
],
'blog' => [
'label' => 'Blog Posts',
'singular_label' => 'Blog Post',
'features' => ['categories', 'featured_image', 'excerpt', 'video-link'],
'category_types' => ['blog-categories'],
],
],
'category_types' => [
'news-categories' => [
'label' => 'News Categories',
'singular_label' => 'News Category',
'hierarchical' => true,
],
],Add CMS routes to your routes/web.php:
use Javaabu\Cms\Support\Routes;
// Admin routes
Routes::admin(
prefix: 'admin',
middleware: ['web', 'auth', 'verified']
);
// Public routes
Routes::web();
// Or register custom post type routes
Routes::customPostType(
postTypeSlug: 'news',
prefix: 'news',
middleware: ['web']
);Post types can be created via:
- Database Seeder:
use Javaabu\Cms\Models\PostType;
PostType::create([
'name' => 'News',
'singular_name' => 'News Article',
'slug' => 'news',
'icon' => 'newspaper',
'features' => [
'categories' => true,
'featured_image' => true,
'excerpt' => true,
],
]);- Admin Panel: Navigate to
/admin/post-typesafter setup
use Javaabu\Cms\Models\Post;
use Javaabu\Cms\Enums\PostStatus;
$post = Post::create([
'type' => 'news',
'title' => 'Breaking News',
'slug' => 'breaking-news',
'content' => '<p>Content here...</p>',
'excerpt' => 'Short description',
'status' => PostStatus::PUBLISHED->value,
'published_at' => now(),
]);
// Attach categories
$post->categories()->attach($categoryIds);use Javaabu\Cms\Models\Post;
// Get published posts of a type
$posts = Post::postType('news')
->published()
->ordered()
->paginate(15);
// Search posts
$posts = Post::postType('news')
->search('keyword')
->published()
->get();
// Get posts by year
$posts = Post::postType('news')
->publishedByYear(2024)
->get();use Javaabu\Cms\Models\Category;
// Get categories for select dropdown
$categories = Category::categoryList($typeId);
// Get nested categories
$categories = Category::categoryType($typeId)
->defaultOrder()
->get()
->toTree();categories- Category supportfeatured_image- Featured imageexcerpt- Post excerptdocuments- Document attachmentsimage_gallery- Image galleryvideo_link- Video embed URLdocument_number- Document reference numberexpireable- Expiry dateformat- Post format (standard, video, gallery, etc.)page_style- Custom page stylingref_no- Reference numbergazette_link- Gazette document link
The package dynamically creates permissions for each Post Type and Category Type you create. Permissions are based on the slug of the type.
For each Post Type (e.g., 'news'), the following permissions are created:
edit_{slug}- Edit own posts (e.g.,edit_news)edit_others_{slug}- Edit all posts (e.g.,edit_others_news)delete_{slug}- Delete own postsdelete_others_{slug}- Delete all postsview_{slug}- View own postsview_others_{slug}- View all postsforce_delete_{slug}- Force delete own postsforce_delete_others_{slug}- Force delete all postspublish_{slug}- Publish own postspublish_others_{slug}- Publish all postsimport_{slug}- Import posts
For each Category Type (e.g., 'news-categories'), the following permissions are created:
edit_{slug}- Edit categories (e.g.,edit_news_categories)delete_{slug}- Delete categoriesview_{slug}- View categoriesimport_{slug}- Import categories
Seed them using:
use Javaabu\Cms\seeders\CmsPermissionsSeeder;
CmsPermissionsSeeder::seedPermissions();Call this after creating your Post Types and Category Types to generate the appropriate permissions.
The package provides models and data - implement your own views:
{{-- resources/views/posts/index.blade.php --}}
@foreach($posts as $post)
<article>
<h2>{{ $post->title }}</h2>
<p>{{ $post->excerpt }}</p>
<a href="{{ route('posts.show', [$post->type, $post->slug]) }}">
Read More
</a>
</article>
@endforeachInstall the required npm packages:
npm install --save @editorjs/editorjs @editorjs/header @editorjs/list @editorjs/image @editorjs/quote @editorjs/table @editorjs/delimiter @editorjs/embed @editorjs/link @editorjs/raw @editorjs/simple-image @calumk/editorjs-columnsOr copy dependencies from package.json in the package root.
You must also configure the window.Laravel object in your admin layout. See the Installation and Setup Guide for details.
composer testFor detailed documentation, see the docs directory:
Please see CONTRIBUTING.md for details.
If you discover any security-related issues, please email security@javaabu.com instead of using the issue tracker.
The MIT License (MIT). Please see License File for more information.