geekyhouse/external-tracking-bundle
A Symfony bundle for integrating external tracking and analytics services into your application. It provides configuration and service wiring for third-party tracking providers, making it easy to drop into existing Symfony projects with minimal setup.
Install the bundle (Symfony 2.x only):
composer require geekyhouse/external-tracking-bundle
Register it in app/AppKernel.php — Symfony2 bundles are not auto-discovered:
public function registerBundles()
{
$bundles = [
// ...
new GeekyHouse\ExternalTrackingBundle\GeekyHouseExternalTrackingBundle(),
];
return $bundles;
}
First place to look: the bundle's README.md, DependencyInjection/Configuration.php, and Resources/config/ services. The bundle is small and low-traffic, so the source is the documentation — the Configuration.php is where the exact YAML node names live, and the Twig extension (usually under Twig/) tells you the helper name to call.
Minimal config (typical shape — verify keys against Configuration.php, since the bundle predates strict naming conventions):
# app/config/config.yml
geeky_house_external_tracking:
trackers:
google_analytics:
parameters:
tracking_id: "%google_analytics_id%"
First use case: define a tracker once in config, then render it in app/Resources/views/base.html.twig inside a block so every page gets the snippet without repeating it:
{% block external_tracking %}
{{ external_tracking('google_analytics') }}
{% endblock %}
That config-to-layout flow is the entire reason to use the bundle: it centralizes IDs and snippets that would otherwise be pasted into dozens of templates.
Config-driven tracker definitions. Rather than hardcoding a UA-XXXX in Twig, define each tracker as a named entry in config and reference it by name in templates. This lets you swap IDs per environment (dev/staging/prod) using parameters.yml and config_dev.yml overrides, which is the most practical day-to-day win.
Environment overrides. In config_dev.yml, point tracker IDs at a test property, or remove trackers you don't want firing in local dev:
# config_dev.yml
geeky_house_external_tracking:
trackers:
google_analytics:
parameters:
tracking_id: "UA-DEV-1"
Layered rendering in Twig. Render trackers in a {% block %} on the base layout and let child templates extend or empty the block where needed (e.g., a checkout confirmation page adding a conversion pixel):
{% block external_tracking %}
{{ parent() }}
{{ external_tracking('facebook_pixel', { value: order.total }) }}
{% endblock %}
Pass per-request context. For conversion/ecommerce pixels, pass runtime values (order value, currency, user id) as a second argument rather than baking them into a global. If the bundle exposes a service, resolve it in a controller and hand the values to the template — keeps business logic out of Twig.
Consistent placement. Standardize where snippets go: head trackers before </head>, conversion pixels before </body>. Put both in separate blocks on the base layout so designers/devs don't fight over placement later.
Extending with custom trackers. If the bundle ships a base template per provider, add your own Twig template under your app's Resources/views/ and point a config entry at it. That's usually the intended extension point for providers the bundle doesn't cover (TikTok, Pinterest, etc.).
Symfony2 era (roughly Symfony 2.3–2.8). It will not work on Symfony 3+ without porting the DependencyInjection and Twig extension to the newer signatures. Do not install it on a modern Symfony app.Twig\Extension instead.<script> tags, so the rendering helper likely returns Twig_Markup/raw. If you build your own wrapper, remember |raw — otherwise Symfony escapes the snippet to text and nothing fires.app/console cache:clear --env=prod) and inspect app/cache/<env>/appDevProjectContainer.xml to confirm your tracker nodes actually compiled.parameters.yml; do not pass raw email or names into pixel templates. Sanitize any dynamic values you hand to external_tracking(...).Configuration.php; template not rendered → check the Twig helper name and that the block is actually reached (add a literal <p> next to it); script present in HTML but not firing → check browser network tab and ad-blockers.How can I help you explore Laravel packages today?