Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Drafts Laravel Package

oddvalue/laravel-drafts

Drop-in drafts and revisions for Laravel Eloquent models. Create, save, publish, and preview revisions with a simple API, middleware support, and minimal setup—ideal for CMS-style editing workflows without building a custom versioning system.

View on GitHub
Deep Wiki
Context7

Getting Started

Start by installing the package via Composer and publishing the config file to customize column names and revision limits. Then add the HasDrafts trait to any model requiring draft support. The package automatically adds required columns (is_current, is_published, published_at, uuid, etc.) via a migration helper — use $table->drafts() in your schema definition. For new models, drafts are optional: call createDraft(), saveAsDraft(), or explicitly set is_published => false. Published records are returned by default due to a global scope, but withDrafts() and current() scopes allow flexible retrieval.

Implementation Patterns

  • Admin UI Flow: Use current() scope to show the latest working version (draft or published), and expose is_published toggling to let authors preview or publish changes.
  • Preview Endpoints: Wrap admin preview routes with WithDraftsMiddleware or use Route::withDrafts() to temporarily bypass the published-only global scope.
  • Bulk Operations: Combine scopes like Post::current()->where('author_id', $id)->get() to manage author-specific drafts.
  • Relations Handling: Define $draftableRelations (or override getDraftableRelations()) on the model to auto-duplicate/sync HasOne, HasMany, BelongsToMany, and MorphToMany relations during publish.
  • Revision Auditing: Use $model->revisions() to walk through change history; leverage the keep config to auto-cleanup old revisions (default 10).
  • Performance Optimization: Use withoutRevision() when updating without generating new revisions (e.g., soft delete cleanup, system updates).

Gotchas and Tips

  • Global Scope Surprise: Eager loading or raw queries might bypass the published-only filter unexpectedly — always test with Post::withoutDrafts()->get() when debugging unexpected query results.
  • UUID Collisions: Although unlikely, if migrating from legacy systems, verify uuid uniqueness before enabling drafts — consider seeding UUIDs first.
  • Soft Deletes Interaction: Soft-deleted records retain revisions; restoring a model restores its revisions — be explicit in your delete logic if orphaning is desired.
  • Custom Column Names: If overriding constants like IS_PUBLISHED or PUBLISHER_MORPH_NAME, ensure the migration columns match exactly. Using $table->drafts() helps avoid mismatches.
  • Middleware Scope: WithDraftsMiddleware only affects the current request — don’t rely on it across jobs or queue workers; use LaravelDrafts::previewMode() manually there.
  • Relation Sync Gotcha: BelongsToMany relations are synced on publish, so any detachments on the draft won’t affect the published model until publish — consider pre-syncing or explicit detach logic if needed.
  • Laravel 12 Compatibility: Version 3.x drops support for older Laravel; ensure your environment matches — check the compatibility table before upgrading.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport