Maintaining a Joomla extension across multiple major versions can be a logistical challenge for developers. One of the most critical components of a professional extension is the update server. It ensures that your users receive timely security patches and feature updates directly within their Joomla administrator interface. However, as Joomla evolves from version 3.x to 4.x and now 5.x, defining which version of your extension belongs to which version of the CMS requires precision.

In this guide, you will learn how to leverage Regular Expressions (regex) within your Joomla update XML files. Specifically, we will look at how to use the targetplatform tag to support a range of Joomla versions—such as 3.8, 3.9, 3.10, and 4.x—within a single update block, ensuring your update logic is both clean and efficient.

Understanding the Joomla Update Server XML Structure

Before diving into the regex logic, it is important to understand how Joomla processes updates. Every Joomla extension should point to an update manifest—an XML file hosted on your server. This file contains one or more <update> blocks. Each block tells Joomla: "If a site meets these criteria, this is the version they should download."

The key element for version targeting is <targetplatform />. A standard implementation looks like this:

<update>
    <name>My Awesome Extension</name>
    <description>A powerful tool for Joomla users.</description>
    <element>com_awesome</element>
    <type>component</type>
    <version>2.0.0</version>
    <downloads>
        <downloadurl type="full" format="zip">https://example.com/download/com_awesome_v2.zip</downloadurl>
    </downloads>
    <targetplatform name="joomla" version="4.[01234]"/>
</update>

The version attribute in <targetplatform> is where the magic happens. While many developers use simple strings, Joomla actually evaluates this attribute using PHP's preg_match() function, allowing for powerful pattern matching.

The Technical Reality of Version Matching

To write effective regex for Joomla, you need to know how the Joomla core processes your XML. Inside the Joomla CMS updater library (specifically within the ExtensionAdapter), the code performs a check similar to this:

preg_match('/^' . $this->currentUpdate->targetplatform['VERSION'] . '/', JVERSION)

Because your version string is wrapped in /^ ... /, it is treated as the start of a regular expression. However, there is a catch: Joomla does not run preg_quote() on your string. This means that special characters like the dot (.), which in regex signifies "any character," will be interpreted as wildcards unless you escape them.

If you write version="3.10", the regex engine sees 3.10, where the dot matches anything. While this usually works for versioning, it is not technically precise. To be safe and professional, you should treat the version attribute as a true regex string.

Crafting the Perfect Regex for Joomla 3.x and 4.x

Suppose you want to target Joomla 3.8, 3.9, 3.10, and all versions of Joomla 4. A naive approach might look like this:

<targetplatform name="joomla" version="(3.[89]|10)|4.*"/>

While this looks logical, it has flaws. The . isn't escaped, and the logic for 10 might accidentally match a future version like 3.100 if the boundaries aren't defined.

Based on the way Joomla's updater handles strings, the most robust and efficient regex to target Joomla 3.8, 3.9, 3.10, and 4.x is:

<targetplatform name="joomla" version="(4|3\.([89]|10))\b"/>

Breaking Down the Regex logic:

  1. ^: (Implicitly added by Joomla) Matches the start of the version string.
  2. (4|3\.([89]|10)): This is a capture group with an "OR" (|) operator.
    • 4: Matches any version starting with 4 (e.g., 4.0, 4.1, 4.4.9).
    • 3\.: Matches a literal 3 followed by a literal dot.
    • ([89]|10): Matches either an 8, a 9, or the sequence 10. This covers 3.8, 3.9, and 3.10.
  3. \b: This is a word boundary. It ensures that the match stops exactly where the version number ends, preventing accidental matches with hypothetical future versions like 3.80 or 44.0.

Expanding Support for Joomla 5.x

With Joomla 5.x now in active use, many developers want to provide a single package that works across Joomla 4 and 5 (thanks to the Compatibility Plugin). To extend our regex to include Joomla 5, we simply update the first part of our group:

<targetplatform name="joomla" version="(5|4|3\.([89]|10))\b"/>

This pattern is highly efficient. It tells the Joomla updater that if the site is running any version of 5, any version of 4, or specific late-stage versions of 3, this update is valid for them.

When to Avoid Regex and Use Multiple Update Blocks

While using regex in a single <update> block is elegant, it isn't always the best choice. You should consider using separate <update> blocks in the following scenarios:

1. Different PHP Requirements

If your version for Joomla 4 requires PHP 8.1, but your Joomla 3 version supports PHP 7.4, you cannot easily distinguish this in a single block. You should use separate blocks so you can utilize the php_minimum tag effectively.

2. Different Extension Packages

If you have a legacy build for Joomla 3 and a completely rewritten modern build for Joomla 4/5, they likely have different download URLs. In this case, separate blocks are mandatory:

<!-- Update for Joomla 3 users -->
<update>
    ... 
    <targetplatform name="joomla" version="3\.[8910]"/>
</update>

<!-- Update for Joomla 4 and 5 users -->
<update>
    ... 
    <targetplatform name="joomla" version="[45]\..*"/>
</update>

Frequently Asked Questions

Can I use the asterisk (*) as a wildcard in the version attribute?

Yes, but remember that Joomla interprets the string as a regex. In regex, * means "zero or more of the preceding character." If you want a wildcard for "any characters," you actually need .*. However, using word boundaries (\b) or simple major version numbers is usually cleaner.

Why is my update not showing up even though the regex is correct?

Joomla caches update information. Ensure you have cleared the Joomla Update cache by going to Extensions > Manage > Update and clicking "Clear Cache" and then "Find Updates." Also, ensure your extension and element names in the XML exactly match your manifest file.

Does this work for all extension types?

Yes. Whether you are developing a component, module, plugin, or template, the Joomla Update System uses the same ExtensionAdapter logic to process the <targetplatform> tag.

Wrapping Up

Using regex in your Joomla update server is a powerful way to streamline your development workflow. By using the pattern (4|3\.([89]|10))\b, you can precisely target the transition period between major CMS versions without duplicating code blocks.

Always remember to escape your dots and use word boundaries to prevent unexpected matching. As Joomla continues to evolve, mastering these small technical nuances will ensure your extensions remain easy to maintain and your users stay up to date with the latest versions of your software.