Plugin Manifest File
Store as plg_myplugin/myplugin.xml.
Something like this...
<?xml version="1.0" encoding="iso-8859-15"?>
<extension type="plugin" method="upgrade" group="system">
<name>Organic Google Tag Manager Plugin</name>
<author>Chris Horgan</author>
<creationDate>Aug 2024</creationDate>
<copyright></copyright>
<license></license>
<authorEmail>This email address is being protected from spambots. You need JavaScript enabled to view it.</authorEmail>
<authorUrl>www.organicwebs.com.au</authorUrl>
<version>5.1</version>
<description><![CDATA[
<div class="alert">
<h2>OrganicWebs Google Tag Manager plugin</h2>
<p>This Plugin adds the Tag Scripts for Google Tag Manager - used for Ads and Remarketing</p>
<p>2024 Updated for use with Google Tag Manager</p>
<br />
<p>Written by Chris Horgan - <a href="http://www.organicwebs.com.au/" target="_blank">OrganicWebs</a></p>
<div id="organic" class="organicstyle" >
<p>Don't forget to Publish the Plugin <a href="/component/plugins/?filter_folder=system&filter_search=google%20tag">here</a></p>
<p>5.1: Joomla 5 version</p>
<p>3.1: Joomla 3 version</p>
</div>
</div>
<style>
.organicstyle { width: auto; height: auto; display: block; margin: 15px 0; }
</style>
]]>
</description>
<namespace path="src">Organic\Plugin\System\Organic_GTag</namespace>
<updateservers>
<server type="extension" priority="1" name="Organic Extension Updates">https://organicwebs.com.au/joomlaupdates/plg_organic_gtag-update.xml</server>
</updateservers>
<files>
<folder plugin="organic_gtag">services</folder>
<folder>src</folder>
</files>
<config>
<fields name="params">
<fieldset name="basic" label="Google Tag Settings">
<field name="google_container_id"
type="text"
default=""
label="Google Tag Manager Container ID"
description="Should be a number like GTM-PDDDXP9"
/>
</fieldset>
</fields>
</config>
</extension>
Create a provider.php file
This is pretty much Boilerplate with a couple lines that need customisation.
Store this file as plg_myplugin/services/provider.php
Something like this...
<?php /** * @package Joomla.Plugin * @subpackage System.organic_gtag * * @copyright (C) 2024 OrganicWebs */ \defined('_JEXEC') or die; use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use Joomla\Event\DispatcherInterface; use Organic\Plugin\System\Organic_GTag\Extension\Organic_GTag; return new class() implements ServiceProviderInterface { public function register(Container $container) { $container->set( PluginInterface::class, function (Container $container) { $config = (array) PluginHelper::getPlugin('system', 'organic_gtag'); $subject = $container->get(DispatcherInterface::class); $app = Factory::getApplication(); $plugin = new Organic_GTag($subject, $config); $plugin->setApplication($app); return $plugin; } ); } };
Create the Plugin Code
The meat and bones. Store as plg_myplugin/src/Extension/My_Plugin.php.
Note - this file name is case sensitive... so save with a filename the same case as the Class (also same case as the new plugin Object in the provider.php file).
See https://docs.joomla.org/Plugin/Events for different types of Joomla 5 Plugin Groups/Types and also for events.
This example plugin below inserts a Google Script at the end of the </head> and another script at the end of the </body> of a rendered page.
<?php /** * System - Organic Google Tag Manager * Google Tag code plugin for Joomla! 5 * Chris Horgan * www.organicwebs.com.au */ // Check out this link for more info... // https://docs.joomla.org/Plugin/Events namespace Organic\Plugin\System\Organic_GTag\Extension; // no direct access defined('_JEXEC') or die; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\Event\Event; use Joomla\Event\SubscriberInterface; use Joomla\CMS\Factory; use Joomla\CMS\Language\Text; use Joomla\CMS\Event\Result\ResultAwareInterface; use Joomla\CMS\Application\WebApplication; class Organic_GTag extends CMSPlugin implements SubscriberInterface { protected $app; public static function getSubscribedEvents(): array { return [ 'onAfterRender' => 'insertTagScripts', ]; } public function insertTagScripts(Event $event) { $google_container_id = $this->params->get('google_container_id', ''); // Return and do nothing if administrator login if ($this->getApplication()->isClient('administrator')) return; // Return with nothing if the GoogeTag ID is unknown... if ( $google_container_id == '' ) return; // Return with nothing if not the site (ie not on api) if (!$this->getApplication()->isClient('site')) return; // Proceeding... $gtag_head_script = " <!-- Google Tag Manager --> <script> (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer','".$google_container_id."'); </script> <!-- End Google Tag Manager --> "; $gtag_body_script = " <!-- Google Tag Manager (noscript) --> <noscript> <iframe src='https://www.googletagmanager.com/ns.html?id=".$google_container_id."' height='0' width='0' style='display:none;visibility:hidden'></iframe> </noscript> <!-- End Google Tag Manager (noscript) --> "; // Get the html body $buffer = $this->app->getBody(); // Insert the Javascript at the end of the HTML <head> and <body> $buffer = str_replace ("</head>", $gtag_head_script."</head>", $buffer); $buffer = str_replace ("</body>", $gtag_body_script."</body>", $buffer); // Set the new html body $this->app->setBody($buffer); return true; } } ?>
References
Plugin Events: https://docs.joomla.org/Plugin/Events
Joomla 5 Manual - Plugins: http://pr-240.manual.joomlacode.org/docs/building-extensions/plugins/