Plugins are easily installed as a .zip file but a correctly formatted XML file must be included. The object-oriented way of writing plugins involves writing a subclass of CMSPlugin.
The XML file is similar to other Joomla XML installation files. You have to add the group="xyz" entry in the <extension> tag and the plugin="xyz" in the <filename> tag.
This information tells Joomla into which folder to copy the file and to which group the plugin should be added.
The object-oriented way of writing plugins involves writing a subclass of CMSPlugin. The CMSPlugin is a base class that implements the basic properties of plugins. Following properties are available:
To use $this->db and $this->app, you have to create properties in the plugin class (protected $db; protected $app; in the same area as protected $autoloadLanguage = true;).
Joomla 4 implements the SubscriberInterface. Instead of the function name automatically being detected and being the same as the event name, this allows you to have custom function names. This allows to tell what plugins are implementing what functions and as parsing public methods in PHP code is slow gives a significant performance boost.
defined( '_JEXEC' ) or die;
class Plg<PluginGroup><PluginName> extends CMSPlugin implements SubscriberInterface
protected $autoloadLanguage = true;
* Returns an array of events this subscriber will listen to.
public static function getSubscribedEvents(): array
'<EventName>' => 'myFunctionName',
* Plugin method is the array value in the getSubscribedEvents method
* The plugin then modifies the Event object (if it's not immutable)
public function myFunctionName(Event $event)
* Plugin code goes here.
* You can access parameters via $this->params
If you are creating a plugin for a new, non-core event, you have to activate your plugin after you install it. The Joomla! core has a number of built-in events that you might want your plugin code to be registered to. However, you will probably want to call it in your code.
The new way of doing this in Joomla 4 is to get the dispatcher and dispatch a named event.
$dispatcher = Factory::getApplication()->getDispatcher();
// Here we create an event however as long as you implement EventInterface you can create your own
// custom classes
$event = AbstractEvent::create(
'<EventName>', array('name' => $value,));
$eventResult = $dispatcher->dispatch('<EventName>', $event);