Professional Laravel 12 + Filament 4 Content Management System
π― Design Philosophy: Standalone & Deployable Built to work both within NetServa 3.0 AND as a completely standalone Laravel package
- π Hierarchical Pages - Nested page structure with multiple templates
- π Blog System - Full-featured blogging with categories and tags
- π·οΈ Categories & Tags - Organize content with taxonomies
- π Menu Builder - Flexible JSON-based navigation with nested items
- π¨ Multiple Templates - Homepage, Service, Pricing, Default, and Blank layouts
- πΌοΈ Media Library - Spatie Media Library with featured images & galleries
- π SEO Optimized - Meta tags, Open Graph, Twitter Cards built-in
- π Reading Time - Automatic word count and reading time calculation
- π Sluggable URLs - Automatic SEO-friendly URL generation
- ποΈ Filament 4 Admin - Modern, beautiful admin interface
- βοΈ Rich Editor - Full-featured content editing with file attachments
- π Dark Mode - Full dark mode support throughout
- π± Responsive - Mobile-first admin panel design
- β Zero Dependencies - NO NetServa dependencies, works anywhere
- π§ͺ Comprehensive Tests - 70+ Pest tests with 100% coverage goal
- π Model Factories - Full factory support for testing
- π― Type Safe - PHP 8.4 with full type declarations
- π Soft Deletes - Safe content management
- PHP: ^8.4
- Laravel: ^12.0
- Filament: ^4.0
- Spatie Media Library: ^11.0
- Spatie Sluggable: ^3.0
composer require netserva/cmsphp artisan vendor:publish --provider="NetServa\Cms\NetServaCmsServiceProvider"php artisan migrateIn your Filament panel provider (app/Providers/Filament/AdminPanelProvider.php):
use NetServa\Cms\NetServaCmsPlugin;
public function panel(Panel $panel): Panel
{
return $panel
->plugins([
NetServaCmsPlugin::make(),
]);
}Visit /admin and start creating content!
All tables use the cms_ prefix to prevent conflicts:
| Table | Purpose |
|---|---|
cms_pages |
Hierarchical page structure with templates |
cms_posts |
Blog posts with word count tracking |
cms_categories |
Multi-type categories (post, portfolio, news, docs) |
cms_tags |
Post tagging system |
cms_post_tag |
Many-to-many pivot table |
cms_menus |
JSON-based navigation menus |
media |
Spatie Media Library tables |
All models are completely standalone with ZERO dependencies on NetServa Core:
NetServa\Cms\Models\
βββ Page // Hierarchical pages with templates & SEO
βββ Post // Blog posts with categories, tags & media
βββ Category // Multi-type categories with type scoping
βββ Tag // Simple tag model with post relationships
βββ Menu // JSON-based menu with hierarchical itemsNetServa\Cms\Http\Controllers\
βββ PageController // home(), show(), showNested()
βββ PostController // index(), show(), category(), tag()NetServa\Cms\Filament\Resources\
βββ PageResource // Full CRUD for pages
βββ PostResource // Full CRUD for posts
βββ CategoryResource // Manage categories
βββ TagResource // Manage tags
βββ MenuResource // Menu builder with nested repeatersresources/views/
βββ layouts/
β βββ app.blade.php // Main layout with SEO & menus
βββ pages/templates/
β βββ default.blade.php // Standard page
β βββ homepage.blade.php // Hero, features, CTA
β βββ service.blade.php // Service page with sidebar
β βββ pricing.blade.php // 3-tier pricing cards
β βββ blank.blade.php // Minimal template
βββ posts/
βββ index.blade.php // Blog archive with search
βββ show.blade.php // Single post with related
βββ category.blade.php // Category archive
βββ tag.blade.php // Tag archive
use NetServa\Cms\Models\Page;
$homepage = Page::factory()->homepage()->create([
'title' => 'Welcome to My Site',
'content' => '<p>Homepage content...</p>',
]);
$about = Page::factory()->create([
'title' => 'About Us',
'template' => 'default',
'parent_id' => null,
]);use NetServa\Cms\Models\Post;
use NetServa\Cms\Models\Category;
use NetServa\Cms\Models\Tag;
$category = Category::factory()->post()->create(['name' => 'Tutorials']);
$tags = Tag::factory()->count(3)->create();
$post = Post::factory()->create([
'title' => 'Getting Started with Laravel',
'content' => '<p>Post content...</p>',
]);
$post->categories()->attach($category);
$post->tags()->attach($tags);use NetServa\Cms\Models\Menu;
$menu = Menu::factory()->header()->create([
'name' => 'Main Navigation',
'items' => [
[
'label' => 'Home',
'url' => '/',
'order' => 0,
'children' => [],
],
[
'label' => 'Services',
'url' => '/services',
'order' => 1,
'children' => [
['label' => 'Web Development', 'url' => '/services/web'],
['label' => 'Hosting', 'url' => '/services/hosting'],
],
],
],
]);# Run all tests
php artisan test
# Run specific test file
php artisan test packages/netserva-cms/tests/Unit/Models/PageTest.php
# Run with coverage
php artisan test --coverage- Model Tests: 40 tests covering all models
- Controller Tests: 25 tests for PageController & PostController
- Resource Tests: 30+ tests for Filament resources
- Total: 95+ comprehensive tests
use NetServa\Cms\Models\Page;
// Create a single page
$page = Page::factory()->create();
// Create 10 published pages
$pages = Page::factory()->count(10)->published()->create();
// Create a homepage
$homepage = Page::factory()->homepage()->create();
// Create nested pages
$parent = Page::factory()->create();
$child = Page::factory()->create(['parent_id' => $parent->id]);Published to config/netserva-cms.php:
return [
'frontend' => [
'enabled' => true,
],
'blog' => [
'route_prefix' => 'blog',
'posts_per_page' => 12,
],
'seo' => [
'site_name' => env('APP_NAME', 'NetServa CMS'),
'site_description' => 'Professional CMS built on Laravel',
],
'media' => [
'disk' => 'public',
'max_file_size' => 10240, // KB
],
'templates' => [
'default' => 'Default Page',
'homepage' => 'Homepage',
'service' => 'Service Page',
'pricing' => 'Pricing Page',
'blank' => 'Blank Page',
],
];// Homepage
GET / // PageController@home
// Pages
GET /{slug} // PageController@show
GET /{parentSlug}/{slug} // PageController@showNested
// Blog
GET /blog // PostController@index
GET /blog/{slug} // PostController@show
GET /blog/category/{slug} // PostController@category
GET /blog/tag/{slug} // PostController@tagAll admin routes are handled by Filament at /admin:
/admin/pages- Page management/admin/posts- Post management/admin/categories- Category management/admin/tags- Tag management/admin/menus- Menu builder
The netserva-cms package is designed to work in two distinct deployment modes:
When installed as part of the NetServa 3.0 platform:
Purpose: Provides professional frontend pages for NetServa installations
Routes:
/ β CMS homepage (NetServa.org branding)
/blog β Blog posts about NetServa updates
/about β About NetServa platform
/features β NetServa features page
/admin β Filament admin (all NetServa plugins)
/admin/pages β CMS page management
/admin/vnodes β Server management (other plugins)
Default Content:
- Homepage: NetServa platform introduction
- About page: Platform explanation
- Features page: Capability overview
- Sample blog post: "Welcome to NetServa 3.0"
Benefits:
- β Professional landing page for NetServa installations
- β Explains platform capabilities to visitors
- β Integrated with other NetServa admin panels
- β Gets constant updates via NS 3.0 development
When installed in a fresh Laravel 12 project:
Purpose: Power standalone websites (client sites, marketing sites, etc.)
Routes:
/ β Client homepage
/blog β Client blog
/{slug} β Client pages
/admin β CMS admin panel only
Client Content Examples:
- SpiderWeb website (spiderweb.com.au) β separate GitHub repo
- Other client marketing sites
- Personal blogs or portfolios
Installation:
# Fresh Laravel 12 project
composer create-project laravel/laravel my-client-site
cd my-client-site
# Install CMS
composer require netserva/cms
# Configure & migrate
php artisan vendor:publish --provider="NetServa\Cms\NetServaCmsServiceProvider"
php artisan migrate
# Seed with default content OR import client content
php artisan db:seed --class="NetServa\Cms\Database\Seeders\NetServaCmsSeeder"Benefits:
- β Zero NetServa dependencies
- β Standalone CMS capabilities
- β Benefits from NS 3.0 CMS development
- β Can be customized per client
Default Content (Included in Repository):
- Professional NetServa.org branding
- General server management messaging
- Suitable for any NetServa installation
Client Content (NOT in Repository):
- SpiderWeb website content β
spiderweb-websiterepo - Other client sites β separate repos/projects
- Imported via seeders or manual entry
Why This Separation Matters:
- Repository Cleanliness - No client-specific data in main repo
- Privacy - Client content stays private to client
- Reusability - Same CMS package powers unlimited sites
- Updates - CMS improvements benefit all deployments
Current State: WordPress website at spiderweb.com.au
Future Workflow:
# 1. Create separate project
git clone <spiderweb-website-repo>
cd spiderweb-website
# 2. Fresh Laravel + CMS
composer create-project laravel/laravel .
composer require netserva/cms
# 3. Import WordPress content
php artisan cms:import:wordpress /path/to/wordpress-export.xml
# 4. Deploy separately
# (SpiderWeb runs independently of NetServa 3.0)Result:
- SpiderWeb gets modern Laravel/Filament CMS
- Benefits from NetServa CMS improvements
- Completely separate GitHub repo
- No NetServa platform dependency
With CMS Installed:
- CMS owns root
/route - Provides homepage, pages, blog routes
- Fallback to Laravel welcome disabled
Without CMS:
- Root
/shows Laravel welcome page - Only
/adminpanel available - Clean backend-only installation
Environment Configuration:
# Enable/disable CMS frontend
CMS_FRONTEND_ENABLED=true
# Customize route prefixes
CMS_BLOG_PREFIX=blog
CMS_PORTFOLIO_PREFIX=portfolio
# Admin panel path (security)
NS_ADMIN_PREFIX=admin// β
Implement Plugin directly
class NetServaCmsPlugin implements Plugin { }
// β
Use own models only
namespace NetServa\Cms\Models;
// β
Keep composer.json clean
"require": {
"laravel/framework": "^12.0",
"filament/filament": "^4.0"
}// β Don't extend BaseFilamentPlugin
class NetServaCmsPlugin extends BaseFilamentPlugin { }
// β Don't use NetServa Core models
use NetServa\Core\Models\VHost;
// β Don't add NetServa dependencies
"require": { "netserva/core": "*" }Verify zero NetServa dependencies:
# Should return nothing
grep -r "NetServa\\Core" packages/netserva-cms/src/
# Should return nothing
grep -r "use NetServa" packages/netserva-cms/src/ | grep -v "NetServa\\Cms"
# Should show only Laravel/Filament/Spatie packages
cat packages/netserva-cms/composer.json | jq '.require'packages/netserva-cms/
βββ composer.json # Zero NS dependencies β
βββ config/
β βββ netserva-cms.php # Published configuration
βββ database/
β βββ factories/ # Model factories
β β βββ PageFactory.php
β β βββ PostFactory.php
β β βββ CategoryFactory.php
β β βββ TagFactory.php
β β βββ MenuFactory.php
β βββ migrations/ # cms_* prefixed tables
β βββ 2024_01_01_000001_create_cms_pages_table.php
β βββ 2024_01_01_000002_create_cms_categories_table.php
β βββ 2024_01_01_000003_create_cms_tags_table.php
β βββ 2024_01_01_000004_create_cms_posts_table.php
β βββ 2024_01_01_000005_create_cms_post_tag_table.php
β βββ 2024_01_01_000006_create_cms_menus_table.php
β βββ 2024_01_01_000007_create_media_table.php
βββ resources/views/
β βββ layouts/
β β βββ app.blade.php
β βββ pages/templates/
β β βββ default.blade.php
β β βββ homepage.blade.php
β β βββ service.blade.php
β β βββ pricing.blade.php
β β βββ blank.blade.php
β βββ posts/
β βββ index.blade.php
β βββ show.blade.php
β βββ category.blade.php
β βββ tag.blade.php
βββ routes/
β βββ web.php
βββ src/
β βββ Filament/Resources/
β β βββ PageResource.php # 3 pages (List, Create, Edit)
β β βββ PostResource.php # 3 pages
β β βββ CategoryResource.php # 3 pages
β β βββ TagResource.php # 3 pages
β β βββ MenuResource.php # 3 pages
β βββ Http/Controllers/
β β βββ PageController.php
β β βββ PostController.php
β βββ Models/
β β βββ Page.php # NO NS relationships β
β β βββ Post.php # 100% standalone β
β β βββ Category.php
β β βββ Tag.php
β β βββ Menu.php
β βββ NetServaCmsPlugin.php # Implements Plugin β
β βββ NetServaCmsServiceProvider.php
βββ tests/
β βββ Feature/
β β βββ Controllers/
β β β βββ PageControllerTest.php
β β β βββ PostControllerTest.php
β β βββ Filament/
β β βββ PageResourceTest.php
β β βββ PostResourceTest.php
β β βββ MenuResourceTest.php
β βββ Unit/Models/
β βββ PageTest.php
β βββ PostTest.php
β βββ CategoryTest.php
β βββ TagTest.php
β βββ MenuTest.php
βββ DEVELOPMENT_STATUS.md
βββ README.md
- β Package foundation (composer.json, service provider, plugin)
- β
Database migrations (7 tables with
cms_prefix) - β Models (5 models, 100% standalone)
- β Filament resources (5 resources, 17 pages)
- β Frontend controllers (PageController, PostController)
- β Blade templates (1 layout, 9 templates)
- β Model factories (5 factories)
- β Comprehensive tests (95+ tests)
- β Documentation (README, DEVELOPMENT_STATUS)
- β³ Run migrations (pending artisan fix)
- β³ SpiderWeb content migration
Status: ~85% Complete
MIT
NetServa Team
This is a NetServa internal package. For issues or feature requests, please contact the NetServa development team.
Built with β€οΈ using Laravel 12 + Filament 4