-
-
- Submit Updated Articles to Bing and Yandex with IndexNow in Joomla
- Add Published and Modified Date Meta Tags to Joomla
- Add Open Graph and Twitter Card Tags to Joomla
- Auto-Generate Meta Descriptions from Article Text in Joomla
- Add Noindex to Specific Pages in Joomla
- Verify Your Joomla Site with Google Search Console
-
- Add a View as Markdown Link to Joomla Articles
- Display the Last Modified Date in Joomla Articles
- Embed Iframes in Joomla
- Automatically Link Twitter (X) @mentions in Joomla Articles
- Open External Links in a New Tab in Joomla
- Display Estimated Reading Time in Joomla Articles
- Replace Old URLs in Joomla
- Search and Replace in Joomla
-
- Add a Footer Line to the Joomla Administrator
- Show a Staging Banner in the Joomla Administrator
- Remove the "All" Option from Admin List Limits in Joomla
- Add a Cookie Consent Banner to Joomla
- Make the Administrator Navigation Sticky in Joomla
- Add Google Fonts to Joomla
- Add a Facebook Messenger Chat Button to Joomla
- Add a Reading Progress Bar to Joomla
- Add a Custom Scrollbar to Joomla
- Show Confetti on a Thank You Page in Joomla
- Add Smooth Scrolling to Joomla
- Add a Back to Top Button in Joomla
- Add a WhatsApp Chat Button in Joomla
-
- Protect the Administrator with a Secret URL Key in Joomla
- Show a Welcome Message on First Login in Joomla
- Log Out Idle Administrators in Joomla
- Assign New Users to a Different User Group Automatically in Joomla
- Redirect Visitors by Country in Joomla
- Redirect Users After Login by User Group in Joomla
- Block User Registration with Certain Usernames in Joomla
- Block User Registration by Country in Joomla
- Block User Registration by Email Address in Joomla
- Block User Registration by IP Address in Joomla
- Remove the Forgot Password and Username Links in Joomla
- Remove the Generator Meta Tag in Joomla
- Let Users Log In with Their Email Address in Joomla
- Block Traffic by Country in Joomla
- Block Bot Traffic in Joomla
- Block Traffic by IP Address in Joomla
PHP
Change how Joomla behaves with a few lines of PHP, from redirects to custom logic, with automatic protection if a snippet ever fails.
PHP snippets execute server-side code during Joomla's page generation cycle, before any HTML is sent to the browser. They are suited for tasks that require access to Joomla's internals: setting up custom redirects, querying the database, modifying how Joomla behaves on specific pages, integrating with external APIs, or running any logic that must happen on the server rather than in the browser.
How to Create a PHP Snippet
To learn how to run a custom PHP snippet in Joomla, follow the steps below:
- Log in to your Joomla administrator
- Go to Components → Tassos Code Snippets
- Click New
- Enter a descriptive Title (e.g. "Redirect Non-Logged-In Users")
- Select PHP as the Code Type.
- Choose the Insertion Method
- To auto-insert the snippet to a predefined location, select Auto-Insert.
- To run the snippet manually via a shortcode, select Shortcode.
- When using Auto-Insert, unlike other snippet types, PHP snippets do not use layout positions like Header or Footer. Instead, they have the following locations:
- Site Page Load: The snippet runs on every frontend request during the
onAfterRouteJoomla event, the earliest point in the page lifecycle when routing and component information is available. This is the default and covers most use cases. - Admin Page Load: The snippet runs on every administrator request, at the same point. That includes the login page when the snippet's Access is Public. Part of Code Snippets Pro.
- Site and Admin Page Load: The snippet runs on both the frontend and the administrator. Part of Code Snippets Pro.
- On Demand: Coming Soon
- Via a Webhook: Coming Soon
- Site Page Load: The snippet runs on every frontend request during the
- When using the Shortcode insertion method, place
{tcs snippet.alias}anywhere Joomla processes content on the frontend: in articles, modules, or component output. Shortcodes are not replaced in the administrator. - Write your code in the editor without including the opening
<?phpor closing?>tags. - Open the Conditional Logic tab to restrict which pages or users the snippet runs on. Leave it empty to run it site-wide. Learn more in Using Snippet Logic.
- Set Status to Published and click Save & Close.
Example
By default your code runs at the onAfterRoute event. To execute code at a different point in the page lifecycle, register an event callback using Joomla's Factory class:
use Joomla\CMS\Factory;
$app = Factory::getApplication();
$app->registerEvent('EVENT_NAME', function()
{
// your code here
});
For example, to hook into onUserAfterSave:
use Joomla\CMS\Factory;
$app = Factory::getApplication();
$app->registerEvent('onUserAfterSave', function($user)
{
// $user contains the saved user data
});
Or to modify the full HTML output of the page via onAfterRender:
use Joomla\CMS\Factory;
$app = Factory::getApplication();
$app->registerEvent('onAfterRender', function() use ($app)
{
$body = $app->getBody();
$body = str_replace('search-text', 'replace-text', $body);
$app->setBody($body);
});
You can register multiple event callbacks within a single PHP snippet, each responding to different lifecycle events. See the official Joomla Plugin Events documentation for a complete list of available events.
Automatic Error Protection
PHP snippets include built-in safety mechanisms to protect your site from errors. If your PHP snippet throws an error or exception during execution, the snippet is automatically disabled, so it can't break your site on the next page load. Its status changes to Auto-Disabled in the snippets list.
Since version 1.0.2 this also covers fatal errors that PHP doesn't throw as exceptions: declaring a function or class that already exists, running out of memory, or hitting the PHP time limit. That matters most in the administrator, where a snippet that fails on every request would otherwise lock you out of the very screen you need to disable it.
When a snippet fails:
- The error message and stack trace are stored with the snippet and shown at the top of its edit screen.
- A log file is written under
administrator/logs/tassos_code_snippets/, one file per snippet. You can read it from the component's Error Logs page. - The site's administrator email address receives a notification with the error details.
The log file and the email can be turned off in the component's Options, under Log Errors and Notify Admin.
Once you see the error, you can:
- Go to the backend (Components → Tassos Code Snippets)
- Review the error message and stack trace to identify the issue
- Edit the snippet to fix the problem
- Re-enable the snippet by publishing it again
Two things slip past the auto-disable: a plain exit() or die(), which ends the request without an error, and a loop that only waits (a sleep() or a slow HTTP call), which never hits PHP's time limit on Linux. If one of those locks you out, turn on safe mode to pause every snippet while you fix it.
Accessing Shortcode Attributes In Your Snippet as Variables
If you are writing a PHP snippet you can access the shortcode attributes as PHP variables based on the name of the attribute you added to your shortcode. For example, if your attribute is named "name" you can access that attribute in PHP as $name.
Basic Example
Given this shortcode:
{tcs snippet.my-php --name=Tassos}
You can use $name directly in your PHP snippet:
echo 'Hello, ' . $name;
// Output: Hello, Tassos
Multiple Attributes
You can pass as many attributes as you need:
{tcs snippet.greeting --name=Tassos --color=blue --age=40}
All attributes become available as variables:
echo $name; // Tassos
echo $color; // blue
echo $age; // 40
Best Practices
Always Check Document Type
This is extremely important: Unlike other snippet types (HTML, CSS, JS) which automatically run only when the document type equals HTML, PHP snippets do not perform this check automatically. This means PHP snippets can execute on:
- Regular HTML page requests
- AJAX requests
- XML feeds
- JSON API responses
- Raw responses
- Any other document type
Without proper document type checking, your PHP snippet can inadvertently break:
- Extensions that rely on AJAX functionality
- API endpoints that return JSON data
- RSS/XML feeds
- Third-party integrations
- Component AJAX handlers
How to Check Document Type
In most cases, your PHP code should only run on standard HTML page requests. To ensure this, you must explicitly check the document type in your code.
Without document type check (runs on every request type):
use Joomla\CMS\Factory;
$app = Factory::getApplication();
$app->registerEvent('onAfterRender', function() use ($app)
{
$body = $app->getBody();
$body = str_replace('foo', 'bar', $body);
$app->setBody($body);
});
With document type check (runs only on HTML pages):
use Joomla\CMS\Factory;
$app = Factory::getApplication();
$doc = $app->getDocument();
$app->registerEvent('onAfterRender', function() use ($app, $doc)
{
// Only run on HTML page requests
if ($doc->getType() !== 'html')
{
return;
}
$body = $app->getBody();
$body = str_replace('foo', 'bar', $body);
$app->setBody($body);
});
Common document types in Joomla:
html— Standard web pagesjson— JSON API responsesraw— Raw output (often used by AJAX)xml— XML feedsfeed— RSS/Atom feeds
Always include this document type check unless you specifically need your code to run on non-HTML requests.
Check the Client Too
A snippet on Site and Admin Page Load runs the same code on the frontend and in the administrator. When part of it belongs to one side only, check the client first:
use Joomla\CMS\Factory;
$app = Factory::getApplication();
if ($app->isClient('administrator'))
{
// Runs in the administrator only
}
if ($app->isClient('site'))
{
// Runs on the frontend only
}
Using Joomla Objects
PHP snippets support use namespace imports, so you can access Joomla classes directly. Here are the most commonly used objects:
use Joomla\CMS\Factory;
// Application object
$app = Factory::getApplication();
// Document object
$doc = $app->getDocument();
// Database object
$db = Factory::getDbo();
// Current user object
$user = $app->getIdentity();
You can also import any other Joomla or third-party namespace class at the top of your snippet:
use Joomla\CMS\Factory;
use Joomla\CMS\Uri\Uri;
use Joomla\CMS\Language\Text;
$app = Factory::getApplication();
echo Uri::root();
echo Text::_('COM_CONTENT_READ_MORE');
Reusing Code Across Snippets
Because all PHP snippets execute in the same PHP request, anything declared in one snippet — functions, variables, or classes — is available to every other snippet that runs after it. This is a powerful pattern for abstracting shared logic into a single place and reusing it across multiple snippets.
The most reliable way to share code is to define a static class in one snippet and call its methods from any other snippet.
Snippet A — declare the shared helper class (e.g. site-helpers, set to auto-insert on Site Page Load):
class SiteHelpers
{
public static function getCurrentUserName()
{
use Joomla\CMS\Factory;
$user = Factory::getApplication()->getIdentity();
return $user->name ?: 'Guest';
}
public static function isLoggedIn()
{
use Joomla\CMS\Factory;
return !Factory::getApplication()->getIdentity()->guest;
}
}
Snippet B — use the helper:
if (SiteHelpers::isLoggedIn())
{
echo 'Welcome, ' . SiteHelpers::getCurrentUserName();
}
Snippet C — use the same helper:
if (!SiteHelpers::isLoggedIn())
{
use Joomla\CMS\Router\Route;
$app = Factory::getApplication();
$app->redirect(Route::_('index.php?option=com_users&view=login'));
}
Security Considerations
For security reasons, PHP snippets automatically block certain dangerous PHP functions. If your code contains any of these functions, the snippet will not execute:
Blocked functions:
fopen,popen— File operationsunlink,rmdir— Delete operationsdl— Load extensionsescapeshellarg,escapeshellcmd— Shell escapingexec,passthru,shell_exec,system— Command executionproc_close,proc_open,pcntl_exec— Process controlsymlink— Create symbolic linkseval,create_function— Dynamic code execution- Backticks (
`) — Shell command execution
Note: curl_exec() is allowed for making HTTP requests to external APIs.
If you need functionality that requires these functions, consider:
- Using Joomla's built-in APIs (e.g.
JFile,JFolderfor file operations) - Using
JHttporcurl_exec()for external requests - Restructuring your code to use safe alternatives
Troubleshooting
PHP Snippet Not Executing
- Check the Location: A snippet on Site Page Load never runs in the administrator, and one on Admin Page Load never runs on the frontend
- Check event hook: Ensure you're using the correct event for your needs
- Check conditions: Verify conditional logic isn't preventing execution
- Look for errors: Enable error reporting and check error logs
- Test isolation: Temporarily remove other snippets to identify conflicts
Learn more in Why your PHP snippet isn't running.
White Screen of Death
A PHP error in a snippet can leave a page blank:
- If the snippet caused a fatal error, it's already disabled. Open Components → Tassos Code Snippets and read the error at the top of its edit screen.
- If pages still hang or stay blank, turn on safe mode in
configuration.php. Every snippet pauses and the site comes back. - Enable error reporting in Joomla's Global Configuration to see the exact error, then fix the snippet and remove the safe mode line.
Learn more in How to debug PHP errors in a snippet.
403 Error When Saving a Snippet
If a 403 Forbidden error appears the instant you click Save, a Web Application Firewall (WAF) is blocking the request. It inspects what you submitted, sees PHP code, mistakes it for an injection attack (SQL, LDAP, and similar), and rejects the request before it ever reaches Joomla. This is not a Code Snippets, file permission, or .htaccess problem.
Two firewalls commonly cause this:
- Server-level ModSecurity (for example the Comodo ruleset on Plesk or cPanel). Open your host's ModSecurity audit log to find the exact rule that fired, then whitelist or disable that specific rule. Whitelisting your IP alone may not help, because some rulesets run before the IP whitelist. If you can't edit the rules yourself, ask your host to whitelist the request.
- Akeeba Admin Tools WAF. Go to Components → Admin Tools → Web Application Firewall → Exceptions and add an exception for
administrator/index.phpwithoption=com_tassoscodesnippets. The Admin Tools → WAF → Security Exceptions Log shows you which rule was triggered.