Custom Plugins, part 1: General Overview
This is the start of a series of articles about building custom plugins. We will start with some general information about plugins and creating them. In subsequent episodes of this series we will take a closer look at specific plugin types and their peculiarities.
Procedural hooks and decoupled services
With plugins you can adjust components and extend their functionality. Basically there are two distinct mechanisms that are used by plugins:
- Procedural hooks: calling some remote “procedure” which gives some return value that is actively used by the calling code. For example, content plugins that receive the article text, can transform it and return the modified text. Or a payment component that uses plugins to define different payment methods. You get an extensible system where custom plugins can be added. It is a simple but powerful way to add extra functionality.
- Follow-up actions: in this case a plugin listens to an event mainly to trigger some side effect. This is more a “fire-and-forget” type of plugin. You can use it for instance to send a notification about a newly saved article or to log your component’s actions. Custom plugins can react to such an event and add totally new actions. This gives possibilities for an event-driven architecture.
Those procedural hooks are the oldest form of plugins. They are a simple kind of middleware. A disadvantage is that they are tightly coupled: there where those events are triggered, you have to know with what parameters those procedures are called and what values they return. Joomla mitigates that coupling by using events instead of direct callbacks.Those callbacks used to require a fixed parameter order; events avoid that. Those events contain the input variables in a standardised way. In principle the plugins don’t have a return value anymore, but you can modify input parameters or add a result array to them. So, you can still use “hooks” in Joomla, but they use events to reduce coupling.
Plugin tutorial in developers manual
In the developers manual you’ll find a tutorial on how to make a plugin. There a basic content plugin serves as an example. In the manual you can also find some general information about how plugins work, and about plugin methods and events. I’ll add some background information in the following sections of this article about the Subscriber Interface and about Dependency Injection.
Subscriber Interface
In former days we directly added a method to a plugin with the same name as the event, and with a fixed order of parameters for that specific event. Those methods were detected with reflection, which was slow with many plugins. By using the SubscriberInterface, we define which events the plugin will handle and what methods will do that. Those handler methods now have the event object as parameter. The SubscriberInterface defines no return value, but you can add a result array. You can even give priorities to those handlers, so you are no longer fully dependent on plugin load order.
Dependency Injection
Like all Joomla extensions, plugins use dependency injection. That is why we have the service provider file. Read the article about dependency injection to understand more on how that works. In the service provider the plugin itself is instantiated and all dependencies are injected into it, typically via setters. For instance, if your plugin needs an application object, the database and user-info, you’ll need something like this in your service provider:
$plugin->setApplication(Factory::getApplication());
$plugin->setDatabase($container->get(DatabaseInterface::class));
$plugin->setUserFactory($container->get(UserFactoryInterface::class));
In the plugin itself you can use getters to get those injected objects: $this->getApplication(), $this->getDatabase(), etc.
The getter and setter for the Application-object is already implemented in the parent Joomla\CMS\Plugin\CMSPlugin. If you want to provide other objects, you’ll have to implement the setter and getter methods yourself. For a lot of basic objects there are traits available to implement those getters and setters. For instance, to provide a database, use the Joomla\Database\DatabaseAwareTrait, and to provide a user object use the Joomla\CMS\User\UserFactoryAwareTrait. Best practice is to declare which interface is implemented when using such a trait; in this case Joomla\Database\DatabaseAwareInterface and Joomla\CMS\User\UserFactoryAwareInterface respectively.
Different types of plugins in this series
In the coming episodes we plan to show custom plugins of the following types:
- Task plugin: schedule tasks to be done by your website, for instance checking in content that is still checked out by an expired session, or notifying you of new content. Task plugins are nice examples of decoupled follow-up actions.
- Workflow plugin: you can customise the current publishing workflow, for instance by notifying the author of an article that the state has altered. Or you can define completely custom workflows, for instance for e-commerce with states for ordered, paid, shipped, etc.
- Finder plugin: when you have a custom component, you’d want to use it in Finder (“smart search”). Write a custom finder plugin for that.
- Content plugin: this is the best known type of plugin. We’ll show some nice possibilities with custom content plugins.
- System plugin: not tied to a specific component, and loaded before other parts of the CMS. We’ll show possibilities, for instance how it is used in the Obix Class Extender system plugin to alter core classes.
- Webservices plugin: if your component has a web services API, you’ll need a custom plugin for them.
- Quickicon plugin: make your own buttons for the quickicons module.
- Filesystem plugin: you can place images and files somewhere in the cloud. How to make a plugin for a custom file location.
- Media-action plugin: make your own image handler.
- User plugin: we’ll extend users and usergroups with some custom plugins.
- Fields plugin: if you have defined your own fields, specific for your component, you can also let your clients use them as additional fields. In this episode we’ll show how.
- Editors and Editors-extended plugin: add your own buttons to the editor.
- Schemaorg plugin: we’ll create some custom schemas for structured data.
- Authentication plugin: how to implement a custom authentication plugin, for instance to login with Github. We’ll also look at multifactor authentication and API-authentication.
- Behaviour plugin: an interesting group of plugins, best known from the backwards compatibility plugin. What are the custom possibilities?
Some articles published on the Joomla Community Magazine represent the personal opinion or experience of the Author on the specific topic and might not be aligned to the official position of the Joomla Project
By accepting you will be accessing a service provided by a third-party external to https://magazine.joomla.org/

Comments