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

Blog Laravel Package

drewroberts/blog

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require drewroberts/blog
    php artisan vendor:publish --provider="DrewRoberts\Blog\BlogServiceProvider" --tag="config"
    
    • Verify the empty config file is published to config/blog.php.
  2. Database Migration: Run migrations to create tables for Pages, Posts, Series, and Topics:

    php artisan migrate
    
  3. First Use Case:

    • Create a Post:
      use DrewRoberts\Blog\Models\Post;
      
      $post = Post::create([
          'title' => 'My First Blog Post',
          'slug' => 'my-first-post',
          'content' => '<p>Hello, world!</p>',
          'status' => 'published', // or 'draft'
      ]);
      
    • Create a Page:
      use DrewRoberts\Blog\Models\Page;
      
      $page = Page::create([
          'title' => 'About Us',
          'slug' => 'about',
          'content' => '<p>About content here.</p>',
      ]);
      
  4. Accessing Content:

    • Retrieve all published posts:
      $posts = Post::published()->get();
      
    • Retrieve a post by slug:
      $post = Post::published()->where('slug', 'my-first-post')->first();
      

Implementation Patterns

Core Workflows

  1. Content Management:

    • Posts: Use for time-sensitive, indexed content (e.g., news, articles).
      • Supports status (published/draft) and published_at timestamps.
      • Example: Fetch recent posts with pagination:
        $recentPosts = Post::published()->latest()->paginate(10);
        
    • Pages: Use for static content (e.g., "About," "Contact").
      • No status field; always treated as published.
    • Series/Topics: Organize posts into hierarchical structures.
      • A Series can contain multiple Posts, and a Topic can group related Posts or Series.
  2. Authorization:

    • Policies are pre-configured via tipoff/authorization. Extend or override default roles/permissions in app/Policies or via config.
    • Example: Grant a role access to manage posts:
      use DrewRoberts\Blog\Models\Post;
      use Tipoff\Authorization\Contracts\Role;
      
      Role::find('editor')->givePermissionTo(Post::class, 'update');
      
  3. Nova Integration:

    • Nova resources are auto-registered for all models (Page, Post, Series, Topic).
    • Customize toolbars or fields by extending the resource classes in app/Nova/Resources.
  4. Routing:

    • The package provides basic routes for posts/pages (e.g., /posts/{slug}). Override or extend in routes/web.php:
      Route::get('/blog/{slug}', [\DrewRoberts\Blog\Http\Controllers\PostController::class, 'show']);
      
  5. API Endpoints:

    • Use the package’s controllers or build custom API routes:
      Route::apiResource('posts', \DrewRoberts\Blog\Http\Controllers\Api\PostController::class);
      

Integration Tips

  • Custom Fields: Add fields to models via model events or traits. Example for Post:
    use DrewRoberts\Blog\Models\Post;
    
    Post::observe(function ($post) {
        if ($post->wasRecentlyCreated) {
            $post->update(['custom_field' => 'value']);
        }
    });
    
  • SEO: Extend models to include meta tags or OpenGraph data:
    use DrewRoberts\Blog\Models\Post;
    
    Post::addGlobalScope('meta', function (Builder $builder) {
        $builder->addSelect(['meta_title', 'meta_description']);
    });
    
  • Media Handling: Use Laravel’s spatie/laravel-medialibrary alongside the package for post/page attachments.

Gotchas and Tips

Pitfalls

  1. Authorization Conflicts:

    • Policies rely on tipoff/authorization. Ensure the package is installed and configured:
      composer require tipoff/authorization
      php artisan vendor:publish --provider="Tipoff\Authorization\AuthorizationServiceProvider" --tag="migrations"
      php artisan migrate
      
    • Debug permission issues with:
      \Tipoff\Authorization\Facades\Authorization::can('update', $post);
      
  2. Nova Resource Overrides:

    • If extending Nova resources, clear Nova’s view cache:
      php artisan nova:publish
      php artisan view:clear
      
  3. Slug Conflicts:

    • Slugs are auto-generated from titles. Handle duplicates manually or use a package like cviebrock/eloquent-sluggable:
      use CViebrock\EloquentSluggable\Sluggable;
      
      class Post extends Model implements Sluggable {
          public function getSlugOptions() {
              return ['source' => 'title'];
          }
      }
      
  4. Missing Config:

    • The config file is empty by default. Add custom settings (e.g., default status) here:
      return [
          'default_post_status' => 'draft',
      ];
      
  5. Outdated Dependencies:

    • The package hasn’t been updated since 2022. Test thoroughly with Laravel 8/9 and PHP 8.x. Fork or extend if needed.

Debugging

  • Model Events: Listen for model events to debug lifecycle issues:
    Post::created(function ($post) {
        Log::info('Post created:', ['id' => $post->id]);
    });
    
  • Policy Debugging: Check registered policies:
    \Tipoff\Authorization\Facades\Authorization::policies();
    
  • Route Debugging: Use php artisan route:list to verify blog routes are registered.

Extension Points

  1. Custom Model Events: Extend models by adding observers or events. Example for Post:

    Post::observe(PostObserver::class);
    
    class PostObserver {
        public function saving(Post $post) {
            $post->author_id = auth()->id();
        }
    }
    
  2. API Responses: Override API controllers to customize responses:

    class CustomPostController extends \DrewRoberts\Blog\Http\Controllers\Api\PostController {
        public function show(Post $post) {
            return response()->json([
                'data' => $post,
                'custom_field' => 'value',
            ]);
        }
    }
    
  3. Query Scopes: Add custom scopes to models. Example for Post:

    class Post extends Model {
        public function scopeFeatured($query) {
            return $query->where('is_featured', true);
        }
    }
    

    Usage:

    Post::published()->featured()->get();
    
  4. Middleware: Protect routes with custom middleware:

    Route::get('/admin/posts', function () {
        // ...
    })->middleware(['auth', 'can:manage,post']);
    
  5. Testing: Use package-specific factories (if available) or create custom ones:

    $post = Post::factory()->create(['status' => 'published']);
    
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.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle