Installation:
composer require aldaflux/fine-diff-bundle
Add the bundle to app/AppKernel.php:
new AlDaFlux\FineDiffBundle\AlDaFluxPHPFineDiffBundle(),
First Use Case: Compare two strings in a Twig template:
{{ renderDiff('Hello world', 'Hello Laravel') }}
Outputs a side-by-side diff highlighting changes.
renderDiff() and renderHtmlTextDiff() in the Usage section.config.yml for granularity settings (character, word, sentence, paragraph).String Comparison:
Use renderDiff() for plain text (e.g., user-generated content, logs, or API responses).
{{ renderDiff(oldText, newText, 'word') }} {# Granularity: word-level diff #}
HTML-Aware Diffs:
Preprocess HTML with strip_tags() before using renderHtmlTextDiff():
{{ renderHtmlTextDiff(strip_tags(oldHtml), strip_tags(newHtml), 'sentence') }}
Dynamic Granularity: Pass granularity as a third argument to control sensitivity:
{% set granularity = 'paragraph' if isLongText else 'character' %}
{{ renderDiff(text1, text2, granularity) }}
Symfony Forms: Display diffs in form validation errors:
{% for error in form.errors %}
{{ renderDiff(oldValue, error.message) }}
{% endfor %}
API Responses: Compare request/response payloads in debug tools:
$diff = $this->get('aldaflux_fine_diff')->renderDiff($oldPayload, $newPayload);
Event Listeners: Log diffs for auditing:
public function onContentUpdate(ContentEvent $event) {
$diff = $this->get('aldaflux_fine_diff')->renderDiff(
$event->getOldContent(),
$event->getNewContent(),
'sentence'
);
$this->logger->info('Content changed:', ['diff' => $diff]);
}
Admin Panels: Highlight changes in CMS content revisions (e.g., SonataAdmin, EasyAdmin).
HTML Handling:
renderHtmlTextDiff() requires strip_tags() preprocessing. Failing to strip tags may break rendering.{{ renderHtmlTextDiff(oldHtml, newHtml) }} {# ❌ Will fail #}
Performance:
character level) are slower for large texts (>10KB). Use paragraph for performance-critical paths.False Positives:
'word') may flag minor typos as changes. Adjust granularity based on use case.Empty Output:
{{ dump(oldValue) }}, {{ dump(newValue) }}
Styling Issues:
.diff-add { background: #ddffdd; }
.diff-del { background: #ffdddd; }
Custom Granularity: Extend the bundle by adding a custom granularity strategy:
// src/AlDaFlux/FineDiffBundle/DependencyInjection/Configuration.php
$builder->append($builder->createArrayNode('custom_granularities'))
->addPrototype('strategy')
->children()
->scalarNode('class')->isRequired()->end()
->end();
Twig Extensions: Override Twig functions in your own bundle:
// src/Acme/MyBundle/Twig/MyExtension.php
public function getFunctions() {
return [
new \Twig\TwigFunction('customDiff', [$this, 'renderDiff']),
];
}
Service Configuration:
Inject the fine_diff service directly for programmatic use:
$diffRenderer = $container->get('aldaflux_fine_diff');
$diff = $diffRenderer->renderDiff($str1, $str2);
Localization: Translate diff labels (e.g., "added", "removed") via Symfony’s translation system:
{{ renderDiff(oldText, newText, 'word', {'added': '✅ Added', 'removed': '❌ Removed'}) }}
Inline Edits: Use diffs to power collaborative editing (e.g., Google Docs-style):
<div class="editor-diff">
{{ renderDiff(currentDraft, latestVersion) }}
</div>
Testing: Mock the service in PHPUnit:
$this->container->set('aldaflux_fine_diff', $this->createMock(FineDiff::class));
How can I help you explore Laravel packages today?