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

Urllinker Laravel Package

kwi/urllinker

Laravel/PHP URL linker that scans text and converts web addresses, emails, and similar patterns into clickable HTML links. Lightweight helper for turning plain content into safe, formatted output in views, notifications, and user-generated text.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation

    composer require kwi/urllinker
    

    No additional configuration is required for basic usage.

  2. First Usage Use the UrlLinker class directly in your code:

    use Kwi\UrlLinker\UrlLinker;
    
    $text = "Check out https://laravel.com and http://example.com";
    $linkedText = UrlLinker::link($text);
    

    Output:

    <a href="https://laravel.com">https://laravel.com</a> and <a href="http://example.com">http://example.com</a>
    
  3. Where to Look First

    • Source Code: UrlLinker.php for regex patterns and core logic.
    • Facade: Use Kwi\UrlLinker\Facades\UrlLinker for cleaner syntax in Laravel applications.
    • Tests: UrlLinkerTest.php for edge cases and expected behavior.

Implementation Patterns

Core Usage Patterns

  1. Basic Linking Convert plain text URLs to HTML links:

    $text = "Visit my site: example.com";
    echo UrlLinker::link($text);
    

    Output:

    Visit my site: <a href="http://example.com">example.com</a>
    
  2. HTML Context Use linkHtml() for existing HTML content:

    $html = '<p>Check <a href="#">here</a> or visit http://example.com</p>';
    echo UrlLinker::linkHtml($html);
    

    Output:

    <p>Check <a href="#">here</a> or visit <a href="http://example.com">http://example.com</a></p>
    
  3. Laravel Integration Service Provider (Recommended)

    // app/Providers/AppServiceProvider.php
    public function boot()
    {
        $this->app->singleton(UrlLinker::class);
    }
    

    Facade Usage

    use Kwi\UrlLinker\Facades\UrlLinker;
    
    $linkedText = UrlLinker::link($comment->text);
    
  4. Blade Directives Create a custom Blade directive for templates:

    // app/Providers/BladeServiceProvider.php
    Blade::directive('linkUrls', function ($expression) {
        return "<?php echo \\Kwi\\UrlLinker\\UrlLinker::link({$expression}); ?>";
    });
    

    Usage in Blade:

    {!! linkUrls($post->content) !!}
    
  5. Text Processing Pipeline Combine with Laravel’s Str helper or other text processors:

    $processedText = Str::markdown($markdownText);
    $linkedText = UrlLinker::link($processedText);
    
  6. Form Requests Auto-link URLs in form submissions or validation messages:

    $validator = Validator::make($data, $rules);
    $errors = $validator->errors();
    $linkedErrors = collect($errors->all())
        ->map(fn($error) => UrlLinker::link($error))
        ->implode('<br>');
    

Advanced Patterns

  1. Custom Link Attributes Extend the UrlLinker class to add custom attributes:

    class CustomUrlLinker extends UrlLinker
    {
        protected function getLinkAttributes($url)
        {
            return 'target="_blank" rel="noopener noreferrer"';
        }
    }
    
  2. Domain Whitelisting Filter URLs to only link specific domains:

    $whitelistedUrls = UrlLinker::link($text, ['example.com', 'laravel.com']);
    
  3. Event-Based Processing Use Laravel events to process URLs before storage or display:

    // In a service or observer
    event(new ProcessingComment($comment));
    
    // Listener
    public function handle(ProcessingComment $event)
    {
        $event->comment->linked_body = UrlLinker::link($event->comment->body);
    }
    
  4. API Responses Auto-link URLs in JSON:API or GraphQL responses:

    return response()->json([
        'data' => [
            'id' => '1',
            'type' => 'comment',
            'attributes' => [
                'body' => UrlLinker::link($comment->body),
            ],
        ],
    ]);
    
  5. Email Templates Use in Laravel’s Mailable classes:

    public function build()
    {
        return $this->markdown('emails.comment')
            ->with(['comment' => UrlLinker::link($this->comment->body)]);
    }
    

Gotchas and Tips

Common Pitfalls

  1. False Positives

    • Issue: Non-URL text (e.g., example.com in a sentence) gets linked.
    • Fix: Use linkHtml() for strict HTML contexts or adjust the regex in UrlLinker::getRegex().
    • Workaround: Post-process with filter_var($url, FILTER_VALIDATE_URL).
  2. HTML Injection

    • Issue: Malicious URLs in user input can lead to XSS.
    • Fix: Always sanitize output, especially in HTML contexts:
      $cleanHtml = Purifier::clean(UrlLinker::linkHtml($userInput));
      
  3. Performance with Large Texts

    • Issue: Slow processing for long texts (e.g., books, articles).
    • Fix: Use linkHtml() for pre-existing HTML or implement caching:
      Cache::remember("linked_{$text}", now()->addHours(1), function() use ($text) {
          return UrlLinker::link($text);
      });
      
  4. Regex Limitations

    • Issue: May miss modern URL formats (e.g., IPv6, Unicode domains).
    • Fix: Extend the regex in UrlLinker::getRegex():
      protected function getRegex()
      {
          return '/\b(?:https?:\/\/|www\.|ftp:\/\/)?[a-z0-9-]+(?:\.[a-z0-9-]+)+(?:[\/\?#][^\s"]*)?\b/i';
      }
      
  5. Nested HTML Conflicts

    • Issue: Breaks existing HTML tags (e.g., <a> inside <code>).
    • Fix: Use linkHtml() for mixed content or disable linking in specific tags:
      $dom = new \DOMDocument();
      $dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
      $xpath = new \DOMXPath($dom);
      // Disable linking in <code> tags
      foreach ($xpath->query('//code') as $node) {
          $node->parentNode->removeChild($node);
      }
      $cleanHtml = $dom->saveHTML();
      echo UrlLinker::linkHtml($cleanHtml);
      

Debugging Tips

  1. Inspect Regex Matches Use preg_match_all to debug regex behavior:

    preg_match_all(UrlLinker::getRegex(), $text, $matches);
    dd($matches);
    
  2. Log False Positives/Negatives Track edge cases for regex tuning:

    $linked = UrlLinker::link($text);
    if (strpos($text, 'example.com') !== false && strpos($linked, 'example.com') === false) {
        Log::warning("False negative: $text");
    }
    
  3. Test with Edge Cases Validate against these inputs:

    • Unicode URLs: https://例子.测试
    • IPv6: http://[2001:db8::1]
    • URLs in code: Visit http://example.com or \http://example.com``
    • Malformed URLs: htp://missing-tld

Configuration Quirks

  1. No Built-in Config

    • The package has no config file. Customize via:
      • Extending the UrlLinker class.
      • Overriding methods like getRegex(), getLinkAttributes(), or shouldLink().
  2. Default Behavior

    • Always links http://, https://, and www. URLs.
    • Does not link mailto:, tel:, or other protocols by default.
  3. HTML vs. Text

    • Use link() for plain text.
    • Use linkHtml() for existing HTML to avoid double-encoding.

Extension Points

  1. Custom Linking Logic Override the link() method to add pre/post-processing:
    class CustomUrl
    
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.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
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
christhompsontldr/laravel-inky