A Filament CMS package for Laravel.
Fund package maintenance!
:vendor_name
Requires
- php: ^8.2
- anhskohbo/no-captcha: ^3.7
- awcodes/filament-curator: *
- awcodes/filament-tiptap-editor: ^3.5
- bezhansalleh/filament-language-switch: ^3.1
- bezhansalleh/filament-shield: ^3.3
- codezero/laravel-unique-translation: ^4.3
- datlechin/filament-menu-builder: ^0.7.0
- filament/filament: ^3.3
- filament/spatie-laravel-settings-plugin: ^3.3
- illuminate/contracts: ^10.0||^11.0||^12.0
- jeffgreco13/filament-breezy: ^2.6
- laravel/framework: ^12.0
- laravel/tinker: ^2.10.1
- littleboy130491/seo-suite: *
- livewire/livewire: ^3.6
- outerweb/filament-translatable-fields: ^2.1
- ryangjchandler/laravel-cloudflare-turnstile: ^2.0
- shortpixel/shortpixel-php: *
- shuvroroy/filament-spatie-laravel-backup: ^2.2
- solution-forest/filament-translate-field: ^1.4
- spatie/laravel-package-tools: ^1.16
- spatie/laravel-responsecache: ^7.7
- spatie/laravel-settings: ^3.4
- spatie/laravel-sitemap: ^7.3
- spatie/laravel-translatable: ^6.11
- stechstudio/filament-impersonate: ^3.16
- symfony/http-client: ^7.2
- symfony/mailgun-mailer: ^7.2
- yizack/instagram-feed: ^2.0
Requires (Dev)
- fakerphp/faker: ^1.23
- larastan/larastan: ^2.9||^3.0
- laravel/pail: ^1.2.2
- laravel/pint: ^1.13
- laravel/sail: ^1.41
- mockery/mockery: ^1.6
- nunomaduro/collision: ^8.6
- orchestra/testbench: ^10.0.0||^9.0.0||^8.22.0
- pestphp/pest: ^3.8
- pestphp/pest-plugin-arch: ^3.0
- pestphp/pest-plugin-laravel: ^3.2
- phpstan/extension-installer: ^1.3||^2.0
- phpstan/phpstan-deprecation-rules: ^1.1||^2.0
- phpstan/phpstan-phpunit: ^1.3||^2.0
- spatie/laravel-ray: ^1.35
This package is auto-updated.
Last update: 2025-10-02 05:31:39 UTC
README
A powerful, multilingual Laravel CMS package built with Filament v3. Features hierarchical content management, role-based permissions, dynamic components, and extensive customization options.
Features
π Multilingual Content - Full translation support with smart fallback and URL redirection
π Content Management - Pages, posts, categories, tags, and comments with hierarchical structure
π Role-Based Access - Comprehensive permission system with predefined roles
π§© Dynamic Components - Flexible component system for reusable content blocks
π SEO Optimized - Built-in SEO suite integration and sitemap generation
π± Responsive Admin - Beautiful Filament-powered admin interface
π¨ Template System - WordPress-like template hierarchy with custom slug support
π§ Form System - Built-in contact forms with email notifications and reCAPTCHA
π Analytics - Page views and likes tracking with real-time updates
π Scheduled Publishing - Automatic content publishing with cron integration
π· Media Management - Advanced media handling with Curator integration
π― Performance - Optimized queries, caching, and route resolution
π¬ Comments System - Hierarchical comments with moderation and approval workflow
Requirements
- PHP 8.2+
- Laravel 12.0+
- MySQL 8.0+ / PostgreSQL 13+
- Node.js 18+ (for asset compilation)
Installation
Step 1: Install Package
composer require littleboy130491/cms
Step 2: Run Installation Command
php artisan cms:install
This command will:
- Publish configuration files
- Publish and run migrations
- Publish views and assets
- Generate default permission roles
- Guide you through the setup process
Step 3: Configure Environment
Add required environment variables to your .env
file:
# reCAPTCHA (optional but recommended) NOCAPTCHA_SITEKEY=your_recaptcha_site_key NOCAPTCHA_SECRET=your_recaptcha_secret_key # Instagram Integration (optional) INSTAGRAM_ACCESS_TOKEN=your_instagram_access_token # Admin Email for Notifications MAIL_ADMIN_EMAIL=admin@yoursite.com # Debug Mode (development only) CMS_DEBUG_MODE_ENABLED=false
Note: The CMS plugin is automatically registered with all Filament panels. No manual plugin registration is required!
Quick Start
1. Create Your First Admin User
php artisan make:filament-user
2. Access Admin Panel
Visit /admin
and log in with your newly created admin account.
3. Configure General Settings
Navigate to Settings > General in the admin panel to configure:
- Site name and description
- Contact information
- Social media links
- Logo and favicon
4. Create Your First Content
- Pages: Create static pages like "About", "Contact", etc.
- Posts: Create blog posts or news articles
- Categories & Tags: Organize your content
- Menus: Build navigation menus
- Comments: Manage user comments and feedback
Configuration
Content Models Configuration
The CMS supports multiple content types with custom slug support defined in config/cms.php
:
'content_models' => [ 'pages' => [ 'model' => \Littleboy130491\Sumimasen\Models\Page::class, 'name' => 'Pages', 'type' => 'content', 'has_archive' => false, 'has_single' => true, ], 'posts' => [ 'model' => \App\Models\Post::class, 'name' => 'Posts', 'type' => 'content', 'has_archive' => true, 'has_single' => true, 'archive_SEO_title' => 'Blog Posts', 'archive_SEO_description' => 'Latest news and articles', 'eager_load' => ['categories', 'tags'], ], 'categories' => [ 'model' => \Littleboy130491\Sumimasen\Models\Category::class, 'name' => 'Categories', 'type' => 'taxonomy', 'has_archive' => true, 'has_single' => false, 'display_content_from' => 'posts', ], 'facilities' => [ 'model' => \App\Models\Facility::class, 'name' => 'Facilities', 'type' => 'content', 'slug' => 'fasilitas', // Custom slug override 'has_archive' => true, 'has_single' => true, ], 'commercials' => [ 'model' => \App\Models\Commercial::class, 'name' => 'Commercials', 'type' => 'content', 'slug' => 'area-komersil', // Custom slug override 'has_archive' => false, 'has_single' => true, ], // Add your custom content types here ],
Custom Slug Support
The CMS supports custom URL slugs different from the configuration key:
- Without custom slug:
/facilities
(uses the config key) - With custom slug:
/fasilitas
(uses the custom slug value)
This allows you to have:
- Clean, localized URLs
- SEO-friendly paths
- Maintain internal code organization
Multilingual Setup
Configure supported languages:
'multilanguage_enabled' => true, 'default_language' => 'en', 'language_available' => [ 'en' => 'English', 'id' => 'Indonesian', 'zh' => 'Chinese', 'ko' => 'Korean', ],
Comments System Configuration
Enable comments on your content models by adding the HasComments
trait:
use Littleboy130491\Sumimasen\Traits\HasComments; class Post extends Model { use HasComments; // Your model code... }
Comments support:
- Hierarchical Structure: Nested replies with unlimited depth
- Moderation Workflow: Pending, approved, and rejected status
- Admin Management: Full CRUD operations in Filament admin
- Frontend Integration: Ready-to-use comment components
Template System
The CMS uses a sophisticated template hierarchy system with WordPress-like template resolution and custom slug support.
Template Hierarchy
Templates are resolved in order of specificity, checking both your application views and the package's fallback views:
1. Home Page Templates
For the home page (/
):
1. user defined template from CMS
2. templates/home.blade.php (content slug in default language)
3. templates/singles/home.blade.php (specific home template)
4. templates/singles/front-page.blade.php (front page template)
5. templates/front-page.blade.php (front page template)
6. templates/singles/default.blade.php (default single)
7. templates/default.blade.php (global default)
2. Static Page Templates
For static pages (e.g., /about
):
1. user defined template from CMS
2. templates/about.blade.php (content slug in default language)
3. templates/singles/about.blade.php (specific page by slug)
4. templates/singles/page.blade.php (all pages)
5. templates/page.blade.php (all pages)
6. templates/singles/default.blade.php (default single)
7. templates/default.blade.php (global default)
3. Single Content Templates
For single content items with custom slug support (e.g., /fasilitas/pool-area
):
1. user defined template from CMS
2. templates/pool-area.blade.php (content slug in default language)
3. templates/singles/fasilitas-pool-area.blade.php (specific content by slug)
4. templates/singles/fasilitas.blade.php (all content of this type by slug)
5. templates/fasilitas.blade.php (all content of this type)
6. templates/singles/facility-pool-area.blade.php (fallback by config key)
7. templates/singles/facility.blade.php (fallback by config key)
8. templates/facility.blade.php (fallback by config key)
9. templates/singles/default.blade.php (default single)
10. templates/default.blade.php (global default)
4. Archive Templates
For content archives (e.g., /fasilitas
):
1. templates/archives/archive-fasilitas.blade.php (specific archive by slug)
2. templates/archive-fasilitas.blade.php (specific archive by slug)
3. templates/archives/archive.blade.php (default archive)
4. templates/archive.blade.php (default archive)
5. Taxonomy Templates
For taxonomy archives (e.g., /categories/technology
):
1. user defined template from CMS
2. templates/archives/categories-technology.blade.php (specific taxonomy-term)
3. templates/archives/categories.blade.php (all terms in taxonomy)
4. templates/categories-technology.blade.php (specific taxonomy-term)
5. templates/categories.blade.php (all terms in taxonomy)
6. templates/archives/archive.blade.php (default archive)
7. templates/archive.blade.php (default archive)
Template Structure
Create your templates in resources/views/templates/
:
templates/
βββ default.blade.php # Global fallback
βββ home.blade.php # Home page
βββ page.blade.php # All static pages
βββ custom-hero-layout.blade.php # User-defined template
βββ custom-about-layout.blade.php # User-defined template
βββ about.blade.php # Content slug template
βββ contact.blade.php # Content slug template
βββ singles/
β βββ default.blade.php # Default single template
β βββ page.blade.php # All static pages
β βββ page-about.blade.php # Specific page
β βββ post.blade.php # All posts
β βββ post-featured.blade.php # Specific post
β βββ fasilitas.blade.php # Custom slug content type
β βββ facility.blade.php # Fallback for original key
ββββarchives/
ββββ archive.blade.php # Default archive
ββββ archive-posts.blade.php # Posts archive
ββββ archive-fasilitas.blade.php # Custom slug archive
ββββ categories.blade.php # Category taxonomy
ββββ categories-technology.blade.php # Specific category
Template Context
Each template receives specific variables:
All Templates
$lang // Current language $bodyClasses // Generated CSS classes
Single Content Templates
$item // The record from CMS $content_type // Content type slug $content_slug // Content slug $title // Content title
Archive Templates
$items // Paginated collection $record // Record from static page CMS assigned as archive $archive // Archive object with metadata $post_type // Content type slug $title // Archive title
Taxonomy Templates
$items // Related content (paginated) $taxonomy // Taxonomy key $taxonomy_slug // Taxonomy slug $record // Taxonomy record from CMS $title // Taxonomy title
Template Body Classes
The system automatically generates CSS classes for styling:
// Example body classes "lang-en type-post slug-my-post-title" "lang-id type-fasilitas slug-pool-area" "lang-en archive-posts archive-page" "lang-id taxonomy-categories term-technology"
Use these in your CSS:
.lang-en .post { /* English posts */ } .lang-id .fasilitas { /* Indonesian facilities */ } .archive-posts { /* Posts archive styling */ } .taxonomy-categories { /* Category taxonomy styling */ }
Performance Optimization
The template system includes several performance optimizations:
- Cached Route Resolution: Routes are cached for 24 hours
- Cached Config Lookups: Content model configs are cached
- Eager Loading: Automatically loads configured relationships
- Template Caching: Laravel's view caching applies to all templates
To clear caches:
# Clear all CMS caches php artisan cms:routes-clear # Clear view cache php artisan view:clear
Advanced Features
Comments System
The CMS includes a powerful hierarchical comments system with the following features:
Admin Management
Comments Resource: Manage all comments from a centralized location with:
- Bulk status updates (approve, reject, pending)
- Content moderation tools
- User information tracking
- Hierarchical relationship viewing
Relation Managers: Each commentable model automatically gets a comments relation manager for inline comment management:
// Automatically available in your Filament resources public static function getRelations(): array { return [ RelationManagers\CommentsRelationManager::class, ]; }
Model Integration
Add comments to any model:
use Littleboy130491\Sumimasen\Traits\HasComments; class Article extends Model { use HasComments; // Now your model has comments relationship }
Access comments in your code:
// Get all comments $article->comments // Get only approved comments $article->approvedComments // Get Filament edit URL (if resource exists) $article->getFilamentEditUrl()
Frontend Integration
Display comments in your templates:
{{-- Show approved comments --}} @foreach($post->approvedComments as $comment) <div class="comment"> <h5>{{ $comment->name }}</h5> <p>{{ $comment->content }}</p> <small>{{ $comment->created_at->diffForHumans() }}</small> {{-- Show replies --}} @if($comment->replies->count()) <div class="replies ml-4"> @foreach($comment->replies as $reply) <div class="reply"> <h6>{{ $reply->name }}</h6> <p>{{ $reply->content }}</p> </div> @endforeach </div> @endif </div> @endforeach
Dynamic Components
Create reusable content blocks:
- Create Component in Admin: Add a new component with a unique name
- Create Blade Template:
resources/views/components/dynamic/{name}.blade.php
- Use in Templates:
<x-component-loader name="your-component" />
Example component template:
{{-- resources/views/components/dynamic/hero-slider.blade.php --}} @foreach ($componentData->blocks as $block) @if ($block['type'] === 'slide') <div class="slide"> <h2>{{ $block['data']['heading'] }}</h2> <p>{{ $block['data']['description'] }}</p> @if(isset($block['data']['image_url'])) <img src="{{ $block['data']['image_url'] }}" alt="{{ $block['data']['heading'] }}"> @endif </div> @endif @endforeach
Livewire Components
Built-in interactive components:
{{-- Like button with real-time updates --}} <livewire:sumimasen-cms.like-button :content="$post" /> {{-- Contact form with reCAPTCHA --}} <livewire:sumimasen-cms.submission-form /> {{-- Comment form (if implementing frontend comments) --}} <livewire:sumimasen-cms.comment-form :commentable="$post" />
Settings Management
Access site settings in templates:
@php $settings = app(\App\Settings\GeneralSettings::class); @endphp <footer> <p>{{ $settings->site_name }}</p> <p>Email: {{ $settings->email }}</p> <p>Phone: {{ $settings->phone_1 }}</p> </footer>
SEO Features
Automatic SEO optimization:
- Meta titles and descriptions
- Open Graph tags
- Structured data
- XML sitemap generation
- Multilingual hreflang tags
Debug Mode
Enable comprehensive debugging in development:
CMS_DEBUG_MODE_ENABLED=true APP_ENV=local
Provides detailed HTML comments with:
- Request information
- Database queries
- View data
- Performance metrics
Scheduled Tasks
Set up cron job for automated features:
* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1
Automated tasks include:
- Publishing scheduled content (every 30 minutes)
- Refreshing Instagram tokens (monthly)
- Other maintenance tasks
Security Features
- CSRF protection on all forms
- XSS prevention with input sanitization
- Role-based access control
- reCAPTCHA integration
- Secure file uploads
- Input validation and filtering
- Comment moderation system
Performance Optimization
- Query optimization with eager loading
- Response caching support
- Image optimization with Curator
- Queue support for heavy operations
- Database indexing
- Asset minification
- Optimized comment queries with relationship loading
- Cached route resolution for custom slugs
Customization
Extending Models
Add traits to your models:
use Littleboy130491\Sumimasen\Traits\HasPageViews; use Littleboy130491\Sumimasen\Traits\HasPageLikes; use Littleboy130491\Sumimasen\Traits\HasComments; class CustomModel extends Model { use HasPageViews, HasPageLikes, HasComments; }
Custom Resources
Override default resources:
SumimasenPlugin::make() ->resources([ CustomPostResource::class, CustomCommentResource::class, // ... other resources ])
Debug Mode
Enable debug mode for detailed error information:
CMS_DEBUG_MODE_ENABLED=true APP_DEBUG=true
Extending Content Blocks in Your Main App
This guide explains how to extend the content blocks from the sumimasen package in your main Laravel application without modifying the trait in your resources.
Step 1: Create a Content Blocks Service Provider
Create a new service provider in your main app at app/Providers/ContentBlocksServiceProvider.php
:
php artisan make:provider ContentBlocksServiceProvider
Then edit the file to add your custom content blocks:
<?php namespace App\Providers; use Awcodes\Curator\Components\Forms\CuratorPicker; use Filament\Forms\Components\Builder as FormsBuilder; use Filament\Forms\Components\Textarea; use Filament\Forms\Components\TextInput; use FilamentTiptapEditor\TiptapEditor; use Illuminate\Support\ServiceProvider; class ContentBlocksServiceProvider extends ServiceProvider { /** * Register services. */ public function register(): void { // } /** * Bootstrap services. */ public function boot(): void { // } /** * Register custom content blocks * This method is called by the HasContentBlocks trait to add custom blocks */ public function registerCustomContentBlocks(): array { return [ $this->getCustomTestimonialBlock(), $this->getCustomPricingBlock(), // Add more custom blocks here ]; } /** * Example: Custom Testimonial Block */ private function getCustomTestimonialBlock(): FormsBuilder\Block { return FormsBuilder\Block::make('testimonial') ->label('Testimonial') ->schema([ TextInput::make('block_id') ->label('Block ID') ->helperText('Identifier for the block') ->columnSpanFull(), TextInput::make('customer_name') ->label('Customer Name') ->required(), TextInput::make('customer_title') ->label('Customer Title'), TiptapEditor::make('testimonial') ->label('Testimonial Content') ->profile('simple') ->columnSpanFull(), CuratorPicker::make('customer_image') ->label('Customer Image') ->acceptedFileTypes(['image/*']) ->preserveFilenames(), TextInput::make('rating') ->label('Rating') ->numeric() ->minValue(1) ->maxValue(5) ->default(5), ]) ->columns(2); } /** * Example: Custom Pricing Block */ private function getCustomPricingBlock(): FormsBuilder\Block { return FormsBuilder\Block::make('pricing') ->label('Pricing Table') ->schema([ TextInput::make('block_id') ->label('Block ID') ->helperText('Identifier for the block') ->columnSpanFull(), TextInput::make('title') ->label('Section Title') ->required(), TiptapEditor::make('description') ->label('Section Description') ->profile('simple') ->columnSpanFull(), // You can add repeaters for pricing plans here TextInput::make('currency') ->label('Currency Symbol') ->default('$'), ]) ->columns(2); } }
Step 2: Register the Service Provider
In Laravel 11+, service providers are automatically registered in bootstrap/providers.php
when you run the make:provider
command. If you're using an older version or need to manually register it, add your service provider to the providers
array in config/app.php
:
'providers' => [ // ... other providers App\Providers\ContentBlocksServiceProvider::class, ],
For Laravel 11+, your provider should already be registered in bootstrap/providers.php
:
<?php return [ // ... other providers App\Providers\ContentBlocksServiceProvider::class, ];
Contributing
Please see CONTRIBUTING for details on how to contribute to this project.
Security
If you discover any security vulnerabilities, please email security@yourproject.com instead of using the issue tracker.
Credits
License
The MIT License (MIT). Please see License File for more information.
Support
- π Documentation
- π Issue Tracker
- π¬ Discussions
Built with β€οΈ using Laravel, Filament, and modern PHP practices.