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 Bundle Laravel Package

adrianbaez/markdown-bundle

Symfony 4 bundle that adds a Markdown parsing service and Twig filter. Uses Parsedown by default but can be configured to use any Markdown library, making it easy to render Markdown content in templates and services.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require adrianbaez/markdown-bundle
    

    Add to config/bundles.php (Symfony 4+ auto-discovers, but explicit inclusion ensures clarity):

    return [
        // ...
        Adrianbaez\MarkdownBundle\MarkdownBundle::class => ['all' => true],
    ];
    
  2. First Use Case Inject the MarkdownParser service into a controller or Twig template:

    // In a controller
    use Adrianbaez\MarkdownBundle\Parser\MarkdownParserInterface;
    
    public function showMarkdown(MarkdownParserInterface $parser) {
        $markdown = "# Hello, **Markdown**!";
        $html = $parser->parse($markdown);
        return new Response($html);
    }
    

    Or in Twig:

    {{ markdown_content|markdown }}
    
  3. Key Files to Review

    • config/packages/adrianbaez_markdown.yaml (default config)
    • src/Resources/doc/index.md (documentation)
    • src/Parser/MarkdownParserInterface.php (core interface)

Implementation Patterns

Core Workflows

  1. Parsing Markdown in Controllers

    public function renderBlogPost(MarkdownParserInterface $parser, string $markdownContent) {
        $html = $parser->parse($markdownContent);
        return $this->render('post/show.html.twig', ['content' => $html]);
    }
    
  2. Twig Integration

    • Use the markdown filter for inline parsing:
      {{ post.content|markdown }}
      
    • Use the markdown_block function for dedicated blocks:
      {% markdown_block post.content %}
      
  3. Custom Markdown Libraries Override the default Parsedown by configuring a custom parser:

    # config/packages/adrianbaez_markdown.yaml
    adrianbaez_markdown:
        parser: App\Custom\MarkdownParser
    
  4. Caching Parsed Output Extend the parser to cache results (e.g., using Symfony Cache component):

    class CachedMarkdownParser implements MarkdownParserInterface {
        private $decorated;
        private $cache;
    
        public function __construct(MarkdownParserInterface $parser, CacheInterface $cache) {
            $this->decorated = $parser;
            $this->cache = $cache;
        }
    
        public function parse(string $markdown): string {
            $cacheKey = md5($markdown);
            return $this->cache->get($cacheKey, function() use ($markdown) {
                return $this->decorated->parse($markdown);
            });
        }
    }
    
  5. Dynamic Markdown Sources Fetch Markdown from APIs or databases:

    public function getMarkdownFromApi(MarkdownParserInterface $parser, string $apiUrl) {
        $markdown = file_get_contents($apiUrl);
        return $parser->parse($markdown);
    }
    

Gotchas and Tips

Pitfalls

  1. Deprecated Symfony Version

    • The package targets Symfony 4 (released 2018). Test thoroughly with Symfony 5/6+ due to potential BC breaks (e.g., autowiring, Twig changes).
    • Workaround: Use a compatibility layer or fork the package.
  2. Parsedown Limitations

    • Default Parsedown lacks support for tables, definition lists, or footnotes. Extend it or switch to League\CommonMark:
      adrianbaez_markdown:
          parser: League\CommonMark\MarkdownConverter
      
  3. Twig Filter Scope

    • The markdown filter is global by default. Override it in a custom Twig extension if you need per-environment behavior:
      class CustomTwigExtension extends \Twig\Extension\AbstractExtension {
          public function getFilters() {
              return [
                  new \Twig\TwigFilter('markdown', [$this->parser, 'parse'], ['is_safe' => ['html']]),
              ];
          }
      }
      
  4. HTML Sanitization

    • Parsedown outputs raw HTML. Sanitize output if user-generated content is involved:
      use Symfony\Component\DomCrawler\Crawler;
      $cleanHtml = (new Crawler($html))->html();
      
  5. Configuration Overrides

    • The bundle does not expose all Parsedown options via config. Override the parser class directly:
      services:
          adrianbaez_markdown.parser:
              class: ParsedownExtra\ParsedownExtra
              arguments: ['--extra']
      

Debugging Tips

  1. Check Parser Output Log raw Markdown and parsed HTML to debug issues:

    file_put_contents(
        'debug/markdown.log',
        "Markdown: {$markdown}\nHTML: {$html}\n\n",
        FILE_APPEND
    );
    
  2. Verify Autowiring Ensure the MarkdownParserInterface is correctly autowired. If not, explicitly bind it:

    services:
        Adrianbaez\MarkdownBundle\Parser\MarkdownParserInterface: '@adrianbaez_markdown.parser'
    
  3. Twig Filter Testing Test Twig filters in isolation using twig:render:

    php bin/console twig:render --env=dev --debug blog/post.html.twig
    

Extension Points

  1. Custom Parsers Implement MarkdownParserInterface for full control:

    class MyMarkdownParser implements MarkdownParserInterface {
        public function parse(string $markdown): string {
            // Custom logic (e.g., pre-process Markdown)
            return (new Parsedown)->text($markdown);
        }
    }
    
  2. Post-Processing Hooks Decorate the parser to add logic after parsing:

    class AnalyticsMarkdownParser implements MarkdownParserInterface {
        private $parser;
    
        public function __construct(MarkdownParserInterface $parser) {
            $this->parser = $parser;
        }
    
        public function parse(string $markdown): string {
            $html = $this->parser->parse($markdown);
            // Inject analytics scripts
            return str_replace('</body>', '<script>...</script></body>', $html);
        }
    }
    
  3. Markdown Syntax Highlighting Combine with a library like Fidry\AliceDataBundle to generate Markdown with syntax highlighting:

    {% markdown_block post.code_with_highlighting %}
    ```php
    <?php
    echo "Hello, world!";
    

    {% endmarkdown_block %}

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.
craftcms/url-validator
directorytree/privacy-filter-classifier
directorytree/privacy-filter
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi
splash/scopes
splash/toolkit
testo/output-teamcity
testo/bridge-symfony