Google Maps with Flux/Fluidcontent

Implementation of Google Maps with one or more markers. When having multiple markers, the bounds are fit to them.

A marker can have a title (is shown as marker tooltipp and in info window), a text (is shown in info window), an icon (standard, chooseable or uploadable).

More configuration options are: Zoom level, map center, map type

Description Google Maps with Flux/Fluidcontent (TYPO3 CMS)
Author SventB
Creation date 2015-10-29T16:27:15.000Z
Extensions
  1. FluidTYPO3.Flux
  2. FluidTYPO3.Fluidcontent
  3. FluidTYPO3.Vhs
Tags
  1. Content
  2. ViewHelpers
Files
  1. README.md
  2. de.locallang.xlf
  3. GoogleMaps.html
  4. JavaScriptEscapeViewHelper.php
  5. locallang.xlf

Google Maps with Flux/Fluidcontent for TYPO3 CMS

Implementation of a Google Maps content element with one or more markers. When having multiple markers, the bounds are fit to them.

A marker can have a title (is shown as marker tooltipp and in info window), a text (is shown in info window), an icon (standard, chooseable or uploadable).

More configuration options are: Zoom level, map center, map type

Usage

  1. Create your own extension
  2. Put file GoogleMaps.html in EXT:yourExt/Resources/Private/Templates/Content/GoogleMaps.html
  3. Adapt this file to your environment, for example "xmlns:base", "MRM", "t3base", "f:comment"
  4. Put file JavaScriptEscapeViewHelper.php in EXT:yourExt/Classes/ViewHelpers/Format/JavaScriptEscapeViewHelper.php
  5. Put file locallang.xlf in EXT:yourExt/Resources/Private/Language/locallang.xlf
  6. Put file de.locallang.xlf in EXT:yourExt/Resources/Private/Language/de.locallang.xlf
  7. Tell me how I can improve it
view raw README.md hosted with ❤ by GitHub
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<xliff version="1.0">
<file source-language="en" target-language="de" datatype="plaintext" original="messages" product-name="t3base">
<header/>
<body>
<trans-unit id="flux.googlemaps">
<target>Google Maps</target>
</trans-unit>
<trans-unit id="flux.googlemaps.description">
<target>Eine einfache Karte mit Google Maps</target>
</trans-unit>
<trans-unit id="flux.googlemaps.fields.fitBounds">
<target>Kartenausschnitt an Adressen anpassen?</target>
</trans-unit>
<trans-unit id="flux.googlemaps.fields.address">
<target>Adresse für Karten-Zentrum</target>
</trans-unit>
<trans-unit id="flux.googlemaps.fields.lng">
<target>Längengrad für Karten-Zentrum (wird der Adresse bevorzugt)</target>
</trans-unit>
<trans-unit id="flux.googlemaps.fields.lat">
<target>Breitengrad für Karten-Zentrum (wird der Adresse bevorzugt)</target>
</trans-unit>
<trans-unit id="flux.googlemaps.fields.zoom">
<target>Zoom (1 = sehr weit, 21 = sehr nah)</target>
</trans-unit>
<trans-unit id="flux.googlemaps.fields.mapType">
<target>Kartentyp</target>
</trans-unit>
<trans-unit id="flux.googlemaps.sections.markers">
<target>Adressen</target>
</trans-unit>
<trans-unit id="flux.googlemaps.objects.marker">
<target>Adresse</target>
</trans-unit>
<trans-unit id="flux.googlemaps.objects.marker.address">
<target>Adresse</target>
</trans-unit>
<trans-unit id="flux.googlemaps.objects.marker.lng">
<target>Längengrad (wird der Adresse bevorzugt)</target>
</trans-unit>
<trans-unit id="flux.googlemaps.objects.marker.lat">
<target>Breitengrad (wird der Adresse bevorzugt)</target>
</trans-unit>
<trans-unit id="flux.googlemaps.objects.marker.icon">
<target>Pin Icon</target>
</trans-unit>
<trans-unit id="flux.googlemaps.objects.marker.iconFile">
<target>Pin Icon hochladen</target>
</trans-unit>
<trans-unit id="flux.googlemaps.objects.marker.title">
<target>Titel (Tooltip für Pin und Titel des Infofensters)</target>
</trans-unit>
<trans-unit id="flux.googlemaps.objects.marker.info">
<target>Text im Infofenster</target>
</trans-unit>
<trans-unit id="flux.googlemaps.objects.marker.showInfo">
<target>Infofenster dieser Adresse anzeigen?</target>
</trans-unit>
</body>
</file>
</xliff>
<div xmlns="http://www.w3.org/1999/xhtml" lang="en"
xmlns:v="http://typo3.org/ns/FluidTYPO3/Vhs/ViewHelpers"
xmlns:flux="http://typo3.org/ns/FluidTYPO3/Flux/ViewHelpers"
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers"
xmlns:base="http://typo3.org/ns/MRM/T3base/ViewHelpers">
<f:layout name="Content"/>
<f:section name="Configuration">
<flux:form id="googlemaps" wizardTab="T3Base_example" options="{icon: 'EXT:t3base_example/Resources/Public/Icons/Content/GoogleMaps.png'}">
<flux:field.checkbox name="fitBounds" default="1" requestUpdate="true"/>
<flux:field.select name="mapType" items="ROADMAP, SATELLITE, TERRAIN, HYBRID"/>
<f:if condition="{fitBounds}">
<f:else>
<flux:field.text name="address" rows="3"/>
<flux:field.input name="lng"/>
<flux:field.input name="lat"/>
<flux:field.input name="zoom" default="15" size="1" eval="int,trim"/>
<f:comment>@TODO: Enable slider and field with minimum/maximum when TYPO3 bug is fixed
<flux:field.input name="zoom" default="15" size="1" minimum="1" maximum="21" eval="int,trim">
<flux:wizard.slider hideParent="true" step="1" width="100"/>
</flux:field.input>
</f:comment>
</f:else>
</f:if>
<flux:form.section name="markers">
<flux:form.object name="marker">
<flux:field.text name="address" rows="3"/>
<f:comment>
@TODO: use displayCond and provide checkbox for switching between address input and
latitude/longitude fields:
<flux:field.checkbox name="provideLatLngInsteadOfAddress"/>
But it seems a displayCond like this (on this level / in a flux:form.object) isn't supported:
<flux:field.input name="lng" displayCond="FIELD:markers.marker.provideLatLngInsteadOfAddress:REQ:true"/>
</f:comment>
<flux:field.input name="lng"/>
<flux:field.input name="lat"/>
<flux:field.select name="icon"
items="{
0: 'Standard',
parking_lot_maps: 'Parking',
library_maps: 'Library',
school_maps: 'School',
info-i_maps: 'Info',
mrm: 'MRM'
}"/>
<flux:field.file
name="iconFile"
showThumbnails="1"
allowed="jpg,png,gif"
maxItems="1"
maxSize="20"
size="1"
/>
<flux:field.input name="title"/>
<flux:field.text name="info" rows="3"/>
<flux:field.checkbox name="showInfo"/>
</flux:form.object>
</flux:form.section>
</flux:form>
</f:section>
<f:section name="Preview">
<f:be.container includeCssFiles="{0: 'typo3conf/ext/t3base/Resources/Public/Css/Backend/Preview.css'}">
Markers:
<ol>
<f:for each="{markers}" as="marker">
<v:variable.set name="marker" value="{marker.marker}"/>
<li>
{marker.title}
<f:if condition="{marker.title}">
<f:if condition="{marker.address}">//</f:if>
</f:if>
{marker.address}
</li>
</f:for>
</ol>
</f:be.container>
</f:section>
<f:section name="Main">
<script src="https://maps.googleapis.com/maps/api/js"></script>
<script>
function initialize() {
<f:if condition="{fitBounds}">
<f:then>
var center = new google.maps.LatLng(0, 0);
</f:then>
<f:else>
<f:if condition="{0: lng, 1: lat} == {0: '', 1: ''}">
<f:then>
<v:variable.set name="geo" value="{base:geo.lngLat(address: '{address}')}" />
</f:then>
<f:else>
<v:variable.set name="geo" value="{lng: marker.lng, lat: marker.lat}" />
</f:else>
</f:if>
var center = new google.maps.LatLng({geo.lat}, {geo.lng});
</f:else>
</f:if>
var icons = new Array();
icons['parking_lot_maps'] = 'https://maps.google.com/mapfiles/kml/shapes/parking_lot_maps.png';
icons['library_maps'] = 'https://maps.google.com/mapfiles/kml/shapes/library_maps.png';
icons['schools_maps'] = 'https://maps.google.com/mapfiles/kml/shapes/schools_maps.png';
icons['info-i_maps'] = 'https://maps.google.com/mapfiles/kml/shapes/info-i_maps.png';
icons['mrm'] = '<f:uri.image src="EXT:t3b_example/Resources/Public/Icons/favicon.ico" />';
var zoom = {zoom};
var mapType = google.maps.MapTypeId.{mapType};
var mapCanvas = document.getElementById('map');
var mapOptions = {
center: center,
zoom: zoom,
streetViewControl: false,
scrollwheel: false,
mapTypeId: mapType
}
var map = new google.maps.Map(mapCanvas, mapOptions);
var infowindow = new google.maps.InfoWindow;
google.maps.event.addListener(map, 'click', function(){
infoWindow.close();
});
var bounds = new google.maps.LatLngBounds();
<f:for each="{markers}" as="marker">
<v:variable.set name="marker" value="{marker.marker}" />
<f:if condition="{0: marker.lng, 1: marker.lat} == {0: '', 1: ''}">
<f:then>
<v:variable.set name="geo" value="{base:geo.lngLat(address: '{marker.address}')}" />
</f:then>
<f:else>
<v:variable.set name="geo" value="{lng: marker.lng, lat: marker.lat}" />
</f:else>
</f:if>
var position = new google.maps.LatLng({geo.lat}, {geo.lng});
var title = '<base:format.javaScriptEscape><f:format.nl2br>{marker.title}</f:format.nl2br></base:format.javaScriptEscape>';
var info = '<base:format.javaScriptEscape><f:format.nl2br>{marker.info}</f:format.nl2br></base:format.javaScriptEscape>';
<f:if condition="{marker.iconFile}">
<f:then>
<f:comment>
@TODO: use v:uri.image when bug (https://github.com/FluidTYPO3/vhs/issues/936) is fixed
<v:uri.image src="{marker.iconFile}" relative="false" />
</f:comment>
var icon = '{v:site.url()}{marker.iconFile}';
</f:then>
<f:else>
<f:if condition="{marker.icon}">
<f:then>
var icon = icons['{marker.icon}'];
</f:then>
<f:else>
var icon = '';
</f:else>
</f:if>
</f:else>
</f:if>
var marker = new google.maps.Marker({
position: position,
map: map,
icon: icon,
content: info,
title: title
});
bounds.extend(position);
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent('<h3>' + this.title + '</h3><p>' + this.content + '</p>');
infowindow.open(map, this);
});
<f:if condition="{marker.showInfo}">
google.maps.event.addListener(map, 'tilesloaded', function(){
google.maps.event.trigger(marker, 'click');
});
</f:if>
</f:for>
<f:if condition="{fitBounds}">
map.fitBounds(bounds);
</f:if>
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
<div id="map"></div>
</f:section>
</div>
view raw GoogleMaps.html hosted with ❤ by GitHub
<?php
namespace MRM\T3base\ViewHelpers\Format;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
* Prepares text for use in JavaScript: escapes quotes, removes line breaks
*/
class JavaScriptEscapeViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper {
/**
* @param string $text
*
* @return string
*/
public function render($text = NULL) {
if(!$text) {
$text = $this->renderChildren();
}
$text = str_replace(array("'", '"'), array("\'", '\"'), $text);
$text = str_replace(array("\n", "\r"), '', $text);
return html_entity_decode($text);
}
}
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<xliff version="1.0">
<file source-language="en" datatype="plaintext" original="messages" product-name="t3base">
<header/>
<body>
<trans-unit id="flux.googlemaps">
<source>Google Maps</source>
</trans-unit>
<trans-unit id="flux.googlemaps.description">
<source>A simple Google Maps</source>
</trans-unit>
<trans-unit id="flux.googlemaps.fields.fitBounds">
<source>Fit map to markers?</source>
</trans-unit>
<trans-unit id="flux.googlemaps.fields.address">
<source>Address for map center</source>
</trans-unit>
<trans-unit id="flux.googlemaps.fields.lng">
<source>Longitude for map center (preferred to address)</source>
</trans-unit>
<trans-unit id="flux.googlemaps.fields.lat">
<source>Latitude for map center (preferred to address)</source>
</trans-unit>
<trans-unit id="flux.googlemaps.fields.zoom">
<source>Zoom (1 = very far, 21 = very near)</source>
</trans-unit>
<trans-unit id="flux.googlemaps.fields.mapType">
<source>Map type</source>
</trans-unit>
<trans-unit id="flux.googlemaps.sections.markers">
<source>Markers</source>
</trans-unit>
<trans-unit id="flux.googlemaps.objects.marker">
<source>Marker</source>
</trans-unit>
<trans-unit id="flux.googlemaps.objects.marker.address">
<source>Address</source>
</trans-unit>
<trans-unit id="flux.googlemaps.objects.marker.lng">
<source>Longitude (preferred to address)</source>
</trans-unit>
<trans-unit id="flux.googlemaps.objects.marker.lat">
<source>Latitude (preferred to address)</source>
</trans-unit>
<trans-unit id="flux.googlemaps.objects.marker.icon">
<source>Pin icon</source>
</trans-unit>
<trans-unit id="flux.googlemaps.objects.marker.iconFile">
<source>Upload pin icon</source>
</trans-unit>
<trans-unit id="flux.googlemaps.objects.marker.title">
<source>Title (marker tooltip and title of info window)</source>
</trans-unit>
<trans-unit id="flux.googlemaps.objects.marker.info">
<source>Text in info window</source>
</trans-unit>
<trans-unit id="flux.googlemaps.objects.marker.showInfo">
<source>Show info window of this marker?</source>
</trans-unit>
</body>
</file>
</xliff>
view raw locallang.xlf hosted with ❤ by GitHub