Skip to content
/ cms Public

NetServa CMS - Professional CMS with Filament 4 admin panel (Read-only split from monorepo)

Notifications You must be signed in to change notification settings

netserva/cms

Repository files navigation

NetServa CMS

Professional Laravel 12 + Filament 4 Content Management System

Laravel Filament PHP Pest

🎯 Design Philosophy: Standalone & Deployable Built to work both within NetServa 3.0 AND as a completely standalone Laravel package


✨ Features

Content Management

  • πŸ“„ 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 & SEO

  • πŸ–ΌοΈ 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

Admin Experience

  • πŸŽ›οΈ 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

Developer Experience

  • βœ… 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

πŸ“‹ Requirements

  • PHP: ^8.4
  • Laravel: ^12.0
  • Filament: ^4.0
  • Spatie Media Library: ^11.0
  • Spatie Sluggable: ^3.0

πŸš€ Quick Start

Installation

composer require netserva/cms

Publish Configuration

php artisan vendor:publish --provider="NetServa\Cms\NetServaCmsServiceProvider"

Run Migrations

php artisan migrate

Register Filament Plugin

In your Filament panel provider (app/Providers/Filament/AdminPanelProvider.php):

use NetServa\Cms\NetServaCmsPlugin;

public function panel(Panel $panel): Panel
{
    return $panel
        ->plugins([
            NetServaCmsPlugin::make(),
        ]);
}

Access Admin Panel

Visit /admin and start creating content!


πŸ“Š Database Schema

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

πŸ—οΈ Architecture

Models (100% Standalone)

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 items

Controllers

NetServa\Cms\Http\Controllers\
β”œβ”€β”€ PageController  // home(), show(), showNested()
└── PostController  // index(), show(), category(), tag()

Filament Resources

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 repeaters

Views

resources/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

🎨 Usage Examples

Creating Pages

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,
]);

Creating Blog Posts

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);

Building Menus

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'],
            ],
        ],
    ],
]);

πŸ§ͺ Testing

Running Tests

# 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

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

Using Factories

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]);

βš™οΈ Configuration

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',
    ],
];

🎯 Routes

Frontend Routes

// 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@tag

Admin Routes

All 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

πŸš€ Deployment Scenarios

Dual-Purpose Architecture

The netserva-cms package is designed to work in two distinct deployment modes:

1. Integrated Mode (Within NetServa 3.0)

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

2. Standalone Mode (Independent Laravel Project)

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

Content Separation Strategy

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-website repo
  • Other client sites β†’ separate repos/projects
  • Imported via seeders or manual entry

Why This Separation Matters:

  1. Repository Cleanliness - No client-specific data in main repo
  2. Privacy - Client content stays private to client
  3. Reusability - Same CMS package powers unlimited sites
  4. Updates - CMS improvements benefit all deployments

Migration Example: SpiderWeb

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

Routing Behavior

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 /admin panel 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

πŸ”’ Design Constraints

βœ… ALWAYS DO

// βœ… 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"
}

❌ NEVER DO

// ❌ 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": "*" }

πŸ” Verification

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'

πŸ“‚ Complete Directory Structure

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

πŸ“ˆ Progress

  • βœ… 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


πŸ“ License

MIT

πŸ‘₯ Authors

NetServa Team


🀝 Contributing

This is a NetServa internal package. For issues or feature requests, please contact the NetServa development team.


Built with ❀️ using Laravel 12 + Filament 4

About

NetServa CMS - Professional CMS with Filament 4 admin panel (Read-only split from monorepo)

Resources

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •