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

Persian Slug Laravel Package

pishran/persian-slug

pishran/persian-slug یک پکیج ساده برای ساخت اسلاگ استاندارد با پشتیبانی کامل از فارسی است. ورودی‌های فارسی و انگلیسی را به اسلاگ‌های خوانا تبدیل می‌کند (مثل سلام دنیا → سلام-دنیا، Hello world → hello-world). نصب با Composer.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require pishran/persian-slug
    

    No additional configuration is required—just autoload the package.

  2. First Use Case: Generate a Persian-friendly slug from a string:

    use Pishran\PersianSlug\PersianSlug;
    
    $slug = PersianSlug::slug('سلام دنیا!'); // Output: "سلام-دنیا"
    $slug = PersianSlug::slug('Hello world!'); // Output: "hello-world"
    
  3. Where to Look First:

    • README.md for basic usage.
    • Tests for edge cases (e.g., mixed scripts, special characters).

Implementation Patterns

Core Workflows

  1. Generating Slugs in Controllers:

    public function store(Request $request)
    {
        $title = $request->input('title');
        $slug = PersianSlug::slug($title); // Auto-converts to slug
        // Save to DB: $model->slug = $slug;
    }
    
  2. Form Request Validation: Use the package to sanitize slugs before saving:

    public function rules()
    {
        return [
            'title' => 'required|string',
            'slug' => 'nullable|string|unique:posts,slug',
        ];
    }
    
    public function withValidator($validator)
    {
        $validator->after(function ($validator) {
            $slug = PersianSlug::slug($this->title);
            $this->merge([
                'slug' => $slug,
            ]);
        });
    }
    
  3. Model Observers: Auto-generate slugs on creating:

    class PostObserver
    {
        public function creating(Post $post)
        {
            if (empty($post->slug)) {
                $post->slug = PersianSlug::slug($post->title);
            }
        }
    }
    
  4. API Responses: Normalize slugs in responses:

    return response()->json([
        'data' => [
            'title' => $post->title,
            'slug' => PersianSlug::slug($post->title), // Ensure consistency
        ],
    ]);
    

Integration Tips

  • Laravel Routes: Use slugs in route parameters:

    Route::get('/posts/{slug}', [PostController::class, 'show']);
    

    Ensure the slug is URL-friendly (e.g., سلام-دنیا%D8%A7%D8%B3%D9%84%D8%A7%D9%85-%D8%AF%D9%86%DB%8C%D8%A7 in UTF-8).

  • SEO Meta Tags: Dynamically generate slugs for Open Graph/Twitter cards:

    $metaSlug = PersianSlug::slug($post->title, '-', true); // Force lowercase
    
  • Localization: Combine with Laravel’s Str::slug() for mixed-language content:

    $slug = Str::contains($title, ['ا', 'ب', 'ج'])
        ? PersianSlug::slug($title)
        : Str::slug($title);
    

Gotchas and Tips

Pitfalls

  1. URL Encoding: Persian characters in slugs (e.g., سلام) must be UTF-8 encoded for URLs:

    $encodedSlug = urlencode(PersianSlug::slug('سلام دنیا')); // "سلام-دنیا"
    // OR use Laravel's `Str::of($slug)->toRoute()` for automatic encoding.
    
  2. Collisions: Slugs like سلام-دنیا and سلام-دنیا-2 may conflict. Handle uniqueness in the DB:

    $slug = PersianSlug::slug($title);
    $originalSlug = $slug;
    $count = 2;
    while (Post::where('slug', $slug)->exists()) {
        $slug = "{$originalSlug}-{$count}";
        $count++;
    }
    
  3. Special Characters: The package removes most special chars, but test edge cases like:

    PersianSlug::slug('سلام!@# دنیا'); // "سلام-دنیا"
    PersianSlug::slug('Hello_World');  // "hello-world"
    
  4. Performance: Avoid regenerating slugs in loops or heavy operations. Cache results if needed:

    $slug = Cache::remember("slug_{$title}", now()->addHours(1), function() use ($title) {
        return PersianSlug::slug($title);
    });
    

Debugging

  • Unexpected Output: Check for hidden Unicode characters (e.g.,  ). Use:

    dd(Str::of($input)->toPlainString()); // Inspect raw string
    
  • Case Sensitivity: The package converts to lowercase by default. Override with:

    PersianSlug::slug('HELLO', '-', false); // "HELLO-world"
    

Extension Points

  1. Custom Rules: Extend the slug logic via a service provider:

    PersianSlug::extend(function ($string, $separator = '-', $lowercase = true) {
        // Add custom logic (e.g., replace 'php' with 'laravel')
        return str_replace('php', 'laravel', $string);
    });
    
  2. Middleware: Sanitize slugs in incoming requests:

    public function handle($request, Closure $next)
    {
        $request->merge([
            'slug' => PersianSlug::slug($request->slug),
        ]);
        return $next($request);
    }
    
  3. Testing: Mock the slugger in unit tests:

    $this->partialMock(PersianSlug::class, function ($mock) {
        $mock->shouldReceive('slug')->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.
besmartand-pro/php-quality-config
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity