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 Content Type:
Define a custom content type (e.g., Article) via a migration or seeder:
// database/migrations/[timestamp]_create_articles_table.php
Schema::create('articles', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('content');
$table->timestamps();
// Add Lara CMS-specific fields if needed (e.g., slug, status)
});
Register the model in app/Providers/AppServiceProvider.php:
use Appdezign\LaraCms\Models\Content;
class Article extends Content { /* ... */ }
Basic CRUD via Admin Panel:
/admin (default route; check config for customization).Article entry through the UI or via Tinker:
php artisan tinker
>>> $article = new App\Models\Article;
>>> $article->title = "Hello Lara CMS";
>>> $article->content = "Welcome to our CMS!";
>>> $article->save();
Display Content in Blade:
@foreach(\App\Models\Article::published()->get() as $article)
<h2>{{ $article->title }}</h2>
<p>{{ $article->content }}</p>
@endforeach
published() or other query scopes (if provided by the package).API Access (Optional):
Enable API routes in routes/api.php:
Route::resource('articles', \App\Http\Controllers\ArticleController::class);
ArticleController to return JSON responses.Content Model:
namespace App\Models;
use Appdezign\LaraCms\Models\Content;
class Product extends Content
{
protected $fillable = ['name', 'price', 'description'];
protected $casts = ['price' => 'decimal:2'];
}
morphTo or morphMany for polymorphic relationships:
public function images()
{
return $this->morphMany(Media::class, 'model');
}
Override Default Views: Publish and extend the admin panel views:
php artisan vendor:publish --tag=lara-cms-views
Copy resources/views/vendor/lara-cms/admin/ to your project and modify templates (e.g., partials/form.blade.php).
Add Custom Fields:
Use Laravel Collective’s Form and Html helpers or custom Blade components:
{!! Form::text('custom_field', null, ['class' => 'form-control']) !!}
Global Scopes:
Add reusable query constraints in App\Models\Content.php:
protected static function boot()
{
static::addGlobalScope(new PublishedScope);
}
class PublishedScope implements Scope
{
public function apply(Builder $builder, Model $model)
{
$builder->where('status', 'published');
}
}
API-First Filtering:
Use Laravel’s api-resources or spatie/laravel-query-builder for dynamic filtering:
use Spatie\QueryBuilder\QueryBuilder;
$articles = QueryBuilder::for(Article::class)
->allowedFilters('title', 'category')
->allowedSorts('created_at')
->get();
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;
class Article extends Content implements HasMedia
{
use InteractsWithMedia;
public function registerMediaCollections(): void
{
$this->addMediaCollection('images');
}
}
app/Providers/LaraCmsServiceProvider.php:
public function boot()
{
\Appdezign\LaraCms\Services\MediaService::macro('customUpload', function ($file) {
// Custom logic (e.g., S3, local storage)
});
}
Events and Listeners: Listen for content changes:
// app/Listeners/LogContentChanges.php
public function handle(ContentUpdated $event)
{
Log::info("Content updated: {$event->content->title}");
}
Register in EventServiceProvider:
protected $listen = [
'Appdezign\LaraCms\Events\ContentUpdated' => [
'App\Listeners\LogContentChanges',
],
];
Queued Jobs: Process content asynchronously (e.g., generate thumbnails):
$article->save();
ProcessArticleMedia::dispatch($article);
class ProcessArticleMedia implements ShouldQueue
{
public function handle()
{
// Generate thumbnails, etc.
}
}
stancl/tenancy or custom logic:
class Article extends Content
{
public function getRouteKeyName()
{
return 'slug';
}
public function getRouteKey()
{
return "{$this->tenant->domain}/{$this->slug}";
}
}
Livewire/Alpine: Use Lara CMS data in Livewire components:
public function getArticlesProperty()
{
return Article::latest()->take(10)->get();
}
<div x-data="{ articles: @entangle('articles') }">
@foreach($articles as $article)
<div>{{ $article->title }}</div>
@endforeach
</div>
Inertia.js: Fetch content in Vue/React:
// Vue example
const { data: articles } = await axios.get('/api/articles');
Laravel Nova: Extend Nova to manage Lara CMS content:
Nova::resources([
new \App\Nova\Article,
]);
React/Vue API Consumption: Proxy API routes through Laravel’s Sanctum or Passport:
// React example
const fetchArticles = async () => {
const response = await axios.get('/api/articles', {
headers: { Authorization: `Bearer ${localStorage.getItem('token')}` }
});
return response.data;
};
Static Site Generation (SSG):
Use Laravel’s spatie/laravel-feed or spatie/laravel-sitemap to generate sitemaps from Lara CMS content.
Caching: Cache frequent queries:
$articles = Cache::remember('featured-articles', now()->addHours(1), function () {
return Article::featured()->get();
});
Database Optimization: Add indexes to frequently queried fields:
Schema::table('articles', function (Blueprint $table) {
$table->index('slug');
$table->index('status');
});
Asset Optimization: Use Laravel Mix/Vite to bundle Lara CMS’s JS/CSS:
// mix.js
mix.js('resources/js/lara-cms.js', 'public/js')
.postCss('resources/css/lara-cms.css', 'public/css', [
require('postcss-import'),
require('tailwindcss'),
]);
/admin route may not be documented. Check routes/web.php for registered routes after publishing.auth, verified) to routes. Override in app/Http/Kernel.php if needed:
protected $routeMiddleware = [
'lara-cms.auth' => \Appdezign\LaraCms\Http\Middleware\Authenticate
How can I help you explore Laravel packages today?