dominservice / laravel-cms
Laravel CMS Backend
Installs: 150
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 1
Forks: 0
Open Issues: 0
pkg:composer/dominservice/laravel-cms
Requires
- php: >=8.1
- ext-gd: *
- astrotomic/laravel-translatable: ^11.13
- dominservice/laravel-config: ^2.2
- dominservice/laravel-media-kit: ^1.0
- kalnoy/nestedset: ^6.0
- laravel/framework: ^9|^10|^11|^12
- livewire/livewire: ^3.0
Requires (Dev)
- orchestra/testbench: ^7.0|^8.0|^9.0
- dev-main
- 4.1.10
- 4.1.9
- 4.1.8
- 4.1.7
- 4.1.6
- 4.1.5
- 4.1.4
- 4.1.3
- 4.1.2
- 4.1.1
- 4.1.0
- 4.0.0
- 3.7.3
- 3.7.2
- 3.7.1
- 3.7.0
- 3.6.0
- 3.5.3
- 3.5.2
- 3.5.1
- 3.5.0
- 3.4.5
- 3.4.4
- 3.4.3
- 3.4.2
- 3.4.1
- 3.4.0
- 3.3.12
- 3.3.11
- 3.3.10
- 3.3.9
- 3.3.8
- 3.3.7
- 3.3.6
- 3.3.5
- 3.3.4
- 3.3.3
- 3.3.2
- 3.3.1
- 3.3.0
- 3.2.2
- 3.2.1
- 3.2.0
- 3.1.1
- 3.1.0
- 3.0.0
- 2.5.2
- 2.5.1
- 2.5.0
- 2.4.2
- 2.4.1
- 2.4.0
- 2.3.0
- 2.2.5
- 2.2.4
- 2.2.3
- 2.2.2
- 2.2.1
- 2.2.0
- 2.1.1
- 2.1.0
- 2.0.1
- 2.0.0
- 1.1.1
- 1.1.0
- 1.0.5
- 1.0.4
- 1.0.3
- 1.0.2
- 1.0.1
- 1.0.0
- dev-detached
This package is auto-updated.
Last update: 2026-01-14 23:38:49 UTC
README
dominservice/laravel-cms
Laravel CMS for multilingual content, categories and media (images & video) — integrated with dominservice/laravel-media-kit.
Installation • Configuration • Upload • Read • Migration v2/v3 → v4 • Tests • Support
Last updated: 2025-10-17 20:38 UTC
Table of Contents
- Highlights
- Requirements
- Installation
- Upgrade from v2/v3 to v4 (data migration)
- Configuration
- Admin Panel (content & categories)
- Routes & localized slugs
- Views and translations
- Models & relations
- Media: write (backward-compatible & recommended)
- Media: read (DynamicAvatarAccessor)
- Blade components / Variant URLs
- End‑to‑end examples
- Tests
- Support
- License
- Changelog (v4 summary)
Highlights
- Multilingual contents and categories (Astrotomic/Translatable).
- Nested categories tree (Nested Set).
- Media (images & video) with
kindmapped to MediaKit collection. - DynamicAvatarAccessor — dynamic names like
avatar_sm,video_hd,poster_display; if missing ⇒ returnsnull. - Content↔Content links with visibility windows and meta.
- Backward-compatible upload methods (
@deprecated) + new, MediaKit‑based APIs.
Requirements
- PHP 8.2+, Laravel 9–12
- dominservice/laravel-media-kit installed & configured
- livewire/livewire v3 (admin panel UI)
Installation
composer require dominservice/laravel-cms php artisan vendor:publish --provider="Dominservice\LaravelCms\ServiceProvider" php artisan vendor:publish --provider="Dominservice\MediaKit\MediaKitServiceProvider" php artisan migrate
In v4, all media reads are served via MediaKit. Legacy storage is migrated once (see below).
Updating the package
When you update the package in an existing project, merge new configuration keys and UI assets:
php artisan vendor:publish --provider="Dominservice\LaravelCms\ServiceProvider" --tag=config php artisan vendor:publish --provider="Dominservice\LaravelCms\ServiceProvider" --tag=views php artisan vendor:publish --provider="Dominservice\LaravelCms\ServiceProvider" --tag=lang php artisan config:clear
- Merge new keys from
config/cms.phpinstead of overwriting your existing settings. - Publish views only if you want to override the CMS admin UI.
- Publish language files if you want file-based route slug translations (see Routes & localized slugs).
Upgrade from v2/v3 to v4 (data migration)
php artisan cms:media:migrate-v4
# dry run:
php artisan cms:media:migrate-v4 --dry-run
- Detects legacy tables from
config('cms.tables.*')(e.g.cms_content_files,cms_category_files,cms_content_videos). - Copies records into MediaKit (
media_assets) mapping kind → collection; video renditions stored in meta. - On success, drops legacy tables. On a clean v4 install: no action.
Configuration
CMS: config/cms.php
MediaKit: config/media-kit.php
Tables
categories,category_translationscontents,content_translationscontent_categories- legacy:
content_files,category_files,content_video(migration only)
Disks
cms.php → disks.* are historical logical disks; real disk/URL is controlled by MediaKit (media-kit.php).
Profiles & sizes (files.*)
Defines logical kinds, default display and list of sizes. In v4 it’s a logical contract; variants & URLs are produced by MediaKit.
Kind ↔ config mapping (file_config_key_map)
Aliases one config key to another for kind resolution.
Logical name mapping (file_kind_map)
Maps logical names consumed by accessors (e.g. avatar, video_avatar, video_poster) to concrete kinds.
Admin Panel (content & categories)
The package ships with a configurable CMS admin panel for managing content, blocks, and categories.
- Admin routes render Livewire v3 components by default.
- Enable routes and set middleware in
cms.admin.*(default:web,auth). - Define sections in
cms.admin.content.sectionsandcms.admin.category.sections. - Required fields follow migrations: content requires
type,name,description; category requirestype,name. - Choose UI preset in
cms.admin.ui.theme(bootstraportailwind) and override classes incms.admin.ui.classes. - Control layout integration via
cms.admin.layout.mode:package: use built-in layout (cms::layouts.bootstraporcms::layouts.tailwind).extends: render inside your own Blade layout (setcms.admin.layout.view+section).component: render inside<x-dynamic-component>(setcms.admin.layout.component).
- If you use
extends/component, include@livewireStylesin<head>and@livewireScriptsbefore</body>in your layout.
Routes & localized slugs
Routes are optional and fully configured in cms.routes.*.
enabled: register public CMS routes.use_locales+use_locale_prefix: create per-locale prefixes (/pl/...,/en/...) or keep a single set.locale_middleware: defaults tolanguagefromdominservice/data_locale_parser(optional).translation_group: used whentranslated_slugsis on (defaults toroutes).
Page routes are configured in cms.routes.pages:
'routes' => [ 'enabled' => true, 'pages' => [ 'home' => [ 'slug' => '/', 'translated' => true, 'content_key' => 'cms.default_pages.home.page_uuid', 'view' => 'cms::frontend.page', ], 'contact' => [ 'slug' => ['pl' => 'kontakt', 'en' => 'contact'], 'content_key' => 'cms.default_pages.contact.page_uuid', ], ], ],
Category routes are configured in cms.routes.category:
'category' => [ 'enabled' => true, 'prefix' => ['pl' => 'kategoria', 'en' => 'category'], 'route_name' => 'category.show', 'view' => 'cms::frontend.category', ],
If you want to use file-based slug translations, publish resources/lang/*/routes.php and keep
cms.routes.translation_group = 'routes'. If you prefer package translations without publishing,
set cms.routes.translation_group = 'cms::routes' (note: data_locale_parser helpers use routes.*).
Views and translations
Publish package UI and route translations if you want to override them:
php artisan vendor:publish --provider="Dominservice\LaravelCms\ServiceProvider" --tag=views php artisan vendor:publish --provider="Dominservice\LaravelCms\ServiceProvider" --tag=lang
Models & relations
Models\Content,Models\Category(translations, meta).- MediaKit relation: morph to
MediaAsset(model_type,model_id,collection).
Media: write (backward-compatible & recommended)
Backward‑compatible (deprecated in CMS)
use Dominservice\LaravelCms\Helpers\Media; // images Media::uploadModelImage($content, $uploadedFile, 'avatar', null, null, true); Media::uploadModelResponsiveImages($content, $uploadedFile, 'avatar'); Media::uploadModelImageWithDefaults($content, $uploadedFile, 'avatar'); // video renditions Media::uploadModelVideos($content, [ 'hd' => $fileHD, 'sd' => $fileSD ], 'video_avatar');
Recommended (MediaKit)
use Dominservice\MediaKit\Traits\HasMedia; class Content extends Model { use HasMedia; } // in your service/controller $content->addMedia($uploadedFile, 'avatar'); // original + variants by MediaKit
Media: read (DynamicAvatarAccessor)
class Content extends Model { use \Dominservice\LaravelCms\Traits\DynamicAvatarAccessor; } $content->avatar; // 'display' variant of 'avatar' $content->avatar_sm; // 'sm' variant $content->video_hd; // video avatar 'hd' $content->poster_display; // poster 'display'
Missing file/variant ⇒ returns null (no exceptions).
Blade components / Variant URLs
MediaKit exposes route:
/media/{{asset-uuid}}/{{variant}}/{{slug?}}
Accessors already return such URLs — plug them directly into <img> / <video>. Blade components from MediaKit can be used alongside existing views.
End‑to‑end examples
1) Upload form + render image
// Controller \Dominservice\LaravelCms\Helpers\Media::uploadModelImage($content, $request->file('avatar'), 'avatar'); // Blade <img src="{{ $content->avatar ?? asset('img/placeholder.png') }}" alt="avatar">
2) Video with renditions + poster
// Controller \Dominservice\LaravelCms\Helpers\Media::uploadModelVideos($content, [ 'hd' => $request->file('video_hd'), 'sd' => $request->file('video_sd'), ], 'video_avatar'); // Blade <video controls poster="{{ $content->poster_display }}"> <source src="{{ $content->video_hd }}" type="video/mp4"> <source src="{{ $content->video_sd }}" type="video/mp4"> </video>
3) Gallery (custom kind)
@foreach(($content->gallery_md_list ?? []) as $url) <img src="{{ $url }}" alt="gallery item"> @endforeach
Tests
Edge‑case coverage recommendations:
- missing files/kinds ⇒ returns
null, no exceptions, - dynamic names (
avatar_sm,video_hd,poster_display, custom kinds), - migration v2/v3 → v4 on empty DB, with data and in
--dry-runmode, - deprecated helper methods delegate to MediaKit,
- integration tests with Laravel app boot (artisan, migrations, storage fake).
Support
Support this project (Ko‑fi)
If this package saves you time, consider buying me a coffee: https://ko-fi.com/dominservice — thank you!
License
MIT — see LICENSE.
Changelog (v4 summary)
- Full read/write integration with MediaKit.
DynamicAvatarAccessor: dynamic names,nullon missing.- v2/v3 → v4 migration (legacy tables dropped afterwards).
- Deprecated upload methods preserved for smooth transition; new code should use MediaKit APIs.
