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

Formatter Bundle Laravel Package

sonata-project/formatter-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require sonata-project/formatter-bundle
    

    Enable the bundle in config/bundles.php:

    return [
        // ...
        Sonata\FormatterBundle\SonataFormatterBundle::class => ['all' => true],
    ];
    
  2. Basic Usage: Register a formatter in config/packages/sonata_formatter.yaml:

    sonata_formatter:
        formats:
            - { name: 'default', extension: 'html', mime_type: 'text/html' }
            - { name: 'text', extension: 'txt', mime_type: 'text/plain' }
    
  3. First Use Case: Inject Sonata\FormatterBundle\Formatter\FormatterInterface into a service/controller and use it to format content:

    use Sonata\FormatterBundle\Formatter\FormatterInterface;
    
    public function __construct(private FormatterInterface $formatter) {}
    
    public function renderContent(string $content, string $format = 'default'): string
    {
        return $this->formatter->format($content, $format);
    }
    

Key Files to Review

  • config/packages/sonata_formatter.yaml (default config)
  • src/Formatter/FormatterInterface.php (core interface)
  • src/DependencyInjection/Configuration.php (customization points)

Implementation Patterns

Common Workflows

  1. Dynamic Format Handling: Use the format() method to dynamically apply formatting based on user input or request parameters:

    $formatted = $this->formatter->format($rawContent, $request->query->get('format', 'default'));
    
  2. Twig Integration: Extend Twig with custom filters for seamless template integration:

    {{ content|format('default') }}
    

    Register the Twig extension in config/packages/twig.yaml:

    twig:
        globals:
            formatter: '@sonata.formatter.formatter'
    
  3. Event-Driven Formatting: Listen to sonata.formatter.format events to pre/post-process content:

    use Sonata\FormatterBundle\Event\FormatEvent;
    
    public function onFormat(FormatEvent $event)
    {
        if ($event->getFormat() === 'text') {
            $event->setContent(strtoupper($event->getContent()));
        }
    }
    
  4. Custom Formatters: Implement Sonata\FormatterBundle\Formatter\FormatterInterface for bespoke logic:

    class CustomFormatter implements FormatterInterface
    {
        public function format($content, $format): string
        {
            return str_replace('foo', 'bar', $content);
        }
    }
    

    Register it in services.yaml:

    services:
        App\Formatter\CustomFormatter:
            tags: [sonata.formatter]
    

Integration Tips

  • Doctrine ORM: Use the Sonata\FormatterBundle\Doctrine\Types\TextType for automatic formatting in database fields.
  • APIs: Return formatted content in API responses with Symfony\Component\HttpFoundation\Response:
    return new Response($this->formatter->format($content, 'text'), 200, ['Content-Type' => 'text/plain']);
    
  • Admin Panels: Integrate with SonataAdminBundle for rich-text editing:
    sonata_admin:
        types:
            text:
                formatter:
                    format: 'default'
    

Gotchas and Tips

Pitfalls

  1. Format Mismatch:

    • Issue: Forgetting to define a format in sonata_formatter.formats causes FormatNotFoundException.
    • Fix: Validate formats exist before use or handle exceptions:
      try {
          $formatted = $this->formatter->format($content, 'nonexistent');
      } catch (FormatNotFoundException $e) {
          return $this->formatter->format($content, 'default');
      }
      
  2. Circular Dependencies:

    • Issue: Over-eager event listeners may cause infinite loops if they trigger formatting recursively.
    • Fix: Add guards or use EventDispatcher::DISPATCHER_PRIORITY_LOW for listeners.
  3. Performance:

    • Issue: Heavy formatters (e.g., Markdown) can slow down rendering.
    • Fix: Cache formatted content or use lazy-loading:
      $this->formatter->format($content, 'default', ['cache' => true]);
      

Debugging

  • Log Formatting: Enable debug mode to log format operations:

    sonata_formatter:
        debug: true
    

    Check logs for sonata.formatter entries.

  • Content Dumping: Use var_dump() or dd() to inspect raw vs. formatted content:

    $raw = $entity->getContent();
    $formatted = $this->formatter->format($raw, 'default');
    dump($raw, $formatted);
    

Configuration Quirks

  1. Default Format:

    • The default format is auto-configured but may conflict with custom formats. Explicitly define it:
      sonata_formatter:
          formats:
              default:
                  name: 'default'
                  extension: 'html'
                  mime_type: 'text/html'
      
  2. Mime Type Overrides:

    • Mime types must match browser expectations (e.g., text/html for HTML). Use fileinfo to auto-detect:
      sonata_formatter:
          mime_types:
              'text/html': ['html', 'htm']
      
  3. Extension Points:

    • Custom Formatters: Tag services with sonata.formatter to auto-register.
    • Event Subscribers: Use sonata.formatter.event_subscriber for priority control.

Pro Tips

  • Batch Processing: Use Sonata\FormatterBundle\Formatter\FormatterPool to format multiple contents at once:

    $pool = $this->container->get('sonata.formatter.pool');
    $results = $pool->formatAll([$content1, $content2], 'text');
    
  • Security: Sanitize user-provided formats to prevent injection:

    $allowedFormats = ['default', 'text'];
    $format = in_array($request->get('format'), $allowedFormats)
        ? $request->get('format')
        : 'default';
    
  • Testing: Mock FormatterInterface in tests:

    $formatter = $this->createMock(FormatterInterface::class);
    $formatter->method('format')->willReturn('formatted!');
    
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.
comsave/common
alecsammon/php-raml-parser
chrome-php/wrench
lendable/composer-license-checker
typhoon/reflection
mesilov/moneyphp-percentage
mike42/gfx-php
bookdown/themes
aura/view
aura/html
aura/cli
povils/phpmnd
nayjest/manipulator
omnipay/tests
psr-mock/http-message-implementation
psr-mock/http-factory-implementation
psr-mock/http-client-implementation
voku/email-check
voku/urlify
rtheunissen/guzzle-log-middleware