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

Minimal Setup

  1. Installation:

    composer require oddvalue/laravel-drafts
    php artisan vendor:publish --tag="drafts-config"
    
  2. Model Integration: Add HasDrafts trait to your model:

    use Oddvalue\LaravelDrafts\Concerns\HasDrafts;
    
    class Post extends Model
    {
        use HasDrafts;
    }
    
  3. Database Migration: Add draft columns to your table:

    Schema::table('posts', function (Blueprint $table) {
        $table->drafts();
    });
    

First Use Case

Create a draft post:

$post = Post::createDraft(['title' => 'Draft Post']);

Publish it:

$post->publish();

Implementation Patterns

Workflows

Content Workflow

  1. Draft Creation:

    // Create a draft
    $post = Post::createDraft(['title' => 'Draft Title']);
    
    // Or update existing as draft
    $post->updateAsDraft(['title' => 'Updated Draft']);
    
  2. Previewing:

    // Enable preview mode (shows current draft)
    LaravelDrafts::previewMode(true);
    $posts = Post::all(); // Shows drafts instead of published
    
    // Disable preview mode
    LaravelDrafts::previewMode(false);
    
  3. Publishing:

    $post->publish(); // Publishes the current draft
    

Admin Panel Integration

  • Use Post::current() to fetch the latest draft for editing.
  • Use Post::published() to fetch live content for the frontend.

Relation Handling

Define draftable relations in your model:

protected $draftableRelations = ['tags', 'author'];

The package automatically syncs relations when publishing.


Integration Tips

Middleware for Draft Access

Restrict draft access to specific routes:

Route::withDrafts(function () {
    Route::get('/admin/posts', [PostController::class, 'edit']);
});

Customizing Column Names

Override defaults via model constants:

class Post extends Model
{
    use HasDrafts;

    public const IS_CURRENT = 'is_editing';
}

Bulk Operations

Use scopes to filter drafts:

// Get all drafts
$drafts = Post::onlyDrafts()->get();

// Get published posts
$published = Post::published()->get();

Gotchas and Tips

Pitfalls

  1. Relation Sync Issues:

    • Ensure $draftableRelations includes all relations you want synced.
    • Complex relations (e.g., polymorphic) may require manual handling.
  2. Preview Mode Scope:

    • Forgetting to disable previewMode() can cause frontend to show drafts unintentionally.
  3. Revision Limits:

    • Default keeps 10 revisions. Adjust in config/drafts.php:
      'revisions' => ['keep' => 20],
      

Debugging

  1. Check Draft Status:

    $post->isDraft(); // Returns true if current revision is a draft
    $post->isPublished(); // Returns true if published
    
  2. Inspect Revisions:

    $post->revisions()->get(); // List all revisions
    
  3. Disable Global Scope Temporarily:

    Post::withoutGlobalScope(HasDrafts::class)->get(); // Bypasses published-only scope
    

Extension Points

  1. Custom Revision Logic: Override shouldCreateRevision() in your model:

    public function shouldCreateRevision(): bool
    {
        return !in_array($this->status, ['archived']);
    }
    
  2. Event Hooks: Listen for draft/publish events:

    Post::created(function ($post) {
        if ($post->isDraft()) {
            event(new DraftCreated($post));
        }
    });
    
  3. Soft Deletes: Revisions respect soft deletes. Use forceDelete() to bypass:

    $post->forceDelete(); // Deletes revisions permanently
    
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.
codraw/entity-migrator
codraw/doctrine-extra
codraw/aws-tool-kit
codraw/validator
codraw/workflow
codraw/open-api
codraw/cron-job
codraw/process
codraw/log
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony