24hoursmedia/twig-extension-bundle
composer require 24hoursmedia/twig-extension-bundle
config/bundles.php (Symfony 4+) or AppKernel.php (Symfony 3):
// Symfony 4+
T4\Bundle\TwigExtensionBundle\T4TwigExtensionBundle::class => ['all' => true],
// Symfony 3
new T4\Bundle\TwigExtensionBundle\T4TwigExtensionBundle(),
{{ 'https://example.com'|ga_link('source', 'campaign') }}
Output: https://example.com?utm_source=source&utm_campaign=campaignDynamic UTM Parameters: Add campaign tracking to links dynamically in Twig:
<a href="{{ path('home')|ga_link('newsletter', 'summer2024') }}">Visit Home</a>
Custom Filters:
Extend the ga_link filter for custom UTM keys:
{{ 'https://example.com'|ga_link('custom_key', 'value', {'utm_medium': 'email'}) }}
Output: https://example.com?utm_source=custom_key&utm_campaign=value&utm_medium=email
Integration with Routing:
Combine with Symfony’s path() function for clean URLs:
{{ path('product', {'id': 123})|ga_link('product_page', 'purchase') }}
Form Validation in Twig: Validate data directly in templates (e.g., for AJAX forms):
{% set errors = 'user.email'|validate %}
{% if errors %}
<ul>
{% for error in errors %}
<li>{{ error.message }}</li>
{% endfor %}
</ul>
{% endif %}
Reusable Validation Logic: Create Twig macros for common validation patterns:
{% macro validateField(field, errors) %}
<div class="form-group {% if errors|length > 0 %}has-error{% endif %}">
<label>{{ field.label }}</label>
<input type="text" name="{{ field.name }}">
{% if errors %}
<div class="help-block">
{% for error in errors %}
{{ error.message }}<br>
{% endfor %}
</div>
{% endif %}
</div>
{% endmacro %}
Usage:
{% set emailErrors = 'user.email'|validate %}
{{ _self.validateField(userEmailField, emailErrors) }}
Custom Validation Constraints:
Pass Symfony Constraint objects to the filter:
{% set customConstraint = App\Validator\Constraints\CustomConstraint::class %}
{% set errors = 'user.input'|validate(customConstraint) %}
validator filter in Twig to show errors without full form submission (e.g., for SPA-like behavior).$twig->addExtension(new \T4\Bundle\TwigExtensionBundle\Twig\Extension\GaExtension());
$twig->addExtension(new \T4\Bundle\TwigExtensionBundle\Twig\Extension\ValidatorExtension());
Bundle Registration:
config/bundles.php will silently fail.AppKernel.php is updated and the bundle is loaded after the FrameworkBundle.ContainerAware services or debug with php bin/console debug:container | grep twig.extension.Validator Extension:
ValidatorInterface instance. If not autowired, configure it manually:
# config/services.yaml
T4\Bundle\TwigExtensionBundle\Twig\Extension\ValidatorExtension:
arguments:
- '@validator'
Google Analytics:
ga_link filter does not encode URLs. Manually encode if needed:
{{ ('https://example.com/search?q=' ~ query)|e('UTF-8')|ga_link('search', 'query') }}
merge filter to avoid conflicts:
{{ ('https://example.com?utm_source=old'|split('&'))|merge({'utm_campaign': 'new'})|join('&') }}
Extension Availability: Check if extensions are registered in Twig:
{{ dump(_twig.extensions) }}
Look for T4\Bundle\TwigExtensionBundle\Twig\Extension\*.
Validator Errors: If validation fails silently, enable Symfony’s validator debug mode:
# config/packages/validator.yaml
validator:
debug: true
Twig Error Suppression:
Wrap extensions in try-catch blocks to avoid template crashes:
{% try %}
{{ 'invalid.data'|validate }}
{% catch Exception %}
<p>Validation failed gracefully.</p>
{% endtry %}
Custom Extensions: Extend the bundle by creating your own Twig extensions and register them alongside:
// src/Twig/AppExtension.php
class AppExtension extends \Twig\Extension\AbstractExtension
{
public function getFilters()
{
return [
new \Twig\TwigFilter('custom_filter', [$this, 'customFilter']),
];
}
}
Register in config/services.yaml:
Twig\Extension\AppExtension: ~
Configuration:
Override default UTM parameters in config/packages/t4_twig_extension.yaml:
t4_twig_extension:
ga:
default_parameters:
utm_medium: 'website'
utm_content: 'twig-generated'
Performance: Cache compiled Twig templates with the extensions enabled to avoid reprocessing:
# config/packages/twig.yaml
twig:
cache: '%kernel.cache_dir%/twig'
Documentation: Refer to the GA Extension Docs and Validator Extension Docs for advanced use cases (e.g., custom validators or UTM parameter overrides).
How can I help you explore Laravel packages today?