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

Knp Markdown Bundle Laravel Package

knplabs/knp-markdown-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require knplabs/knp-markdown-bundle
    

    Add to config/bundles.php (Laravel 5.5+ auto-discovers, but explicit inclusion ensures compatibility):

    Knp\Bundle\MarkdownBundle\KnpMarkdownBundle::class => ['all' => true],
    
  2. Basic Usage Inject the KnpMarkdownBundle\MarkdownService into a controller or service:

    use Knp\Bundle\MarkdownBundle\MarkdownService;
    
    public function __construct(private MarkdownService $markdown)
    {
    }
    
    public function renderMarkdown(string $markdownContent): string
    {
        return $this->markdown->transformMarkdown($markdownContent);
    }
    
  3. First Use Case Render a blog post or comment in a view:

    {{ markdown(content) }}  {# Twig filter #}
    

    Or in PHP:

    $html = $this->markdown->transformMarkdown($markdownText);
    return view('post.show', ['content' => $html]);
    

Implementation Patterns

Core Workflows

  1. Twig Integration Use the markdown filter in Twig templates:

    {{ post.content|markdown }}
    

    Configure extensions (e.g., tables, footnotes) via config/packages/knp_markdown.yaml:

    twig:
        markdown_extensions: [extra, tables]
    
  2. Dynamic Processing Process markdown in controllers/services:

    $html = $this->markdown->transformMarkdown($rawMarkdown, [
        'extra' => true,
        'safe_mode' => false,
    ]);
    
  3. Caching Cache rendered markdown to avoid reprocessing:

    $cacheKey = 'markdown_'.$post->id;
    $html = Cache::remember($cacheKey, now()->addHours(1), function() use ($post) {
        return $this->markdown->transformMarkdown($post->content);
    });
    
  4. Form Handling Sanitize markdown input (e.g., from forms) to prevent XSS:

    $sanitized = $this->markdown->transformMarkdown($userInput, [
        'safe_mode' => true, // Disables dangerous HTML tags
    ]);
    

Advanced Patterns

  1. Custom Extensions Register a custom extension (e.g., for Laravel-specific syntax):

    $markdown = new \Michelf\MarkdownExtra();
    $markdown->addExtension(new class extends \Michelf\MarkdownExtra_Extension {
        public function getName() { return 'laravel'; }
        public function getPattern() { return '/\[@(\w+)\]/'; }
        public function handle($text, $matches) {
            return '<a href="/user/'.$matches[1].'">@'.$matches[1].'</a>';
        }
    });
    $this->markdown->setMarkdown($markdown);
    
  2. Event Listeners Hook into markdown processing via events (e.g., log processed content):

    public function handle(KnpMarkdownEvent $event)
    {
        Log::debug('Markdown processed', ['content' => $event->getContent()]);
    }
    

    Register in EventServiceProvider:

    protected $listen = [
        KnpMarkdownEvent::MARKDOWN_TRANSFORMED => [
           \App\Listeners\LogMarkdown::class,
        ],
    ];
    
  3. API Responses Return markdown-rendered content in API responses:

    return response()->json([
        'content' => $this->markdown->transformMarkdown($post->content),
    ]);
    

Gotchas and Tips

Common Pitfalls

  1. XSS Vulnerabilities

    • Issue: safe_mode: false allows arbitrary HTML/JS injection.
    • Fix: Always use safe_mode: true in production or sanitize output:
      $html = $this->markdown->transformMarkdown($input, ['safe_mode' => true]);
      $html = strip_tags($html, '<p><a><strong><em><ul><ol><li><br>');
      
  2. Extension Conflicts

    • Issue: Some extensions (e.g., tables) may break rendering.
    • Fix: Test extensions in isolation and disable unused ones:
      # config/packages/knp_markdown.yaml
      twig:
          markdown_extensions: [extra] # Exclude problematic extensions
      
  3. Performance

    • Issue: Processing large markdown (e.g., 100KB+) can be slow.
    • Fix: Cache aggressively and use now()->addDays(7) for static content.
  4. Twig vs. PHP API

    • Issue: Twig filter and PHP service may have different configs.
    • Fix: Explicitly pass options to the PHP service to avoid surprises:
      $this->markdown->transformMarkdown($text, $this->getMarkdownOptions());
      

Debugging Tips

  1. Inspect Extensions Dump enabled extensions to debug issues:

    $markdown = $this->markdown->getMarkdown();
    dump(get_class_methods($markdown));
    
  2. Raw Output Compare raw vs. processed markdown to spot parsing errors:

    $raw = $request->input('content');
    $processed = $this->markdown->transformMarkdown($raw);
    dd(['raw' => $raw, 'processed' => $processed]);
    
  3. Configuration Overrides Override global config per request:

    $this->markdown->setMarkdownOptions([
        'extra' => true,
        'safe_mode' => false,
    ]);
    

Extension Points

  1. Custom Markdown Parser Replace the default parser (Michelf/Markdown) with Parsedown or [CommonMark]:

    $this->markdown->setMarkdown(new \Parsedown());
    
  2. Pre/Post-Processing Wrap the service to add logic:

    class CustomMarkdownService
    {
        public function __construct(private MarkdownService $markdown) {}
    
        public function render(string $content): string
        {
            $html = $this->markdown->transformMarkdown($content);
            return $this->postProcess($html);
        }
    
        private function postProcess(string $html): string
        {
            // Add custom logic (e.g., analytics tags)
            return str_replace('<p>', '<p data-track="true">', $html);
        }
    }
    
  3. Environment-Specific Config Use Laravel’s config caching to switch extensions per environment:

    # config/packages/knp_markdown/dev.yaml
    twig:
        markdown_extensions: [extra, footnotes]
    
    # config/packages/knp_markdown/prod.yaml
    twig:
        markdown_extensions: [extra]
        safe_mode: true
    
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.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui