Installation
composer require apacz/map-bundle
Register the bundle in config/bundles.php:
return [
// ...
Apacz\MapBundle\ApaczMapBundle::class => ['all' => true],
];
Configuration
Add Google Maps API key to config/packages/apacz_map.yaml:
apacz_map:
google_maps:
api_key: 'YOUR_GOOGLE_MAPS_API_KEY'
First Use Case Embed a basic map in a Twig template:
{{ render(controller('ApaczMapBundle:Default:map', {
'width': 600,
'height': 400,
'center': {lat: 48.8566, lng: 2.3522}, # Paris coordinates
'zoom': 12
})) }}
Dynamic Map Rendering
Use Twig’s render function to generate maps dynamically:
{% set mapOptions = {
'width': userMapWidth,
'height': userMapHeight,
'center': {lat: userLat, lng: userLng},
'markers': [{lat: 48.8566, lng: 2.3522, title: 'Paris'}]
} %}
{{ render(controller('ApaczMapBundle:Default:map', mapOptions)) }}
Reusable Components Extend the bundle’s controller to add custom logic:
// src/Controller/CustomMapController.php
namespace App\Controller;
use Apacz\MapBundle\Controller\DefaultController;
class CustomMapController extends DefaultController {
public function customMapAction($width, $height, $center) {
$this->addMarker($center); // Custom logic
return $this->mapAction($width, $height, $center);
}
}
Passing Complex Data Serialize arrays/objects to JSON for Twig:
// src/Controller/MapController.php
public function showMapAction(Request $request) {
$locations = [
['lat' => 40.7128, 'lng' => -74.0060, 'title' => 'New York'],
['lat' => 34.0522, 'lng' => -118.2437, 'title' => 'Los Angeles']
];
return $this->render('map/map.html.twig', [
'markers' => json_encode($locations),
'center' => json_encode(['lat' => 37.7749, 'lng' => -122.4194])
]);
}
Event-Driven Maps
Use JavaScript events (e.g., click) to trigger Symfony actions:
<script>
document.addEventListener('DOMContentLoaded', function() {
google.maps.event.addListener(map, 'click', function(event) {
fetch('/map/handle-click', {
method: 'POST',
body: JSON.stringify({lat: event.latLng.lat(), lng: event.latLng.lng()})
});
});
});
</script>
.env:
GOOGLE_MAPS_API_KEY=your_key_here
Load it in config/packages/apacz_map.yaml:
apacz_map:
google_maps:
api_key: '%env(GOOGLE_MAPS_API_KEY)%'
API Key Restrictions
Twig render Caching
render function caches routes by default. Clear cache after changes:
php bin/console cache:clear
Deprecated Symfony 3
Console Errors
Check browser console for Google Maps API errors (e.g., InvalidKey). Verify the key is correct and not revoked.
Lat/Lng Validation
Ensure coordinates are valid (e.g., lat between -90 and 90). Use:
if ($lat < -90 || $lat > 90) {
throw new \InvalidArgumentException('Invalid latitude');
}
Custom Markers
Override the Twig template (templates/ApaczMapBundle/Default/map.html.twig) to add custom icons:
{# Add this inside the map initialization script #}
var marker = new google.maps.Marker({
position: {lat: {{ lat }}, lng: {{ lng }}},
icon: '/path/to/custom-icon.png',
title: '{{ title }}'
});
Polyfills for Older Browsers
Include a polyfill for fetch or Promise if supporting legacy browsers:
<script src="https://cdn.jsdelivr.net/npm/promise-polyfill@8/dist/polyfill.min.js"></script>
Server-Side Geocoding Use Symfony’s HTTP client to fetch geocoding data:
$client = new Client();
$response = $client->get('https://maps.googleapis.com/maps/api/geocode/json', [
'query' => [
'address' => '1600 Amphitheatre Parkway, Mountain View',
'key' => $this->container->getParameter('google_maps.api_key')
]
]);
$data = json_decode($response->getContent(), true);
Lazy-Load Maps Load the Google Maps script dynamically to improve page load:
<script>
function initMap() {
// Map initialization logic
}
function loadMapScript() {
var script = document.createElement('script');
script.src = `https://maps.googleapis.com/maps/api/js?key=${apiKey}&callback=initMap`;
document.body.appendChild(script);
}
// Load after DOM is ready
document.addEventListener('DOMContentLoaded', loadMapScript);
</script>
Static API Key
For production, use a static key (not from .env) to avoid exposing it in source maps.
How can I help you explore Laravel packages today?