Work In Progress

This book is currently work in progress. Some sections are not yet written. Thank you for your understanding!

New Joomla 4 features at a glance

Joomla 4 is a smorgasbord of new features, improvements and much needed changes. Unfortunately, a year into its release you'd be hard pressed to find any kind of documentation of what these are and how they can impact your software development practices. I will try to give you the 30,000-feet overview of what I found to be the most important changes.

Namespaces. As you may remember, ever since Joomla 3.3 the legacy class names (e.g. JUri) changed to a namespaced equivalent (e.g. Joomla\CMS\Uri\Uri). In Joomla 4 a lot of the legacy classes stopped working. You can find out these changes neatly codified along with tools to mass convert your extensions in my Joomla Type Hints repository. In Joomla 4 the namespacing work went even deeper, having all classes in components, modules, plugins and templates also support namespaces — if you use the new, Joomla 4 API for developing extensions. This is a game-changer concept! Namespaced classes follow the PSR-4 specification. Joomla caches and registers the PSR-4 mappings between namespace prefixes and directories on your site which means that you can safely use any class of any extension anywhere without having to use include or require ever again. This greatly reduces the possibility for bugs and massively improves the performance of Joomla and its extensions.

Dependency Injection Container / Service Locator. Joomla 1.x to 3.x inclusive had this annoying God Object called the Joomla Factory (JFactory or \Joomla\CMS\Factory). It had a very opinionated approach on instantiating all sorts of globally used services, from the application itself, to the database, to the user objects, to the mailer object. If you wanted to write Unit Tests for your extension — or Joomla itself — it was the bane of your existence. In Joomla 4 we instead have a Container. It is not a real Dependency Injection Container as much as it is a Service Locator, meaning that it won't magically instantiate an object based on the type definitions in its class' constructor but it will let you retrieve the services you need to inject to your objects. Each extension — component, module, plugin and template — gets its own service locator and its own extension object which uses it. This makes it far easier to write unit tests for your code, especially your Models (which is where most of your business logic, therefore your code that needs testing, should already be).

Web Asset Manager. In the past, whenever we wanted to load a JavaScript or CSS file we'd have to load its dependencies and finally our file. For example we might want to load jQuery, then load some Bootstrap core JavaScript files, then our JavaScript file. Each extension would do that and it lead to several chicken and egg problems. What if file A from extension X depends on files B and C and file B from extension Y depends on files C and D but D must be loaded before C? Bummer. The Web Asset Manager codifies the dependencies in a way which lets Joomla resolve them. It also lets you define alternative dependencies,e.g. a different JavaScript file to load depending on whether the user's browser supports JavaScript modules or not, and asset groups, e.g. a collection of CSS and JavaScript which are meant to be loaded together. This lets you split your CSS and JavaScript into smaller files which load in the correct order and improve the performance of your user's site.

A new MVC. The MVC in Joomla 1.5 to 3.10 inclusive had changed very little. Previous attempts to modernise it failed ignominiously because they simultaneously failed to go far enough and maintain b/c (backwards compatibility). Joomla 4 has a new MVC model which is based on Dependency Injection and namespaces, it is more prescriptive, more flexible and more powerful than its predecessors. You can very easily extend a frontend model from a backend model instead of writing the same code twice or doing a contortionist act with PHP Traits. You can easily create custom HTML helpers without calling static functions, use categories without writing precarious database code, create object-oriented URL routers and much more which we will explore in this book.

Hide-able inline help. Remember how Joomla 3 XML Forms looked like a word vomit with all the inline help text (field descriptions) being always visible? This was a bad interface for experienced users. At the same time, Joomla 4.0 removing all inline help text made the interface inapproachable for newcomers and end clients meant to use the site. With Joomla 4.1 it is now possible to have hide-able inline help text in your forms and your component configuration. The field descriptions are hidden by default and the user can show them by clicking on the Show Inline Help button in the interface. Now your extensions' interface can be simultaneously approachable for both new and experienced users.

Prepared statements. SQL injection vulnerabilities have been almost de rigueur for any web software, Joomla extensions being no exception to that. Sure, Joomla does have some very nifty tools to get filtered input and escape it when placed inside database queries but not all input can be escaped sufficiently if you do not know its type (integer, string, array of one or the other). Moreover, despite best intentions, accidents can and do happen, e.g. forgetting to escape one piece of input you assumed it's an integer but it came through a path which never did check the input type nor did it try to typecast it to an integer! Joomla 4 introduced prepared statements which make these oversights and corner cases a thing of the past. You tell the query builder where you expect potentially user-originating data in your query, which data to use in there and what type this data is. You are guaranteed safe execution without worrying about SQL injection unless you try really hard to NOT let Joomla use a prepared statement. On the flip side, there are a few types of SQL queries which cannot execute in the context of prepared statements and required some code contortion to execute.

Mail templates. In the past there were two ways to handle email for your extension. You could send plain text only email using language strings OR you would have to invent your own email template management. The former led to ugly email messages. The latter required reinventing a very complex device on each and every of your components. If you did not have a component, tough luck. Darn! Joomla 4's mail templates feature allows your users to use the Joomla WYSIWYG editor to create rich email templates with placeholders to be replaced by data provided by your extension. This feature looks half-finished in Joomla 4 as it has no obvious way to register or update email templates. Don't worry, though, we do have a way to work around its shortcomings, complete with example code.

Scheduled Tasks. Many extensions need to periodically execute some kind of code. For example, sending email newsletters, updating the prices of thousands of SKUs in an online shop from an Excel or XML file, running backups, you name it! In the past we had to reinvent the wheel on each extension we built. For example, we created ‘special’ URLs in our components or through com_ajax to be accessed with wget, cURL or a service like periodically; or we created CLI scripts to be used with CRON jobs. We almost always offered more than one way to do things which led to a certain degree of code duplication. In all cases, the user was responsible for setting up CRON jobs or the equivalent on a third party service for every single task they needed to be executed periodically. This was a tall ask! Joomla 4.1 and later offers a new Scheduled Tasks feature which allows users to select which tasks they want to be executed, when to execute them and even configure their execution parameters — all within the familiar Joomla user interface. It even lets the task scheduler to be executed three ways: with a command line CRON job, a URL-based CRON job or automatically based on visitor traffic (lazy scheduling). The end user has to set up just the one CRON job or, if they are using lazy scheduling, just flip a switch.

CLI Application. In the past we had to create bespoke CLI scripts for every task each of our extensions needed to allow to be executed from a command line context, be it a CRON job or a manually executed CLI helper tool. This required creating a new application and contend with the two facts that a) the base class changed at least twice in the last ten years and b) it lacked a lot of methods several core and third party classes were expecting to be present. This led to a lot of reinventing the wheel. The Joomla CLI Application is like a built-in version of WordPress' WP-CLI or Drupal's Drush in that it's based on the Symfony Console Components and can be easily extended using plugins which register command classes. Used wisely, it can enhance your extensions and help your advanced users who can use the CLI to automate things around their site.

API Application. Joomla has historically been an HTML-only application. Yes, sure, you can have JSON, XML, Feed and Raw views but they feel bolted onto the HTML application; they are not a real API to your component. Joomla 4 introduced a brand-new application, the ApiApplication which lives in the api directory of your site. For now it's only accessible to Super Users but it provides a real RESTful JSON-based API to components which integrate with it. Integrating your component with the API application is as easy as creating a Web Services plugin and adding a few easy to create controllers and views in the API part of your component. That is to say, your component now has a backend, a frontend and an API side. You don't have to integrate with the API application but if you have something which could benefit from automation it is strongly encouraged to do so.

Dashboards. Between Joomla 1.0 and 3.10 inclusive Joomla only ever offered one dashboard, the main Control Panel page which loaded when you logged into your site's backend. In Joomla 1.0 to 1.6 it was hard-coded and inflexible. I added the ability to use plugins to render custom action buttons in Joomla 1.7, based on my experience with my software. Starting with Joomla 3.0 you could now publish modules to add information panes to the Control Panel dashboard. If you wanted the same experience in your extension… tough luck. You would have to reinvent the wheel. Joomla 4.0 and later allow you to set up one or more dashboard pages for your own component which appear in the Joomla menu structure, under your component's menu item, and where you and your end users can publish any number of modules.

Layouts everywhere. A lot of the HTML generated by Joomla, even throughout version 3, was statically coded in the PHP files implementing the business logic, making any kind of customisation impossible (or, at the very least, requiring a very judicious application of in-memory code editing, buffer stream wrappers and Reflection). Let's just say that if you disagreed with how a certain form field or HTML helper rendered its HTML you were out of luck. Layouts were introduced in Joomla 3.4 and later versions did make better use of them in various places but you still had to contend with several of the same issues. Not anymore! Joomla 4 uses layouts for every kind of HTML output. If you want to override how some core code renders in your component or your template you can easily do that by overriding the layout. Likewise, you are encouraged to use Layouts everywhere you have reusable HTML output in your extensions to make it easier for end users to override them in their template.

Media options per component. Joomla 3.4 introduced an upload checker for all uploaded files based on the work I had done in Admin Tools. This was a massive leap in security as we codified the basic upload checks and encapsulated them in a way that made them run automatically whenever you were handling uploads. However, this was controlled by the Media component's (com_media) settings. This was great if your extension only ever needed static media files to be uploaded. If you wanted to allow your users to upload non-media files, or files otherwise not acceptable anywhere else com_media was exposed, such as ZIP, 7Z, and RAR files in a helpdesk component, you had to modify the Media options, allowing these files everywhere. The unfortunate solution to that was that third party component developers chose to disable the upload checks, undoing the security improvements we added in Joomla 3.4. This is no longer the case! Joomla 4 allows each component to have its own, private copy of Media settings for its own uploads. Any upload being handled by your component (not com_media!) will have these private settings applied. It's a bit of a chore BUT it lets you provide a much safer option for uploading files through your extension.

There are many more improvements which I will not cover in this book. If you found out something cool and you'd like me to write a section for it, please do let me know. I can't promise it will definitely make it into the book but I will at least promise to give it a good thought and most likely a good try.