3

I am trying to create a plugin that will add the following in the of pages:

<meta http-equiv="origin-trial" content="MY_CHROME_TRIAL_TOKEN">

I assume this should be a system plugin that targets the onAfterRender event so have added this code (I have substituted the real token):

public function onAfterRender()
{
  $document = JFactory::getDocument();
  $document->setMetaData('origin-trial', 'mychrometrialtoken');
}

The plugin installs but the meta tag is not added to the page header. What am I doing incorrectly? I am a novice at this so have used a plugin template from Github and modified it. I have probably made a basic error! I wonder if I have specified the tagname 'origin-trial' incorrectly.

XML file:

 <?xml version="1.0" encoding="utf-8"?>
<extension version="3.1" type="plugin" group="system">
    <name>plg_system_tdcchromexhrenable</name>
    <author>AG</author>
    <creationDate>8 September 2020</creationDate>
    <copyright>Copyright (C) 2005 - 2013 Open Source Matters. All rights reserved.</copyright>
    <license>GNU General Public License version 2 or later; see LICENSE.txt</license>
    <authorEmail>admin@joomla.org</authorEmail>
    <authorUrl>www.joomla.org</authorUrl>
    <version>1.0</version>
    <description>Enable the XHR synchronous setting in Chrome to prevent SCORM errors</description>
    <files>
        <filename plugin="tdcxhr">tdcxhr.php</filename>
        <filename>index.html</filename>
    </files>
</extension>

PHP:

    <?php
// no direct access
defined( '_JEXEC' ) or die;

class plg<system><plg_system_tdcchromexhrenable> extends JPlugin
{
    /**
     * Load the language file on instantiation. Note this is only available in Joomla 3.1 and higher.
     * If you want to support 3.0 series you must override the constructor
     *
     * @var    boolean
     * @since  3.1
     */
    protected $autoloadLanguage = true;

    /**
     * Plugin method with the same name as the event will be called automatically.
     */
     function onBeforeCompileHead()
        {
           $document = JFactory::getDocument();
           $document->setMetaData('origin-trial', 'token_goes_here','http-equiv');
           return true;
        }
}
?>
  • 1
    I think the chances are it's because you have done onAfterRender. Something else will possibly work better. A system plugin is correct. – Eoin Sep 7 at 9:17
  • 1
    Try using onBeforeCompileHead, which will add your meta tag to the <head> before it's rendered...which is what you need so that it's there before page load. And +1 for using a plugin – Lodder Sep 7 at 9:21
  • 1
    Looking at the API, I think you should maybe be setting the third parameter of the setMetaData() call, and specifying it as 'http-equiv'. Can you try that? – Robbie Jackson Sep 7 at 13:31
  • 1
    I coded up a plugin and it worked fine. Could you post the complete contents of your plugin xml and php files, together with their filenames and the name of the directory they're in. If you're getting a PHP error then Joomla will be doing a require of your code (PHP is reading it) but maybe your function isn't being called. One reason could be that your plugin class name isn't what Joomla expects. – Robbie Jackson Sep 7 at 21:13
  • 1
    Try adding die; inside your function. If you see a blank page, then the plugin is actually working – Lodder Sep 8 at 10:38
2

If I were you I would try this instead of onBeforeRender:

onBeforeCompileHead

That way you are adding the meta to the document prior to it being rendered.

Here is an excellent video explaining all the different plugin types, but admittedly it can take a while to get your head around them. https://www.youtube.com/watch?v=_agXP5DHm_g&list=PLbSGtuctZCf0VSfiMXWtoD5u7wrSmpr_Y&index=18&t=0s

It would also be good to add this code:

    // If we are on admin don't process.
    if (!$app->isClient('site'))
    {
        return;
    }

Joomla has 2 client apps. Site and Administrator. This code will ensure that the plugin only adds the meta data to the front end and not the backend. Effectively it checks if it is not on the site (e.g. administrator or any other type of client e.g. CLI or Web Services) and if it's not on the site it exits.

| improve this answer | |
  • Thanks to you both. I have tried onBeforeCompileHead but the tag is still not appearing (I didn't see this listed as a system event when I first looked). – agould Sep 7 at 10:02
  • I also added: if (!$app->isClient('site')) { return; } before the system event but Joomla then gave a system error: syntax error, unexpected 'if' (T_IF), expecting function (T_FUNCTION) or const (T_CONST) ...so I removed it. I'm not sure what T_FUNCTION is (a case of a little knowledge being a dangerous thing I think!). – agould Sep 7 at 10:04
  • It will mean the if is in the wrong place, it could be very early. Also you'll need to define $app. – Eoin Sep 8 at 15:41
2

Plugins can be fickle things to get right, so here's a short guide to getting your plugin working successfully.

Identify the Plugin Type and Event

Firstly work out which event you need to subscribe to.

The events which are emitted by Joomla are listed in https://docs.joomla.org/Plugin/Events, and these are segregated by plugin type. Unfortunately it's not always clear which event you need to subscribe to. I watched the video suggested by Eoin in his answer and there is a good description there of how Joomla generates a web page from an HTTP request, and at what stages the system type plugin events are emitted.

For your particular requirement of inserting a meta tag into the HTTP response head you could probably choose any one of a number of the system events.

Joomla third party extensions can also generate events; check the extension document for these.

Naming Conventions

Once you know which plugin type you need to develop and the event to subscribe to then you can start coding. But you have to abide strictly to certain Joomla naming conventions. I'll list these relating to the case where you want to create a system type plugin called "example". (Replace as appropriate "example" and "system" with the names for your plugin everywhere below.)

Avoid underscores in your plugin name!

Create the folder plg_system_example, and in that folder create 2 files:

example.xml (your manifest file for the plugin) example.php (your main php code file for the plugin)

Here's example.xml with the key things:

<?xml version="1.0" encoding="utf-8"?>
<extension version="3.8" type="plugin" group="system" method="upgrade">
    <name>plg_system_example</name>
    <description>An example of a plugin</description>
    <files>
        <filename plugin="example">example.php</filename>
    </files>
</extension>

Here's example.php (assuming you're subscribing to onBeforeCompileHead):

<?php
defined( '_JEXEC' ) or die;

class PlgSystemExample extends JPlugin
{
     public function onBeforeCompileHead()
     {
        … your code here
    }
}

Note the capitalisation in the plugin class name!

If you're subscribing to a different event, then use the appropriate parameters for your function call, as described in https://docs.joomla.org/Plugin/Events.

Installation

Zip up your folder to create a zip file plg_system_example.zip and install it.

Remember to enable your plugin.

Also plugins have an Access field, so you can define the set of usergroups for which the plugin is run.

Your plugin is run both on the front-end and the back-end, so as Eoin mentioned, it's sensible to check which you're running on, and code appropriately.

Finally, I did create a little video describing how plugins work in Joomla which you can find at https://www.youtube.com/watch?v=UuOPrTu6Vac&feature=youtu.be

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.