binetvn/laravel-pages
Simple pages manager for Laravel applications. Provides basic structure to create and manage site pages, intended for quick setup of static or CMS-like content within a Laravel project.
Installation:
composer require binetvn/laravel-pages
php artisan vendor:publish --provider="Binetvn\Pages\PagesServiceProvider" --tag="pages-config"
php artisan migrate
config/pages.php.First Use Case:
use Binetvn\Pages\Models\Page;
$page = Page::create([
'title' => 'About Us',
'slug' => 'about',
'content' => '<h1>Welcome to our page!</h1>',
'is_published' => true,
]);
@foreach(\Binetvn\Pages\Models\Page::published()->get() as $page)
<h2><a href="{{ route('pages.show', $page->slug) }}">{{ $page->title }}</a></h2>
{!! $page->content !!}
@endforeach
Routing:
routes/web.php:
Route::get('/pages/{slug}', [\Binetvn\Pages\Http\Controllers\PageController::class, 'show'])->name('pages.show');
CRUD Operations:
Page model for all CRUD operations (e.g., Page::find(1)->update(['content' => '...'])).Page::with('author')->get()).Content Management:
content field. Use a package like spatie/laravel-medialibrary for file attachments if needed.meta_description field to the pages table and update the model:
$page->meta_description = 'SEO-friendly description';
$page->save();
Dynamic Page Rendering:
// In a controller
public function show(Page $page)
{
return view('pages.show', compact('page'));
}
PageController to customize behavior (e.g., caching, redirects).Pagination:
$pages = Page::published()->paginate(10);
Localization:
locale and content fields to a pivot table (e.g., page_translations) if supporting multilingual content. Override the Page model to handle translations.Middleware:
Route::get('/pages/{slug}', [PageController::class, 'show'])
->middleware('pages.published')
->name('pages.show');
namespace App\Http\Middleware;
use Closure;
use Binetvn\Pages\Models\Page;
class CheckPageExists
{
public function handle($request, Closure $next, $slug)
{
if (!Page::where('slug', $slug)->exists()) {
abort(404);
}
return $next($request);
}
}
Events:
// In EventServiceProvider
protected $listen = [
'Binetvn\Pages\Events\PageCreated' => [
'App\Listeners\NotifyPageCreated',
],
];
API Endpoints:
Route::apiResource('pages', \Binetvn\Pages\Http\Controllers\Api\PageController::class)->only(['index', 'show']);
Admin Panel:
Page resource:
// For Laravel Nova
Nova::resources([
\Binetvn\Pages\Nova\Page::class,
]);
Slug Conflicts:
Page model to auto-generate slugs from titles:
protected static function boot()
{
parent::boot();
static::creating(function ($page) {
$page->slug = Str::slug($page->title);
});
}
Content Security:
Purifier or HTML Purifier:
$cleanContent = Purifier::clean($page->content);
Performance:
with() selectively:
// Bad: Page::with('author', 'tags')->get();
// Good: Page::with('author')->get();
Migration Conflicts:
pages table already exists, manually adjust the migration or use:
php artisan migrate --path=/vendor/binetvn/laravel-pages/database/migrations
Caching:
$page = Cache::remember("page:{$slug}", now()->addHours(1), function () use ($slug) {
return Page::where('slug', $slug)->firstOrFail();
});
Query Logs:
DB::enableQueryLog();
Page::published()->get();
dd(DB::getQueryLog());
Model Events:
Page::created(function ($page) {
\Log::info('Page created:', ['id' => $page->id]);
});
Route Debugging:
php artisan route:list to verify routes are registered correctly.Custom Fields:
pages table with custom fields (e.g., template, layout). Update the model:
protected $fillable = ['title', 'slug', 'content', 'is_published', 'template'];
Page Templates:
template field and using Blade includes:
@if($page->template === 'hero')
@include('pages.templates.hero', ['page' => $page])
@else
{!! $page->content !!}
@endif
Soft Deletes:
use Illuminate\Database\Eloquent\SoftDeletes;
class Page extends Model
{
use SoftDeletes;
protected $dates = ['deleted_at'];
}
Policy Integration:
use Binetvn\Pages\Models\Page;
use App\Models\User;
class PagePolicy
{
public function view(User $user, Page $page)
{
return $page->is_published || $user->isAdmin();
}
}
AuthServiceProvider.Testing:
public function test_page_creation()
{
$response = $this->post('/admin/pages', [
'title' => 'Test Page',
'slug' => 'test',
'content' => '<p>Hello</p>',
]);
$response->assertRedirect();
$this->assertDatabaseHas('pages', ['slug' => 'test']);
}
How can I help you explore Laravel packages today?