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

Slug Laravel Package

moox/slug

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require moox/slug
    php artisan slug:install
    
    • The slug:install command publishes the config file (config/slug.php) and creates a migration for the slugs table.
  2. First Use Case:

    • Generate a slug from a string:
      use Moox\Slug\Slug;
      
      $slug = Slug::create('Hello World!');
      // Returns: 'hello-world'
      
    • Generate a slug for a model:
      use Moox\Slug\Slug;
      
      $slug = Slug::createForModel(new Post(), 'title');
      // Generates slug from the `title` attribute of the `Post` model.
      
  3. Where to Look First:

    • Config File: config/slug.php (customize separators, transliteration, etc.).
    • Service Provider: Moox\Slug\SlugServiceProvider (registers the Slug facade).
    • Migration: database/migrations/[timestamp]_create_slugs_table.php (check table structure).

Implementation Patterns

Core Workflows

  1. Generating Slugs:

    • Basic Usage:
      $slug = Slug::create('My Awesome Post');
      // Output: 'my-awesome-post'
      
    • Custom Separator:
      $slug = Slug::create('My Awesome Post', '-', true);
      // Output: 'my-awesome-post' (third param: force lowercase)
      
    • Transliteration:
      $slug = Slug::create('Café au Lait');
      // Output: 'cafe-au-lait' (handles accented characters).
      
  2. Model Integration:

    • Accessing Slugs:
      use Moox\Slug\HasSlug;
      
      class Post extends Model
      {
          use HasSlug;
          protected $sluggable = 'title'; // Attribute to slugify.
      }
      
      $post = Post::find(1);
      $post->slug; // Returns the slug (e.g., 'my-awesome-post').
      
    • Updating Slugs:
      $post = Post::find(1);
      $post->title = 'Updated Title';
      $post->save(); // Automatically updates the slug.
      
  3. Dynamic Tabs (Moox Core Feature):

    • Configure tabs in config/slug.php to filter the slugs table:
      'tabs' => [
          'active' => ['label' => 'Active Slugs', 'value' => 1],
          'inactive' => ['label' => 'Inactive Slugs', 'value' => 0],
      ],
      
    • Use in Blade:
      {!! \Moox\Slug\SlugTab::render('active') !!}
      
  4. Translatable Config:

    • Localize slug generation rules per language:
      'translatable' => [
          'separator' => [
              'en' => '-',
              'es' => '_',
          ],
      ],
      
    • Set language dynamically:
      $slug = Slug::create('Hola Mundo', null, true, 'es');
      // Output: 'hola_mundo' (uses Spanish separator).
      

Integration Tips

  • Seeding Slugs: Use the Slug::createForModel() method in seeders to pre-generate slugs for existing records.

    $posts = Post::all();
    foreach ($posts as $post) {
        $post->slug = Slug::createForModel($post, 'title');
        $post->save();
    }
    
  • Validation: Combine with Laravel validation to ensure slug uniqueness:

    use Illuminate\Validation\Rule;
    
    $validator = Validator::make($request->all(), [
        'slug' => [
            'required',
            Rule::unique('slugs')->ignore($post->id),
        ],
    ]);
    
  • API Responses: Serialize slugs in API responses using Laravel's App\Http\Resources:

    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'title' => $this->title,
            'slug' => $this->slug,
        ];
    }
    

Gotchas and Tips

Pitfalls

  1. Case Sensitivity:

    • Slugs are case-sensitive by default in URLs. Ensure consistency when generating and accessing them.
    • Force lowercase with the third parameter:
      $slug = Slug::create('Hello WORLD', '-', true); // 'hello-world'
      
  2. Reserved Words:

    • Avoid generating slugs that conflict with Laravel routes (e.g., admin, login). Filter them in the config:
      'reserved' => ['admin', 'login', 'api'],
      
  3. Duplicate Slugs:

    • The package does not handle uniqueness by default. Use Laravel's unique validation or a custom solution:
      $slug = Slug::createUnique('My Post', $post->id);
      // Requires extending the Slug class or using a scope.
      
  4. Performance:

    • Generating slugs for large datasets (e.g., in seeders) can be slow. Batch updates or use database transactions:
      DB::transaction(function () {
          Post::chunk(100, function ($posts) {
              foreach ($posts as $post) {
                  $post->slug = Slug::createForModel($post, 'title');
              }
              Post::whereIn('id', $posts->pluck('id'))->update();
          });
      });
      

Debugging

  1. Config Overrides:

    • If slugs aren’t generating as expected, check:
      • config/slug.php for custom rules.
      • Environment-specific config (e.g., .env overrides).
    • Temporarily disable transliteration to isolate issues:
      'transliterate' => false,
      
  2. Model Events:

    • Debug HasSlug events by listening to saving or updating:
      Post::saved(function ($post) {
          \Log::info('Slug generated:', ['slug' => $post->slug]);
      });
      
  3. Migration Issues:

    • If the slugs table isn’t created, run:
      php artisan migrate
      
    • Check for existing tables with the same name (e.g., slugs) and rename them.

Extension Points

  1. Custom Slug Generator:

    • Extend the Moox\Slug\Slug class to add logic:
      namespace App\Services;
      
      use Moox\Slug\Slug as BaseSlug;
      
      class CustomSlug extends BaseSlug
      {
          public static function createWithPrefix($string, $prefix = 'app-')
          {
              return parent::create($prefix . $string);
          }
      }
      
  2. Dynamic Separators:

    • Override separators per model or context:
      class Product extends Model
      {
          use HasSlug;
      
          protected $sluggable = 'name';
          protected $slugSeparator = '--'; // Custom separator.
      }
      
  3. Slug Storage:

    • Store slugs in a custom table by overriding the HasSlug trait’s getSlugAttribute:
      public function getSlugAttribute()
      {
          return $this->customSlugs()->value('slug');
      }
      
  4. Transliteration Rules:

    • Extend the transliteration map in config/slug.php:
      'transliterate' => [
          'ä' => 'ae',
          'ü' => 'ue',
          'ö' => 'oe',
          // Add custom mappings.
      ],
      

Pro Tips

  • URL-Friendly Slugs: Combine with Laravel’s Str::of() for additional URL sanitization:

    use Illuminate\Support\Str;
    
    $slug = Str::of(Slug::create('My Post!'))->slug();
    // Output: 'my-post' (removes special chars).
    
  • SEO Optimization: Use the slug column in Sitemap or Meta packages (e.g., spatie/laravel-sitemap) for dynamic URLs:

    public function toArray()
    {
        return [
            'loc' => url($this->slug),
            'lastmod' => $this->updated_at,
        ];
    }
    
  • Testing: Mock the Slug facade in tests:

    $this->mock(\Moox\Slug\Slug::class)->shouldReceive('create')
        ->with('Test')
        ->andReturn('test-slug');
    
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.
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
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