Development Update - 1st May 2026 - Email from GoogleMaps
Hello Google Maps Platform customer,
This communication informs you about the upcoming deprecation of the KmlLayer class in the Maps JavaScript API and provides the necessary resources for transitioning your applications to modern alternatives.
What you need to know
The KmlLayer functionality in the Maps JavaScript API will no longer be supported. This feature is deprecated as of today, and will be made unavailable in version 3.66 of the Maps JavaScript API, releasing in August 2026. You can keep using the KML Layer until May 2027, by explicitly using Maps JavaScript API versions that still support it.
Development Update - May 2024
Please read the article for the earlier version for the philosophy and methodology which remain unchanged.
There are two major changes:
- The way in which a plug is called in Joomla 5, and the location of the various files.
- The way in which scripts are executed, and there are two scripts which are required:
- The script which generates the maps.
- the script which grants authority to show the maps.
Joomla 4 and now Joomla 5 have altered the way in which Joomla Operates internally.
For the average user of course this is all hidden. There are two categories of developer:
- People like me who want to do something really very very simple - like run a script to display a KML file in Google Maps, and to embed a Facebook Page. These are really very simple.
- People who develop what might be termed "serious" modules such as SigPlus, and Akeeba Backup to name the ones most important to me.
I have been very surprised to discover the massive extent of the changes within Joomla recently. At 77 I am left unable to take it all in. I do recollect when TDOC, my document control and management software moved from dBase to Clipper, and then the awe inspiring move to CA Visual Objects which meant learning to program using reusable objects with properties - and one could "subclass" making said objects either simpler or more complex.
Thus thanks to Robbie Jackson for taking the time and trouble to update both the Facebook and Google Map stuff for me.
His discourses are to be found at: https://www.youtube.com/playlist?list=PLzio09PZm6TuXGnu-ptpVb90Szkawy9IV, and he recommends a most marvellous book at https://www.dionysopoulos.me/book by the developer of Akeeba etc etc.
12th May 2024: Modifications made per Robbie Jackson are shown in red.
The main changes are relocation of files, and the addition of "provider.php".
In the tdocgmap.php, the construct is altered in how "oncontentprepare" is called.
The actual preparation of the content [generation of the maps etc is unaffacted]
My thanks to Robbie Jackson. https://forum.joomla.org/viewtopic.php?f=833&t=1008461
Content of the tdocgmap folder
Files are as follows:
- from the root
- language [subdirectory]
- en_GB
- plg_content_tdocgmap.ini
- plg_content_tdocgmap.sys.ini
- en_GB
- services [new subdirectory]
- provider.php [new file]
- src [new subdirectory]
- extension [new subdirectory]
- tdocgmap.php
- extension [new subdirectory]
- index.html
- tdocgmap.xml
- language [subdirectory]
- in the "upgrade" server directory - on the web
- index.html
- tdocgmap.zip [all of the above zipped]
- tdocgmap_update.xml
Revised xml file
<?xml version="1.0" encoding="utf-8"?>
<extension version="5.5.1" type="plugin" group="content" method="upgrade">
<!-- 12th March 2022 - Added translation files thanks to pe7er for unscrambling the specification -->
<!-- 13th May 2024 Modified to J5 oer Robbie Jackson -->
<!-- 2nd Jan 2025 Fixed a wee bug and made compatible with J4 calls -->
<name>PLG_CONTENT_TDOCGMAP</name>
<author>Eur Ing Richard Townsend-Rose</author>
<creationDate>2 January 2025</creationDate>
<copyright>Copyright (C) 2025 Open Source Matters. All rights reserved.</copyright>
<license>http://www.gnu.org/licenses/gpl-3.0.html</license>
<authorEmail>
<authorUrl>rgtr.tdocplus.co.uk</authorUrl>
<version>5.5.1</version>
<description>PLG_CONTENT_TDOCGMAP_XML_DESCRIPTION</description>
<!-- namespece dceclaration -->
<namespace path="src">Tdoc\Plugin\Content\Tdocgmap</namespace>
<!-- revised files and folders -->
<files>
<folder plugin="tdocgmap">services</folder>
<folder>src</folder>
<folder>language</folder>
</files>
<!-- new folder for the json file which calls the java script for the map creation -->
<media destination="plg_tdocgmap" folder="media">
<filename>joomla.asset.json</filename>
<folder>js</folder>
</media>
<!-- Setup the form for the Basic tab -->
<config>
<fields name="params">
<fieldset name="Basic">
<!-- google maps api key -->
<field type="spacer" name="mandatory" label="PLG_CONTENT_TDOCGMAP_MANDATORY"
/>
<field name="apikey"
type="text"
label="PLG_CONTENT_TDOCGMAP_GOOGLE_MAPS_API_KEY"
description="PLG_CONTENT_TDOCGMAP_GOOGLE_MAPS_API_KEY_DESC"
size="48"
/>
<!-- google maps display settings -->
<field type="spacer" name="defaults" label="PLG_CONTENT_TDOCGMAP_DEFAULTS" />
<field name="width"
type="text"
label="PLG_CONTENT_TDOCGMAP_WIDTH"
description="PLG_CONTENT_TDOCGMAP_WIDTH_DESC"
default="500"
size="4"
/>
<field name="height"
type="text"
label="PLG_CONTENT_TDOCGMAP_HEIGHT"
description="PLG_CONTENT_TDOCGMAP_HEIGHT_DESC"
default="500"
size="4"
/>
</fieldset>
</fields>
</config>
<!-- xml file that holds the update information -->
<!-- decided to create J5 native -->
<updateservers>
<server type="extension" name="Plugin TDOC Googlemap Update Site">http://www.tdocplus.co.uk/tdoc_j5_dev/tdoc_gmap/tdocgmap_update.xml</server>
</updateservers></extension>
Modified tdocgmap.php
<?php
/**
* @package TDOC Google Maps Display
* @copyright Copyright (C) 2025. All rights reserved.
* @license http://www.gnu.org/licenses/gpl-3.0.html
* @version 5.5.1
* 5.5.0 updated to meet J5 requirements 12th May 2024 per Robbie Jackson - see https://forum.joomla.org/viewtopic.php?f=833&t=1008461
* 5.5.0 updated per Robbie Jackson to J5.
* 5.5.1 Bugs fixed 2nd Jan 2025. Compatible with J4 - allow quotes round kml, and moved endif to right place - after script calls !
**/
/**
Many thanks to Gene from the Google Maps Platform Technical Support team
**/
// Ver 5.5.0 per Robbie added new line
namespace Tdoc\Plugin\Content\Tdocgmap\Extension;
use Joomla\CMS\Plugin\CMSPlugin;
// Ver 5.5.0 per Robbie added two new lines
use Joomla\Event\Event;
use Joomla\Event\SubscriberInterface;
// Ver 5.5.1 per comments on Forum. NO spaces within brackets.
defined('_JEXEC') or die('Restricted access');
// Ver 5.5.0 per Robbie amended line
class Tdocgmap extends CMSPlugin implements SubscriberInterface {
/**
* Load the language file on instantiation.
*
* @var boolean
* @since 1.0.0
**/
protected $autoloadLanguage = true;
// Ver 5.5.0 per Robbie added lines
public static function getSubscribedEvents(): array
{
return [
'onContentPrepare' => 'onContentPrepare',
];
}
function onContentPrepare(Event $event) {
$app = $this->getApplication();
if (!$app->isClient('site')) {
return;
}
[$context, $article, $params, $limitstart] = array_values($event->getArguments());
// Original Code here till comment
//step zero - kick everything else out
$name=$this->_name;
//echo "<br>"."Name: ".$name;
if ($name !== "tdocgmap"){return true;}
// required to pass one css, and two js scripts.
// step one - read settings - apikey, defaults for width, height
$apikey = $this->params->get('apikey','');
$height = $this->params->get('height','');
$width = $this->params->get('width' ,'');
//echo "<br>Step One - Default Settings: ".$apikey .", ". $height .", ". $width ;
// step two locate number of instances of {tdocgmap}
$content = $article->text ;
$occurrences = array();
// set counter for replacing etc etc
$counter = 0;
$tag='tdocgmap';
$regex = "/\{".$tag."\s+(.*?)\}/is";
$found = preg_match_all($regex, $content, $occurrences);
//echo "<br>Step Two - Occurrences: ". sizeof($occurrences) ;
$kml = [];
// step three get data for each map
if ($found){
// array to collect maps
$mydivs = array() ; // used to replace occurrences in text
foreach ($occurrences[0] as $value) {
// create array for each data, create map and add to mymap
$gotdata=array('','','','') ; // 4.1.0
// replace tag and get local data [kml file, height, width]
$data = $value ;
$data = str_replace('{tdocgmap ', '', $data);
$data = str_replace('}', '', $data);
// explode data into an array
$arr = explode(" ", $data);
foreach ($arr as $phrase) {
if (strstr(strtolower($phrase), 'kml=')) {
$tpm = explode('=', $phrase);
// echo "<br>Step c - data: ".$tpm[1] ;
// 5.5.1 strip out apostophes - allows previously required single quotes
$tpm[1] = str_replace("'", '', $tpm[1]);
// echo "<br>Step d - stripped: ".$tpm[1] ;
$gotdata[0]=$tpm[1];
}
if (strstr(strtolower($phrase), 'height=')) {
$tpm = explode('=', $phrase);
$gotdata[1]=$tpm[1];
}
if (strstr(strtolower($phrase), 'width=')) {
$tpm = explode('=', $phrase);
$gotdata[2]=$tpm[1];
}
if ($phrase =='left') {
$gotdata[3]="left" ;
} elseif ($phrase =='right') {
$gotdata[3]="right" ;
} elseif ($phrase =='print') {
$gotdata[3]="print" ;
}
} // end for each data
// check if height & width were set, if not use defaults, no kml - zappo !
if (empty($gotdata[0])){return true ; } // kml
if (empty($gotdata[1])){$gotdata[1] = $height ;}
if (empty($gotdata[2])){$gotdata[2] = $width ; }
// create divs // 4.1.0 // mapno, height, width, ifprint
$mydivs[$counter] = getmydiv($counter, $gotdata[1], $gotdata[2], $gotdata[3]) ;
// create maps
$kml[] = $gotdata[0];
$counter = $counter + 1 ;
} // end for each occurrence
// Replace tag occurences with divs.
for ($i = 0; $i < count($mydivs); $i++) {
$article->text = preg_replace($regex, $mydivs[$i], $article->text, 1);
} // end for replace tags with maps
// Original Code ends here
/** ver 5.5.0 major changes on script generation etc
*
* The initMap() function is now created in a java script.
* The java script is called by a json statement: joomla.asset.json in the media\plg_tdocgmap folder
*
* See https://www.dionysopoulos.me/book/concepts-webassetmanager.html-
* Caveat: modules don't auto-load the joomla.asset.json file
**/
// Authority Script
// script name is plg_tdocgmap.google-maps - defined as a dependency in the .json file.
$document = $app->getDocument();
$wa = $document->getWebAssetManager();
$apikey = $this->params->get('apikey','');
$wa->registerScript("plg_tdocgmap.google-maps",
"https://maps.googleapis.com/maps/api/js?key={$apikey}&callback=initMap&loading=async",
array(),
array("async" => true),
array()
);
// call the json file.
$wr = $wa->getRegistry();
$wr->addRegistryFile('media/plg_tdocgmap/joomla.asset.json');
// script to create maps with the initMaps function: map.js in \media\plg_tdocgmap\js,
// script name defined in .json file.
$document->addScriptOptions('nmaps', $counter);
$document->addScriptOptions('kml', $kml);
$wa->useScript('plg_tdocgmap.map');
} // end found
return true;
} // end oncontentprepare
} // end plgcontenttdocgmap class
/**
* The .json code is:
{
"$schema": "https://developer.joomla.org/schemas/json-schema/web_assets.json",
"name": "plg_tdocgmap",
"version": "1.0.0",
"description": "tdoc google map",
"license": "GPL-2.0-or-later",
"assets": [
{
"name": "plg_tdocgmap.map",
"type": "script",
"uri": "plg_tdocgmap/map.js",
"dependencies": [
"plg_tdocgmap.google-maps"
],
"version": "1.1.0"
}
]
}
*
* The above code is incredibly sensitive . . . be very very careful
**/
/**
* The java script code is:
function initMap() {
const nmaps = Joomla.getOptions('nmaps');
const kml = Joomla.getOptions('kml');
var map = [];
var kmlLayer = [];
for (let i=0; i<nmaps; i++) {
map[i] = new google.maps.Map(document.getElementById("Map" + i), {
center: new google.maps.LatLng(0, 0),
zoom: 12,
scaleControl: true,
mapTypeId: "terrain"
});
kmlLayer[i] = new google.maps.KmlLayer( {
url: kml[i],
suppressInfoWindows: false,
preserveViewport: false,
map: map[i]
});
}
}
*
**/
// below is the getmydiv function called from above.
// previously used https://codebeautify.org/html-to-php-converter
// set up the divs to hold the maps, used in the tag replacement in the article - 4.1.0 code.
function getmydiv($i, $h, $w, $xx) {
// echo "<br>Opt:".$xx.":" ;
if($xx=="print") {
$output = '<div id="Map'.$i.'" style="width:100%; height:700px; border: thin solid #333;">'.$i.'</div>';
} elseif($xx=="left") {
$output = '<div id="Map'.$i.'" style="width:'.$w.'px; height:'.$h.'px; float:left; margin: 15px; border: thin solid #333;">'.$i.'</div>' ;
} elseif($xx=="right"){
$output = '<div id="Map'.$i.'" style="width:'.$w.'px; height:'.$h.'px; float:right; margin: 15px; border: thin solid #333;">'.$i.'</div>' ;
} else {
$output = '<div id="Map'.$i.'" style="width:'.$w.'px; height:'.$h.'px; margin:auto; border: thin solid #333;">'.$i.'</div>' ;
}
return $output ;
}
?>
4) tdocgmap_update.xml
Purpose: Used by Joomla to check the latest version and the whereabouts of the installation.
Nota Bene: https://manual.joomla.org/docs/building-extensions/install-update/update-server/ - The is mandatory for plugins !
Content:
<?xml version="1.0" encoding="utf-8"?>
<updates>
<update>
<name>tdocgmap</name>
<description>Google Maps KML Display</description>
<element>tdocgmap</element>
<type>plugin</type>
<folder>content</folder>
<client>0</client>
<version>5.5.1</version>
<infourl title="tdoc">http://www.tdocplus.co.uk</infourl>
<downloads>
<downloadurl type="full" format="zip">http://www.tdopclus.co.uk/tdoc_j5_dev/tdoc_gmap/tdocgmap.zip</downloadurl>
</downloads>
<tags>
<!-- dev, alpha, beta, rc, stable -->
<tag>stable</tag>
</tags>
<maintainer>Eur Ing Richard Townsend_Rose</maintainer>
<maintainerurl>http://www.rgtr.tdocplus.co.uk</maintainerurl>
<targetplatform name="joomla" version="5.*"/>
<php_minimum>8.1</php_minimum>
</update>
</updates>