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

Parsedown Bundle Laravel Package

colibo/parsedown-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require colibo/parsedown-bundle:dev-master
    

    Enable the bundle in config/bundles.php (Symfony 4+) or AppKernel.php (Symfony 3):

    // config/bundles.php
    Colibo\ParsedownBundle\ColiboParsedownBundle::class => ['all' => true],
    
  2. First Use Case:

    • Twig: Parse a variable in a template:
      {{ markdownContent|md }}  {# Standard Parsedown #}
      {{ markdownContent|mde }} {# Parsedown Extra #}
      
    • PHP: Inject the service via dependency injection:
      use Symfony\Component\DependencyInjection\ContainerInterface;
      
      public function __construct(private ContainerInterface $container) {}
      
      public function renderMarkdown(string $content): string
      {
          return $this->container->get('parsedown')->text($content);
      }
      

Implementation Patterns

Common Workflows

  1. Dynamic Parsing in Controllers:

    use Symfony\Component\HttpFoundation\Response;
    
    public function showMarkdown(ContainerInterface $container, string $content): Response
    {
        $parsed = $container->get('parsedown_extra')->text($content);
        return new Response($parsed);
    }
    
  2. Twig Extensions for Custom Logic: Extend the bundle’s Twig filters by creating a custom extension:

    // src/Twig/AppExtension.php
    namespace App\Twig;
    
    use Twig\Extension\AbstractExtension;
    use Twig\TwigFilter;
    
    class AppExtension extends AbstractExtension
    {
        public function getFilters(): array
        {
            return [
                new TwigFilter('custom_md', [$this, 'customMarkdownFilter']),
            ];
        }
    
        public function customMarkdownFilter(string $content): string
        {
            // Custom logic (e.g., pre-process content)
            return $this->container->get('parsedown_extra')->text($content);
        }
    }
    

    Register the extension in services.yaml:

    services:
        App\Twig\AppExtension:
            tags: ['twig.extension']
    
  3. Reusable Services in Forms: Use the parsers to sanitize or pre-process user input (e.g., in form types):

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('description', TextType::class, [
            'attr' => ['class' => 'markdown-input'],
            'mapped' => false,
        ]);
    }
    
    // In a controller or subscriber:
    $form->get('description')->setData(
        $container->get('parsedown_extra')->text($rawInput)
    );
    
  4. API Responses: Parse markdown in API responses for consistency:

    return $this->json([
        'content' => $container->get('parsedown')->text($markdown),
    ]);
    

Gotchas and Tips

Pitfalls

  1. Symfony 4+ Compatibility:

    • The bundle is designed for Symfony 3. For Symfony 4+, ensure config/bundles.php is used instead of AppKernel.php.
    • Fix: Use dev-master branch or fork the repo to update for Symfony 4+ autowiring.
  2. Twig Filter Overrides:

    • If you override the md or mde filters globally, ensure the new filter accepts the same input/output contract:
      {{ some_var|md }}  {# Expects string, returns HTML string #}
      
    • Tip: Use {{ some_var|raw|md }} if you need to bypass Twig auto-escaping before parsing.
  3. Performance with Large Content:

    • Parsedown-extra is slower than standard Parsedown due to additional features (tables, definitions, etc.).
    • Tip: Cache parsed results if rendering the same markdown repeatedly:
      $cacheKey = md5($content);
      $parsed = $cache->get($cacheKey, function() use ($content) {
          return $container->get('parsedown_extra')->text($content);
      });
      
  4. Security:

    • Never parse untrusted markdown in user-facing contexts (XSS risk). Use htmlspecialchars() or a whitelist if needed.
    • Tip: Sanitize output with HTML Purifier after parsing:
      use HTMLPurifier;
      
      $config = HTMLPurifier_Config::createDefault();
      $purifier = new HTMLPurifier($config);
      $safeHtml = $purifier->purify($parsedown->text($content));
      

Debugging

  1. Check Parser Output:

    • Log raw markdown and parsed HTML to debug issues:
      file_put_contents(
          'debug/markdown.html',
          $container->get('parsedown_extra')->text($content)
      );
      
  2. Twig Debugging:

    • Enable Twig’s debug mode in config/packages/twig.yaml:
      twig:
          debug: '%kernel.debug%'
          strict_variables: '%kernel.debug%'
      
    • Use {{ dump(_context) }} to inspect variables in templates.
  3. Service Not Found:

    • Ensure the bundle is enabled and dependencies (erusev/parsedown, erusev/parsedown-extra) are installed:
      composer require erusev/parsedown erusev/parsedown-extra
      

Extension Points

  1. Custom Parsedown Extensions:

    • Extend Parsedown’s functionality by subclassing and overriding methods:
      use Parsedown;
      
      class CustomParsedown extends Parsedown
      {
          protected $MarkdownExtra = true;
      
          public function __construct()
          {
              parent::__construct();
              // Add custom rules
              $this->setBreaksEnabled(true);
          }
      }
      
    • Register the custom service in services.yaml:
      services:
          custom.parsedown:
              class: App\Parsedown\CustomParsedown
              tags: ['parsedown']
      
  2. Hook into Parsedown Events:

    • Use Parsedown’s setMarkupEscaped() or setUrlScheme() for global config:
      $parsedown = $container->get('parsedown');
      $parsedown->setUrlScheme('https');
      
  3. Integrate with CMS:

    • Use the bundle to parse markdown stored in Doctrine entities:
      // Entity
      #[ORM\Column(type: 'text')]
      private string $markdownContent;
      
      // Repository/Service
      $htmlContent = $container->get('parsedown_extra')->text($entity->markdownContent);
      
  4. CLI Usage:

    • Parse markdown in console commands:
      use Symfony\Component\Console\Command\Command;
      use Symfony\Component\Console\Input\InputInterface;
      use Symfony\Component\Console\Output\OutputInterface;
      
      class MarkdownCommand extends Command
      {
          protected static $defaultName = 'app:parse-markdown';
      
          protected function execute(InputInterface $input, OutputInterface $output, ContainerInterface $container)
          {
              $parsed = $container->get('parsedown')->text(file_get_contents('input.md'));
              file_put_contents('output.html', $parsed);
              $output->writeln('Markdown parsed!');
          }
      }
      
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.
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
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