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

Php Htmltruncator Laravel Package

judev/php-htmltruncator

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require judev/php-htmltruncator
    

    Ensure dom, intl, and mbstring PHP extensions are enabled (check php -m).

  2. First Use Case: Truncate a blog post excerpt in a Laravel controller:

    use HtmlTruncator\Truncator;
    
    $postContent = '<p>This is a <strong>sample</strong> post with HTML.</p>';
    $truncated = Truncator::truncate($postContent, 5); // Keep 5 words
    // Output: "<p>This is a <strong>sample</strong> post…</p>"
    
  3. Blade Integration: Add a helper in app/Helpers/html.php:

    if (!function_exists('truncate_html')) {
        function truncate_html($html, $words, $ellipsis = '…') {
            return \HtmlTruncator\Truncator::truncate($html, $words, $ellipsis);
        }
    }
    

    Use in Blade:

    {!! truncate_html($post->content, 10) !!}
    

Implementation Patterns

Usage Patterns

  1. Word-Based Truncation (Default):

    // Truncate to 3 words, default ellipsis
    Truncator::truncate("<p>Hello world, this is a test.</p>", 3);
    // => "<p>Hello world, this…</p>"
    
  2. Character-Based Truncation:

    Truncator::truncate($html, 20, ['length_in_chars' => true]);
    
  3. Custom Ellipsis:

    // Text ellipsis
    Truncator::truncate($html, 5, " (read more)");
    
    // HTML ellipsis (e.g., a link)
    Truncator::truncator($html, 5, '<a href="/read-more">…</a>');
    
  4. Extending Ellipsable Tags:

    Truncator::$ellipsable_tags[] = "blockquote";
    Truncator::truncate("<blockquote>Content here.</blockquote>", 2);
    

Workflows

  1. Dynamic Previews (API/Blade):

    // API Response
    return response()->json([
        'excerpt' => Truncator::truncate($article->body, 8),
    ]);
    
    // Blade (with caching)
    @php
        $truncated = cache()->remember("truncated_{$post->id}", now()->addHours(1), function () use ($post) {
            return truncate_html($post->content, 10);
        });
    @endphp
    {!! $truncated !!}
    
  2. Search Results:

    // In a Scout search result formatter
    public function toArray($model)
    {
        return [
            'title' => $model->title,
            'excerpt' => Truncator::truncate($model->content, 5),
        ];
    }
    
  3. Database Storage:

    // Observer for posts
    public function saved(Post $post)
    {
        $post->update([
            'truncated_excerpt' => Truncator::truncate($post->content, 15),
        ]);
    }
    

Integration Tips

  1. Laravel Service Provider: Bind the truncator for DI:

    $this->app->singleton('truncator', function () {
        return new class {
            public function __invoke($html, $words, $ellipsis = null) {
                return Truncator::truncate($html, $words, $ellipsis);
            }
        };
    });
    

    Usage:

    $this->app->make('truncator')($post->content, 7);
    
  2. Form Request Validation:

    public function rules()
    {
        return [
            'content' => 'required|string|max:10000', // Ensure HTML isn't too large
        ];
    }
    
  3. Testing:

    public function test_truncate_html()
    {
        $html = '<p>Test <strong>HTML</strong> truncation.</p>';
        $truncated = Truncator::truncate($html, 2);
        $this->assertStringContainsString('Test', $truncated);
        $this->assertStringContainsString('…', $truncated);
    }
    

Gotchas and Tips

Pitfalls

  1. DOM Parsing Overhead:

    • Issue: Slow for large HTML strings (>5KB). May time out in shared hosting.
    • Fix: Cache results aggressively or pre-truncate during content creation.
  2. Malformed HTML5:

    • Issue: Fails on non-standard HTML5 (e.g., <div><p>) without html5-php.
    • Fix: Install masterminds/html5 and use:
      $dom = new \Masterminds\HTML5();
      $dom->loadHTML($html);
      
  3. Unicode/Emoji Handling:

    • Issue: mbstring required for accurate word counting in non-Latin scripts.
    • Fix: Ensure mbstring.func_overload = 0 in php.ini.
  4. Nested Tags:

    • Issue: Ellipsis may appear in unexpected places (e.g., inside <table>).
    • Fix: Extend Truncator::$ellipsable_tags or pre-process HTML to wrap content in allowed tags.
  5. PHP 8.x Compatibility:

    • Issue: Potential type errors in older code.
    • Fix: Update the package or fork it to add type hints:
      public static function truncate(string $html, int $words, ?string $ellipsis = null): string
      

Debugging

  1. Log Input/Output:

    $html = '<p>Debug <em>this</em> HTML.</p>';
    $truncated = Truncator::truncate($html, 2);
    \Log::debug("Input: $html");
    \Log::debug("Output: $truncated");
    
  2. Fallback for Failures:

    try {
        return Truncator::truncate($html, $words);
    } catch (\Exception $e) {
        \Log::error("Truncation failed: " . $e->getMessage());
        return Str::limit(strip_tags($html), $words * 5) . '…';
    }
    
  3. Validate HTML First:

    use Symfony\Component\DomCrawler\Crawler;
    
    if (!Crawler::createFromHtml($html)->count()) {
        throw new \InvalidArgumentException("Invalid HTML provided");
    }
    

Config Quirks

  1. Ellipsable Tags:

    • Default: ['p', 'ol', 'ul', 'li', 'div', 'header', 'article', 'nav', 'section', 'footer', 'aside', 'dd', 'dt', 'dl'].
    • Tip: Add blockquote or figure if needed:
      Truncator::$ellipsable_tags = array_merge(Truncator::$ellipsable_tags, ['blockquote']);
      
  2. Character vs. Word Length:

    • Use length_in_chars option for fixed-length truncation (e.g., Twitter-style):
      Truncator::truncate($html, 140, ['length_in_chars' => true]);
      
  3. HTML5 Parsing:

    • Requires html5-php for non-standard HTML5. Install via:
      composer require masterminds/html5
      
    • Use with:
      $dom = new \Masterminds\HTML5();
      $dom->loadHTML($html);
      $truncated = Truncator::truncate($dom->saveHTML(), $words);
      

Extension Points

  1. Custom Truncator Class: Extend the core class for Laravel-specific logic:

    class LaravelTruncator extends \HtmlTruncator\Truncator {
        public static function truncateWithCache($html, $words, $cacheKey) {
            return cache()->remember($cacheKey, now()->addHours(1), function () use ($html, $words) {
                return parent::truncate($html, $words);
            });
        }
    }
    
  2. Blade Component: Create a reusable component (resources/views/components/truncate.blade.php):

    @props(['html', 'words', 'ellipsis' => '…'])
    
    {!! \HtmlTruncator\Truncator::truncate($html, $words, $ellipsis) !!}
    

    Usage:

    @truncate(html: $post->content, words: 8)
    
  3. Eloquent Accessor: Add to

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.
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
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope