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

Markdown Extra Laravel Package

twig/markdown-extra

Twig extension adding Markdown conversion filters: markdown_to_html to render Markdown as HTML, and html_to_markdown to convert HTML back to Markdown. Useful for templating content workflows where Markdown and HTML need to interoperate.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the package (Symfony/Twig projects only):

    composer require twig/markdown-extra league/html-to-markdown
    

    Note: Laravel users should skip this and use cebe/markdown or league/commonmark instead.

  2. Register the extension (Symfony): Add to config/packages/twig.yaml:

    twig:
        extra:
            markdown: true
    
  3. First use case: Render Markdown in a Twig template:

    {{ user_comment|markdown_to_html }}
    

    Pass a Markdown string (e.g., **Hello**) to render as HTML.


Implementation Patterns

Core Workflows

  1. Markdown to HTML (Rendering)

    • Use markdown_to_html filter for user-generated content (e.g., blog posts, comments):
      <div class="content">
          {{ article_body|markdown_to_html }}
      </div>
      
    • Sanitization: Always pair with html-sanitizer for untrusted input:
      {{ user_input|markdown_to_html|sanitize_html }}
      
  2. HTML to Markdown (Conversion)

    • Convert legacy HTML to Markdown for migration:
      {{ legacy_html|html_to_markdown }}
      
    • Limitations: Complex HTML (tables, scripts) may break. Test with real content.
  3. Bidirectional Editing

    • Enable live previews in admin panels:
      {# Display rendered preview #}
      <div class="preview">{{ markdown_editor|markdown_to_html }}</div>
      
      {# Sync back to Markdown #}
      {{ form_hidden('content', markdown_editor|html_to_markdown) }}
      

Integration Tips

  • Symfony Forms: Use with Symfony\Component\Form\Extension\Core\Type\TextareaType:

    $builder->add('description', TextareaType::class, [
        'attr' => ['class' => 'markdown-editor'],
    ]);
    

    Render with:

    {{ form_row(form.description) }}
    <div class="preview">{{ form.description.data|markdown_to_html }}</div>
    
  • Caching: Cache rendered HTML for performance:

    {% cache 'markdown_'.article.id %}
        {{ article.content|markdown_to_html }}
    {% endcache %}
    
  • Custom Extensions: Extend Twig’s Markdown parser via league/commonmark:

    use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
    use League\CommonMark\Environment;
    
    $env = new Environment();
    $env->addExtension(new CommonMarkCoreExtension());
    

Gotchas and Tips

Pitfalls

  1. Laravel Incompatibility

    • Error: Class 'Twig\Extension\MarkdownExtraExtension' not found in Laravel.
    • Fix: Use cebe/markdown or league/commonmark instead. Avoid Twig bridges unless necessary.
  2. HTML-to-Markdown Lossiness

    • Issue: <table>, <script>, or inline styles may not round-trip cleanly.
    • Fix: Manually validate output or pre-process HTML:
      {{ legacy_html|replace({'<table>': '', '</table>': ''})|html_to_markdown }}
      
  3. XSS Risks

    • Issue: Unsanitized Markdown → HTML conversion allows script injection.
    • Fix: Always sanitize:
      {{ user_input|markdown_to_html|sanitize_html }}
      
      Install html-sanitizer:
      composer require html-sanitizer
      
  4. Dependency Conflicts

    • Issue: league/html-to-markdown may conflict with Laravel’s Twig.
    • Fix: Pin versions in composer.json:
      "require": {
          "league/html-to-markdown": "^5.0"
      }
      
  5. Performance Overhead

    • Issue: Per-request parsing adds latency.
    • Fix: Cache rendered HTML or pre-render in the backend:
      // In a controller
      $article->setAttribute('rendered_content', $article->content|markdown_to_html);
      

Debugging Tips

  • Filter Availability: Verify the extension is registered:

    {% if 'markdown_to_html' in twig.filters %}
        {# Filter is available #}
    {% endif %}
    
  • Markdown Parsing Errors: Check for invalid syntax:

    {% if markdown_content is not null %}
        {{ markdown_content|markdown_to_html }}
    {% else %}
        <p>Invalid Markdown</p>
    {% endif %}
    
  • HTML-to-Markdown Debugging: Log the output to inspect lossiness:

    {% set markdown = html_content|html_to_markdown %}
    {{ dump(markdown) }}
    

Extension Points

  1. Custom Markdown Parser Override the default parser in a Twig extension:

    use League\CommonMark\MarkdownConverter;
    
    class CustomMarkdownExtension extends \Twig\Extension\AbstractExtension
    {
        public function getFilters()
        {
            return [
                new \Twig\TwigFilter('markdown_to_html', [$this, 'customMarkdownToHtml']),
            ];
        }
    
        public function customMarkdownToHtml($markdown)
        {
            $converter = new MarkdownConverter();
            return $converter->convert($markdown);
        }
    }
    
  2. Post-Processing Filters Chain filters for custom transformations:

    {{ content
        | markdown_to_html
        | replace({'<p>': '<div class="prose">'})
        | sanitize_html
    }}
    
  3. Environment Configuration Configure league/html-to-markdown globally in a service provider:

    use League\HTMLToMarkdown\HtmlConverter;
    
    $converter = new HtmlConverter();
    $converter->getConfig()->setExtra('tables', true); // Enable table support
    
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