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

Htmldiff Bundle Laravel Package

caxy/htmldiff-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require caxy/htmldiff-bundle
    

    Register the bundle in config/bundles.php (Symfony 4+):

    return [
        // ...
        Caxy\HtmlDiffBundle\CaxyHtmlDiffBundle::class => ['all' => true],
    ];
    
  2. First Use Case: Generate a diff between two HTML strings in a controller:

    use Caxy\HtmlDiffBundle\HtmlDiff;
    
    class DiffController extends AbstractController {
        public function showDiff(string $oldHtml, string $newHtml): Response {
            $diff = new HtmlDiff();
            $result = $diff->diff($oldHtml, $newHtml);
            return $this->render('diff/show.html.twig', ['diff' => $result]);
        }
    }
    
  3. Twig Integration (if using Symfony): Add the Twig extension to config/packages/twig.yaml:

    twig:
        extensions:
            - Caxy\HtmlDiffBundle\Twig\HtmlDiffExtension
    

    Use in templates:

    {{ html_diff(oldHtml, newHtml) }}
    

Implementation Patterns

Core Workflows

  1. Generating Diffs:

    $diff = new \Caxy\HtmlDiffBundle\HtmlDiff();
    $diff->setOptions([
        'ignoreWhitespace' => true, // Ignore whitespace changes
        'ignoreCase' => true,      // Case-insensitive comparison
    ]);
    $result = $diff->diff($oldHtml, $newHtml);
    
    • Options: Leverage setOptions() for fine-grained control (e.g., ignoreAttributes, ignoreTags).
  2. Integration with Forms: Compare rendered form HTML for A/B testing or regression checks:

    $form1 = $this->createForm(FormType::class);
    $form2 = $this->createForm(ModifiedFormType::class);
    $diff = $htmlDiff->diff($form1->createView()->renderBlock('widget'), $form2->createView()->renderBlock('widget'));
    
  3. API Responses: Return diffs as JSON for frontend processing:

    return $this->json([
        'diff' => $htmlDiff->diff($oldHtml, $newHtml),
        'status' => 'generated',
    ]);
    
  4. Command-Line Usage: Create a console command for CLI diffs:

    use Symfony\Component\Console\Command\Command;
    use Symfony\Component\Console\Input\InputInterface;
    use Symfony\Component\Console\Output\OutputInterface;
    
    class GenerateDiffCommand extends Command {
        protected function execute(InputInterface $input, OutputInterface $output) {
            $oldHtml = file_get_contents($input->getArgument('old-file'));
            $newHtml = file_get_contents($input->getArgument('new-file'));
            $diff = $this->getHtmlDiff()->diff($oldHtml, $newHtml);
            $output->write($diff);
        }
    
        private function getHtmlDiff(): HtmlDiff {
            return new HtmlDiff();
        }
    }
    
  5. Event Listeners: Hook into kernel events to auto-diff HTML responses (e.g., for testing):

    use Symfony\Component\HttpKernel\Event\ResponseEvent;
    use Symfony\Component\HttpKernel\KernelEvents;
    
    class DiffListener {
        public function onKernelResponse(ResponseEvent $event) {
            if ($event->isMasterRequest()) {
                $diff = $this->getHtmlDiff()->diff(
                    $event->getRequest()->get('old_html', ''),
                    $event->getResponse()->getContent()
                );
                // Log or store diff for comparison
            }
        }
    }
    

Gotchas and Tips

Common Pitfalls

  1. Performance:

    • Large HTML: Diffing large HTML strings (e.g., full pages) can be slow. Use ignoreWhitespace and ignoreAttributes to optimize.
    • Memory Limits: For very large diffs, increase PHP’s memory_limit or process in chunks.
  2. False Positives:

    • Dynamic Content: Ignore dynamic elements (e.g., timestamps, CSRF tokens) by pre-processing HTML:
      $cleanHtml = preg_replace('/<div class="dynamic">.*?<\/div>/s', '', $html);
      
    • Whitespace Sensitivity: Enable ignoreWhitespace unless you need exact whitespace diffs.
  3. Configuration Quirks:

    • Bundle Auto-Registration: In Symfony 4+, the bundle auto-registers via config/bundles.php. No manual AppKernel edits are needed.
    • Twig Extension: Ensure the Twig extension is loaded after the default extensions in twig.yaml.
  4. Edge Cases:

    • Malformed HTML: The package may throw errors on invalid HTML. Sanitize input first:
      use Symfony\Component\DomCrawler\Crawler;
      $cleanHtml = (new Crawler($html))->html();
      
    • Encoding Issues: Ensure HTML strings are UTF-8 encoded to avoid diff artifacts.

Debugging Tips

  1. Log Diff Options:
    $diff = new HtmlDiff();
    $diff->setOptions(['debug' => true]); // Logs options and input
    
  2. Compare Raw Output: For debugging, compare raw HTML before diffing:
    file_put_contents('debug_old.html', $oldHtml);
    file_put_contents('debug_new.html', $newHtml);
    
  3. Disable Caching: Clear Symfony’s cache if diffs appear stale:
    php bin/console cache:clear
    

Extension Points

  1. Custom Diff Renderer: Override the default renderer for custom output formats:

    use Caxy\HtmlDiffBundle\Renderer\HtmlDiffRendererInterface;
    
    class CustomRenderer implements HtmlDiffRendererInterface {
        public function render(array $diff): string {
            // Custom logic (e.g., Markdown, JSON)
            return json_encode($diff);
        }
    }
    

    Register it in services.yaml:

    services:
        Caxy\HtmlDiffBundle\HtmlDiff:
            arguments:
                $renderer: '@custom.renderer'
    
  2. Pre/Post-Processing: Extend the HtmlDiff class to add hooks:

    class ExtendedHtmlDiff extends HtmlDiff {
        public function diff(string $oldHtml, string $newHtml): string {
            $oldHtml = $this->preProcess($oldHtml);
            $newHtml = $this->preProcess($newHtml);
            return parent::diff($oldHtml, $newHtml);
        }
    
        private function preProcess(string $html): string {
            // Strip non-critical elements
            return preg_replace('/<script>.*?<\/script>/s', '', $html);
        }
    }
    
  3. Symfony Messenger Integration: Use the Messenger component to queue diff jobs for async processing:

    use Symfony\Component\Messenger\MessageBusInterface;
    
    class DiffService {
        public function __construct(private MessageBusInterface $bus) {}
    
        public function queueDiff(string $oldHtml, string $newHtml) {
            $this->bus->dispatch(new DiffMessage($oldHtml, $newHtml));
        }
    }
    
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.
aimeos/prisma
besmartand-pro/php-quality-config
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor
spatie/laravel-javascript-views