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

Html2Text Laravel Package

soundasleep/html2text

Convert HTML to clean, readable plain text in PHP. soundasleep/html2text handles tags, links, images, and whitespace to produce email-friendly, human-readable output, with sensible defaults and options for tweaking formatting.

Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation

    composer require soundasleep/html2text
    

    Add to composer.json if not using Composer globally:

    "require": {
        "soundasleep/html2text": "^3.0"
    }
    
  2. Basic Usage

    use Soundasleep\Html2Text\Html2Text;
    
    $html = '<h1>Hello World</h1><p>This is <strong>HTML</strong>.</p>';
    $converter = new Html2Text();
    $text = $converter->getText($html);
    
    // Output: "Hello World\n\nThis is HTML."
    
  3. First Use Case Convert HTML emails to plain text for storage or display in a text-only interface:

    $emailHtml = '<h2>Welcome!</h2><p>Click <a href="/login">here</a>.</p>';
    $plainText = (new Html2Text())->getText($emailHtml);
    

Implementation Patterns

Common Workflows

  1. Laravel Service Provider Integration Register the converter in AppServiceProvider:

    public function register()
    {
        $this->app->singleton(Html2Text::class, function () {
            return new Html2Text();
        });
    }
    

    Inject via constructor:

    public function __construct(private Html2Text $converter) {}
    
  2. Middleware for Text-Only Responses Convert HTML responses to plain text in middleware:

    public function handle($request, Closure $next)
    {
        $response = $next($request);
        if ($request->wantsText()) {
            $text = app(Html2Text::class)->getText($response->getContent());
            $response->setContent($text);
        }
        return $response;
    }
    
  3. Model Observers for Automatic Conversion Store plain-text versions of HTML fields:

    public function saving(Model $model)
    {
        if ($model->html_content) {
            $model->text_content = app(Html2Text::class)->getText($model->html_content);
        }
    }
    
  4. Blade Directives Create a Blade directive for inline conversion:

    Blade::directive('toText', function ($expression) {
        return "<?php echo app(\\Soundasleep\\Html2Text\\Html2Text::class)->getText({$expression}); ?>";
    });
    

    Usage:

    @toText($htmlVariable)
    
  5. API Response Transformation Use in Laravel API resources:

    public function toArray($request)
    {
        return [
            'title' => $this->title,
            'content_text' => app(Html2Text::class)->getText($this->content),
        ];
    }
    

Integration Tips

  • Customize Conversion Rules Extend the converter for domain-specific needs:

    $converter = new Html2Text();
    $converter->setOption('ignore_links', true); // Skip links entirely
    $converter->setOption('width', 80); // Wrap text at 80 chars
    
  • Batch Processing Useful for converting large datasets (e.g., blog posts):

    $posts = Post::all();
    foreach ($posts as $post) {
        $post->update(['text_content' => $converter->getText($post->content)]);
    }
    
  • Testing Mock the converter in tests:

    $this->app->instance(Html2Text::class, Mockery::mock(Html2Text::class));
    

Gotchas and Tips

Pitfalls

  1. Link Handling

    • By default, links are converted to [text](url). Disable with:
      $converter->setOption('ignore_links', true);
      
    • Or customize the format:
      $converter->setOption('link_style', 'text (url)');
      
  2. Nested HTML Complex nested HTML (e.g., tables, lists) may not convert as expected. Use setOption('skip_tags', ['table', 'div']) to ignore problematic tags.

  3. Whitespace Preservation Extra whitespace in HTML may cause awkward line breaks. Trim input:

    $converter->getText(trim($html));
    
  4. Character Encoding Ensure input HTML is UTF-8 encoded to avoid mojibake in output.

  5. Performance Avoid instantiating the converter repeatedly. Use dependency injection or a singleton.


Debugging

  • Inspect Conversion Rules Dump the converter’s options to debug:

    var_dump($converter->getOptions());
    
  • Log Raw vs. Converted Output Compare input/output for discrepancies:

    \Log::debug("Input HTML:", [$html]);
    \Log::debug("Converted Text:", [$converter->getText($html)]);
    
  • Check for Malformed HTML Use a validator like HTMLPurifier to clean input before conversion if needed.


Extension Points

  1. Custom Tag Handlers Override how specific tags are processed:

    $converter->setOption('pre_tags', ['pre', 'code']); // Preserve preformatted text
    
  2. Post-Processing Chain with str_replace or regex for fine-tuning:

    $text = $converter->getText($html);
    $text = preg_replace('/\s+/', ' ', $text); // Normalize whitespace
    
  3. Event Listeners Trigger actions on conversion (e.g., log changes):

    $converter->addListener(function ($text) {
        \Log::info("Converted text:", [$text]);
    });
    
  4. Laravel Events Dispatch events after conversion:

    event(new TextConverted($text));
    

Config Quirks

  • Default Options Key options:

    $converter->setOption('width', 78); // Line width
    $converter->setOption('xhtml', true); // Handle XHTML
    $converter->setOption('proportional_headers', true); // Scale headers
    
  • Case Sensitivity Tag names in options are case-insensitive (e.g., 'ignore_tags' or 'Ignore_Tags').

  • Priority Options set later override earlier ones. Reset with:

    $converter->resetOptions();
    
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.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport