Installation:
composer require appdezign/lara-cms
php artisan vendor:publish --provider="Appdezign\LaraCms\LaraCmsServiceProvider"
php artisan migrate
config/lara-cms.php, database/migrations/, and public/vendor/lara-cms/.First Use Case:
Article) via the admin panel or manually:
use Appdezign\LaraCms\Models\ContentType;
ContentType::create(['name' => 'article', 'slug' => 'articles']);
$contentType->fields()->create(['name' => 'title', 'type' => 'text']);
$contentType->fields()->create(['name' => 'body', 'type' => 'textarea']);
use Appdezign\LaraCms\Models\Content;
Content::create([
'content_type_id' => $contentType->id,
'data' => json_encode(['title' => 'Hello World', 'body' => 'Lara CMS is awesome!']),
]);
Display Content:
@foreach(\Appdezign\LaraCms\Models\Content::where('content_type_id', $articleTypeId)->get() as $content)
<h1>{{ $content->data->title }}</h1>
<p>{{ $content->data->body }}</p>
@endforeach
route('api.cms.content.index', ['type' => 'articles']);
Admin Panel:
/admin/cms (default route) to manage content types, fields, and entries.Appdezign\LaraCms\Http\Controllers\AdminController.config/lara-cms.php for route prefixes, middleware, and default settings.database/migrations/ for schema changes (e.g., content_types, contents, fields).appdezign/lara-cms/src/Models/ for Eloquent relationships and business logic.routes/web.php and routes/api.php for CMS-specific endpoints (e.g., /api/cms/content).// Define a 'Product' content type
$productType = ContentType::create(['name' => 'Product', 'slug' => 'products']);
$productType->fields()->createMany([
['name' => 'name', 'type' => 'text'],
['name' => 'price', 'type' => 'number'],
['name' => 'description', 'type' => 'textarea'],
['name' => 'image', 'type' => 'media'], // Assuming media field type exists
]);
// routes/api.php
Route::get('/products', [ContentController::class, 'index'])->name('api.cms.products.index');
// app/Http/Controllers/ContentController.php
public function index()
{
return Content::with('contentType.fields')
->where('content_type_id', $productTypeId)
->get();
}
// Extend the 'text' field type
namespace App\Extensions\LaraCms\Fields;
use Appdezign\LaraCms\Fields\TextField;
class CustomTextField extends TextField
{
public function getRules()
{
return ['required', 'max:255', 'unique:contents,data->title'];
}
}
Register the extension in config/lara-cms.php:
'field_extensions' => [
'text' => \App\Extensions\LaraCms\Fields\CustomTextField::class,
],
// app/Observers/ContentObserver.php
use Appdezign\LaraCms\Models\Content;
use Illuminate\Support\Facades\Log;
Content::observe(function ($content) {
if ($content->wasRecentlyCreated) {
Log::info("New content created: {$content->id}");
// Trigger email, Slack notification, etc.
}
});
Register the observer in AppServiceProvider:
Content::observe(\App\Observers\ContentObserver::class);
tenant() helper or middleware.// Middleware to scope content by tenant
public function handle($request, Closure $next)
{
$tenant = auth()->user()->tenant;
Content::addGlobalScope('tenant', function ($query) use ($tenant) {
$query->where('tenant_id', $tenant->id);
});
return $next($request);
}
/admin/cms/content/create).POST /api/cms/content).Content::create([
'content_type_id' => $typeId,
'data' => json_encode($data),
'user_id' => auth()->id(),
]);
$content->update(['status' => 'published']);
$content = Content::find($id);
$content->update([
'data' => json_encode(array_merge($content->data, ['title' => 'Updated Title'])),
]);
$content->delete(); // Sets 'deleted_at' column
$content->forceDelete();
$content->media()->attach($mediaId);
@foreach($content->media as $media)
<img src="{{ $media->url }}" alt="{{ $media->name }}">
@endforeach
Content, ContentType, and Field as Eloquent models.Content::addGlobalScope('published', function ($query) {
$query->where('status', 'published');
});
use Appdezign\LaraCms\Models\Content;
use Illuminate\Auth\Access\HandlesAuthorization;
class ContentPolicy
{
use HandlesAuthorization;
public function viewAny($user)
{
return $user->can('view-cms-content');
}
}
@include for reusable CMS templates:
@include('cms::partials.content', ['content' => $article])
public $content;
public function mount($id)
{
$this->content = Content::findOrFail($id);
}
How can I help you explore Laravel packages today?