Blog

  • Fix Class JRequest Not Found in Joomla 4, 5, and 6

    Fix Class JRequest Not Found in Joomla 4, 5, and 6

    Class ‘JRequest’ not found means your extension, template override, or custom PHP still calls the removed Joomla 1.x/2.x/3.x request helper. JRequest was deprecated for years and is gone in Joomla 4+. It is not restored by the Behaviour – Backward Compatibility plugins. Replace every call with the Joomla Input API: Factory::getApplication()->getInput() (or $this->input inside a core MVC controller).

    This is one of the most common fatals after a Joomla 3 to 4 upgrade, and it still appears on Joomla 5 and 6 when an old module, plugin, or child-template override was never updated. Official Input docs: Joomla Input.

    What you will learn

    • Why Joomla removed JRequest and why the compat plugin will not bring it back
    • Exact old → new code replacements for getVar, getInt, getCmd, and related helpers
    • How to find every remaining JRequest usage on the server
    • Controller, module, plugin, and template override patterns that stay valid on Joomla 6
    • How filters work so you do not silently break integers, HTML, or form arrays

    Why the error appears after upgrading

    On Joomla 3, JRequest::getVar('foo') still ran (with deprecation noise in newer 3.x). On Joomla 4, 5, and 6 the class file is not loaded. PHP throws a fatal error as soon as that line executes.

    Typical sources:

    • Custom components and modules written for Joomla 2.5 / 3
    • Abandoned third-party extensions
    • Template overrides copied from an old html/ folder
    • One-off scripts in the site root or a cli/ helper

    The Behaviour – Backward Compatibility plugins bridge selected later APIs. They do not reintroduce JRequest. See our Behaviour – Backward Compatibility guide for what those plugins actually restore.

    Old JRequest call Modern replacement Notes
    JRequest::getVar('x') $input->get('x', null, 'STRING') or typed helper Default filter for get() is CMD, not “anything goes”
    JRequest::getInt('id') $input->getInt('id', 0) Always pass a default
    JRequest::getCmd('task') $input->getCmd('task', '') Safe for option/task style tokens
    JRequest::getBool('check') $input->getBool('check', false) Watch string "false" quirks; prefer real booleans
    JRequest::getWord('layout') $input->getWord('layout', '') Letters and underscore only
    JRequest::getFloat('price') $input->getFloat('price', 0.0) Or getDouble where available
    JRequest::getMethod() $input->getMethod() / server method checks Prefer framework request method helpers when available
    JRequest::setVar('x', $v) $input->set('x', $v) Use def() when you only want to set if missing

    Step 1: Capture the full stack trace

    Turn on error reporting on staging (or read administrator/logs/ and the PHP / server error log). The fatal line path tells you whether to edit an extension, a template override, or a custom file.

    Example message:

    Error: Class "JRequest" not found
    Calling: templates/YOUR_TEMPLATE/html/.../default.php:42

    Fix that file first. Searching the whole tree still matters because several files may call JRequest.

    Step 2: Find every JRequest usage

    From the site root (SSH) or a project-wide search in your IDE:

    grep -R --include="*.php" -n "JRequest" .
    # or
    rg -n "JRequest" -g "*.php"

    Also search case variants and legacy imports:

    rg -n "jrequest|JRequest::" -g "*.php" -i

    Skip libraries/ core and vendor trees unless you overwrote core (you should not). Focus on components/, modules/, plugins/, templates/, and any custom src/ folders.

    Step 3: Replace with Factory::getApplication()->getInput()

    Preferred modern form (Joomla 4, 5, and forward-compatible with Joomla 6 guidance):

    use Joomla\CMS\Factory;
    
    $input = Factory::getApplication()->getInput();
    $data  = $input->get('data', '', 'STRING');
    $id    = $input->getInt('id', 0);
    $task  = $input->getCmd('task', '');

    Avoid the older property access when you can:

    // Works on many CMS installs, but the public ->input property is deprecated for new code
    $input = Factory::getApplication()->input;

    Joomla’s migration notes recommend getInput() instead of reading the input property directly. See Joomla 5.4 → 6 deprecations.

    Old code

    $data = JRequest::getVar('data');
    $id   = JRequest::getInt('id');
    $view = JRequest::getCmd('view');

    New code

    use Joomla\CMS\Factory;
    
    $input = Factory::getApplication()->getInput();
    $data  = $input->get('data', null, 'STRING');
    $id    = $input->getInt('id', 0);
    $view  = $input->getCmd('view', '');

    Step 4: Use $this->input inside MVC controllers

    If your class extends Joomla\CMS\MVC\Controller\BaseController, Input is already available:

    $id   = $this->input->getInt('id', 0);
    $data = $this->input->post->get('jform', [], 'array');

    Do not call Factory::getApplication() again unless you are outside that controller context.

    Step 5: Match filters to the old intent

    Blindly changing getVar to $input->get('name') can break values because the default filter is CMD (strips many characters). Pick the filter that matches the old third argument or helper name.

    • INT / getInt for IDs and counts
    • CMD / getCmd for option, view, task, layout tokens
    • STRING / getString for normal text (HTML tags stripped)
    • HTML when you must keep markup more carefully (still sanitize before output)
    • ARRAY for jform style posts: $input->post->get('jform', [], 'array')
    • RAW only when you fully trust and validate afterward

    Typed helpers keep code readable:

    $name = $input->getString('name', '');
    $qty  = $input->getInt('quantity', 0);
    $ok   = $input->getBool('agree', false);

    Step 6: GET vs POST vs files

    Use nested input when the source matters:

    $getOnly  = $input->get->get('p1', 0, 'int');
    $postOnly = $input->post->get('p1', 0, 'int');
    $files    = $input->files->get('jform');

    On SEF sites, routing values like option and view come from the router as well as query strings. Prefer the main $input->getCmd('view') unless you intentionally need raw GET only.

    Step 7: Fix template overrides and modules

    Overrides under templates/TEMPLATE/html/ often keep decade-old snippets. After replacing JRequest:

    1. Clear Joomla cache
    2. Reload the exact menu item that crashed
    3. Re-run the project-wide search until zero hits remain in site-owned PHP

    For modules using a modern Dispatcher, inject Input (or read it from the application) instead of static JRequest calls. The official Input manual includes a full module sample.

    Step 8: Prefer updates over patches when the vendor still exists

    If the fatal sits inside a third-party extension:

    1. Install the vendor’s Joomla 4/5/6 native package
    2. Only then patch local forks if the product is abandoned
    3. Document every local patch so the next update does not overwrite your fix blindly

    A one-line site patch is fine for an override you own. It is a poor long-term plan inside administrator/components/com_oldthing/ that you did not write.

    Situation Best action
    Your custom module / override Replace with getInput() and commit the change
    Maintained commercial extension Upgrade to the Joomla 4+ package from the vendor
    Abandoned extension Patch if small, or replace the extension
    Only one leftover JRequest in a child template Fix the override; do not hack core

    Key takeaways

    1. JRequest does not exist on Joomla 4, 5, or 6. The fatal is expected until you remove the calls.
    2. Use Factory::getApplication()->getInput() or $this->input in MVC controllers.
    3. Map old helpers to typed getters and explicit filters. Default get() uses CMD.
    4. Search the whole site tree. One fixed file is not enough if overrides still call JRequest.
    5. Compatibility plugins will not resurrect JRequest. Update the code.

    Frequently asked questions

    What does Class ‘JRequest’ not found mean in Joomla 4?

    PHP tried to call the removed JRequest class. Update that code to the Input API before the page can load.

    Does this still happen on Joomla 5 and Joomla 6?

    Yes. Any leftover JRequest call fatals on current majors the same way.

    Will Behaviour – Backward Compatibility fix JRequest?

    No. Those plugins bridge other legacy pieces. JRequest must be replaced in code.

    Is JFactory::getApplication()->input still OK?

    It often still works, but new code should call getInput(). Prefer use Joomla\CMS\Factory over legacy JFactory aliases when you touch the file.

    Why did my value become empty after switching to input->get()?

    You probably hit the default CMD filter. Use STRING, INT, or another filter that matches the old getVar intent.

    How do I read jform POST data now?

    Use $input->post->get('jform', [], 'array'), then validate in the model the same way core components do.

    Can Infyways fix this on a client site?

    Yes. If you need a Joomla 3 to 4/5/6 upgrade with extension and override cleanup, contact Infyways.

  • Fix Joomla 500 Error on mod_rewrite

    Fix Joomla 500 Error on mod_rewrite

    A Joomla 500 error on mod_rewrite is almost always Apache rejecting a directive in your root .htaccess file right after you enable Search Engine Friendly URLs or “Use URL rewriting.” The browser only shows Internal Server Error. The Apache error log names the real cause: usually Options +FollowSymLinks, a missing AllowOverride, disabled mod_rewrite, or a bad RewriteBase.

    This guide is the fix path we use on Joomla 4, 5, and 6 sites (and older 3.x still on Apache). It complements our deeper Joomla .htaccess guide and the Joomla SEF URL setup.

    What you will learn

    • How to prove the 500 is caused by .htaccess / mod_rewrite in under two minutes
    • The exact Apache log messages that map to each fix
    • How to repair FollowSymLinks, AllowOverride, mod_rewrite, and RewriteBase
    • How to rebuild a clean Joomla .htaccess from htaccess.txt
    • What to check in Global Configuration and conflicting extensions

    Why Joomla shows 500 after enabling URL rewriting

    Joomla SEF without rewriting still works with index.php in the URL. Turning on Use URL rewriting tells Joomla to drop index.php and rely on Apache mod_rewrite plus the rules in .htaccess (renamed from the shipped htaccess.txt).

    If Apache cannot apply those rules, every front-end request can return HTTP 500. The administrator may still load if you open it with a direct /administrator/ path, which is a useful clue.

    Symptom / log clue Most likely cause First fix
    Site dies only after enabling URL rewriting .htaccess active and rejected Rename .htaccess to restore the site, then fix the directive
    Options not allowed here or FollowSymLinks error Host forbids Options in .htaccess Comment out Options +FollowSymLinks
    .htaccess ignored, URLs 404 AllowOverride None Set AllowOverride All (or FileInfo Options) in the vhost
    Invalid command RewriteEngine mod_rewrite not loaded Enable the module and restart Apache
    Works in root, breaks in subdirectory Wrong RewriteBase Set RewriteBase /subfolder/
    Works until a security extension ships custom rules Broken rewrite block from a plugin Disable the extension, restore core SEF section

    Step 1: Prove it is the .htaccess file

    1. Via FTP or file manager, rename root .htaccess to .htaccess.bak.
    2. Reload the homepage.
    3. If the 500 disappears (even if SEF URLs look ugly again), the rewrite file is the culprit.

    Do not leave rewriting enabled in Global Configuration while .htaccess is missing, or you will get 404s on pretty URLs. Temporarily turn Use URL rewriting off, then continue.

    Step 2: Read the Apache error log

    Guessing wastes time. Open today’s error log (cPanel “Errors”, Plesk logs, /var/log/apache2/error.log, or your host’s equivalent) and reload the site once.

    Look for lines that mention .htaccess, Options, RewriteEngine, or AllowOverride. Match them to the table above before editing Joomla again.

    Step 3: Fix Options +FollowSymLinks (the most common 500)

    Joomla’s shipped htaccess.txt includes Options +FollowSymLinks because mod_rewrite historically needed it. Many shared hosts already set symlink policy in the virtual host and forbid changing Options from .htaccess. Apache then returns 500 with “Options not allowed here.”

    In your .htaccess, comment the line:

    # Options +FollowSymLinks

    Some hosts prefer:

    Options +SymLinksIfOwnerMatch

    Official Joomla docs note that if commenting FollowSymLinks restores the site and SEF still works, your administrator already set the option server-side and you should leave it commented. See Preconfigured htaccess and Enabling SEF URLs.

    Step 4: Confirm AllowOverride permits .htaccess

    If you control the server (VPS, dedicated, local XAMPP/WAMP), open the virtual host or httpd.conf <Directory> block for the site document root and ensure overrides are allowed:

    <Directory "/var/www/html">
        AllowOverride All
        Require all granted
    </Directory>

    On shared hosting you usually cannot edit this. If AllowOverride is None, ask support to enable .htaccess overrides for Options and FileInfo, or to enable Joomla URL rewriting for your account.

    Restart Apache after config changes.

    Step 5: Enable mod_rewrite

    On Debian/Ubuntu:

    sudo a2enmod rewrite
    sudo systemctl restart apache2

    On RHEL/Alma/CloudLinux, ensure this line is uncommented in the Apache config and restart:

    LoadModule rewrite_module modules/mod_rewrite.so

    Quick PHP check on a throwaway file (delete after testing):

    <?php
    print_r(apache_get_modules());

    If mod_rewrite is missing from the list (or apache_get_modules is unavailable under PHP-FPM), confirm with your host. Without the module, leave Joomla URL rewriting off. SEF can still run with index.php in the path.

    Step 6: Rebuild .htaccess from htaccess.txt

    Corrupt or hand-edited rewrite blocks are a frequent source of 500s. Joomla ships a known-good template as htaccess.txt in the site root.

    1. Download a fresh copy from your Joomla version package if the root file is missing.
    2. Copy htaccess.txt to .htaccess (merge carefully if you already have custom redirects).
    3. Comment Options +FollowSymLinks if Step 3 applied.
    4. Keep core SEF rules inside the <IfModule mod_rewrite.c> block.

    Core SEF section (simplified shape; prefer the full file from your Joomla version):

    <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} !^/index\.php
    RewriteCond %{REQUEST_URI} /component/|(/[^.]*|\.(php|html?|feed|pdf|vcf|raw))$ [NC]
    RewriteRule .* index.php [L]
    </IfModule>

    Never paste truncated snippets that smash the title or other text into the middle of a RewriteCond line. That alone will 500 the site.

    Step 7: Set RewriteBase for subdirectory installs

    If Joomla lives at https://example.com/shop/, set:

    RewriteBase /shop/

    Root installs usually use RewriteBase /. Wrong base values produce 500s or broken asset paths after rewriting is enabled.

    Step 8: Align Global Configuration

    In System → Global Configuration → Site (wording varies slightly by Joomla 4/5/6):

    • Search Engine Friendly URLs: Yes
    • Use URL rewriting: Yes only after .htaccess works
    • Adds Suffix to URL: optional
    • Unicode Aliases: as needed for non-ASCII

    Save, clear Joomla cache, then test a menu item URL. If enabling rewriting brings the 500 back, return to Steps 2 and 3. Keep SEF on and rewriting off until Apache is clean.

    Step 9: PHP-FPM Authorization line and host extras

    Some hosts need the HTTP Authorization pass-through for API or extension auth:

    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

    That line belongs in the core SEF section of a current Joomla .htaccess. Removing it rarely causes a 500, but a broken duplicate of it can. Also watch for host-injected blocks (LiteSpeed, Imunify, custom php_flag lines) that are invalid on your PHP handler. Comment suspect lines one at a time while watching the error log.

    Step 10: Rule out extensions and security plugins

    After the core file works, re-enable custom redirects and security rules carefully.

    • Disable recently installed SEF, security, or “firewall” extensions that write rewrite rules.
    • Check for a second .htaccess in /administrator or a subdomain docroot.
    • Restore from backup if a malware cleanup left garbage rewrite conditions.

    If the site was compromised, fix rewriting only after a clean restore. See our guide on repairing a hacked Joomla website.

    Nginx and IIS note

    mod_rewrite is an Apache module. Nginx uses try_files toward index.php. IIS uses web.config. A “mod_rewrite 500” on those stacks usually means you are reading Apache advice on the wrong server. Ask the host which web server fronts PHP before editing .htaccess.

    Key takeaways

    1. A Joomla 500 right after enabling URL rewriting is an Apache .htaccess problem until the error log proves otherwise.
    2. Commenting Options +FollowSymLinks fixes the majority of shared-hosting cases.
    3. Rename .htaccess to restore the site, then rebuild from htaccess.txt.
    4. Enable mod_rewrite and correct AllowOverride / RewriteBase before turning rewriting back on in Joomla.
    5. Keep Global Configuration rewriting off until a homepage request returns 200 with the fixed file in place.

    Frequently asked questions

    Why do I get a Joomla 500 error when I enable mod_rewrite?

    Apache is rejecting a directive in .htaccess, most often Options +FollowSymLinks, or mod_rewrite is not allowed. Check the error log, then comment FollowSymLinks and confirm AllowOverride.

    Is the administrator also down during a rewrite 500?

    Not always. /administrator/ can still load while the public site 500s. That pattern strongly points at front-end rewrite rules rather than a total PHP crash.

    Should I delete .htaccess permanently?

    No. Use a rename only to diagnose. Joomla needs a valid .htaccess for clean SEF URLs and basic exploit blocking from the core template.

    Does this apply to Joomla 5 and Joomla 6?

    Yes. The SEF and htaccess.txt flow is the same family on Joomla 4, 5, and 6. Always copy htaccess.txt from your exact version package.

    What if I am on Nginx?

    Do not chase mod_rewrite. Configure Nginx try_files $uri $uri/ /index.php?$args; (or your host’s Joomla snippet) instead of Apache .htaccess.

    Can a plugin cause a rewrite 500?

    Yes. Security and SEF extensions sometimes append invalid rules. Disable recent extensions, restore the core SEF block, then re-add custom rules one by one.

    Where can I get a clean Joomla htaccess file?

    From the htaccess.txt in your Joomla root or install package. Our htaccess for Joomla article covers version-specific notes and hardening.

  • How to Backup a Joomla Website

    How to Backup a Joomla Website

    Backing up a Joomla website means capturing both the site files and the database in a form you can restore on the same host or a new one. A usable backup is not a folder zip of images/ alone, and it is not a host snapshot you have never tested. For most Joomla 4, 5, and 6 sites the standard tool is Akeeba Backup (free Core or paid Professional), plus an off-site copy and a restore drill.

    This is the complete Infyways runbook: strategy, what to include, Akeeba install and configuration, Backup Now, off-site storage, Kickstart restore, automation, and the mistakes that turn “we have a backup” into downtime.

    What you will learn

    • What belongs in a real Joomla backup (and what you can safely exclude)
    • How Core and Professional Akeeba Backup differ for solo sites vs agencies
    • Step-by-step install, configure, Backup Now, download, and Kickstart restore
    • How to schedule backups, apply quotas, and keep archives off the public web root
    • When host backups, manual SQL dumps, and CLI jobs are better (or worse) than Akeeba

    What a complete Joomla backup must include

    Joomla stores content and settings in MySQL/MariaDB (or another supported DB). Templates, media, extensions, and configuration.php live on disk. Restore either piece alone and the site breaks.

    Piece Why it matters Typical location
    Database Articles, users, menus, extension settings, SEF data MySQL/MariaDB (prefix from configuration.php)
    Site files Core, templates, extensions, media, overrides Document root (and sometimes private folders outside it)
    configuration.php DB credentials, paths, secret, mail, caching Site root (rewritten during restore)
    Restoration script Lets you install the archive without a blank Joomla package Embedded by Akeeba inside the archive

    Optional but valuable: a written note of PHP version, Joomla version, and critical extensions. That context speeds recovery after a failed major upgrade.

    Backup strategy before you click Backup Now

    Tooling fails when strategy is missing. Use a simple policy every production site can follow.

    1. 3-2-1 rule: at least three copies, on two different media/systems, with one off-site (S3, Drive, another server, or downloaded to a machine that is not the web host).
    2. Before every risky change: Joomla update, PHP bump, template change, migration, or security incident response.
    3. On a schedule: daily or weekly depending on how often content changes. Ecommerce and membership sites usually need daily.
    4. Test restore quarterly: a backup you have never restored is a hope, not a plan.
    5. Retention: keep several generations (for example 7 daily + 4 weekly) so a bad backup does not overwrite the last good one.
    Method Best for Limits
    Akeeba Backup Core (free) Most sites: one-click full backup, Kickstart restore/migrate No cloud push, limited automation, no encrypted JPS
    Akeeba Backup Professional Agencies, shops, scheduled jobs, S3/Drive/SFTP, CLI Paid subscription
    Host panel backup / snapshot Emergency host-level recovery Often opaque; hard to move hosts; may exclude remote DBs
    Manual files + phpMyAdmin dump Tiny sites or one-off cloning Easy to miss files; painful restore; no integrated installer
    Server CLI (mysqldump + rsync/tar) DevOps-managed VPS You own scripting, encryption, and restore docs

    Infyways recommendation for typical Joomla sites: Akeeba as the primary portable backup, host snapshots as a secondary safety net, and at least one copy downloaded or pushed off the origin server.

    Step 1: Install Akeeba Backup

    1. Download the current Akeeba Backup Core (or Professional) package from the official Akeeba product page. Match the package to your Joomla major version.
    2. In the administrator go to System → Install → Extensions (wording varies slightly on Joomla 4/5/6).
    3. Upload the package and confirm a clean install with no PHP fatal.
    4. Open Components → Akeeba Backup. On first run, accept the configuration wizard / automatic configuration so Akeeba tunes itself to your server.

    If installation fails on PHP version or memory, fix the server requirements first. Do not force an ancient Akeeba build onto a new Joomla release.

    Step 2: Configure output directory and security

    Open Akeeba Backup Configuration (profile settings).

    • Output directory: prefer a folder outside the public web root when the host allows it. If you must use a web-accessible path, use a random folder name and block HTTP access with .htaccess / server rules. Never leave dated .jpa / .zip files downloadable by the world.
    • Temporary directory: a writable temp path Akeeba can use during archival (often derived from site tmp). Confirm the folder is writable by PHP.
    • Archiver: JPA is the Akeeba-native format and usually the best default. ZIP is fine when you need wide tooling support. JPS (AES-encrypted) is a Professional feature for sensitive sites.
    • Database dump options: keep extended INSERTs enabled when your host supports them; include procedures/triggers if your extensions use them.

    Save the profile. Create a second profile later if you need “files only” or “database only” jobs (Professional), or a lighter profile that excludes bulky cache folders.

    Step 3: Set filters (exclude junk, keep what restores)

    Default full-site backup is correct for disaster recovery. Trim noise so jobs finish and archives stay manageable:

    • Exclude cache directories that regenerate (cache/, template cache, image-cache plugins) unless you have a reason to keep them.
    • Exclude old backup archives inside the output folder so backups do not nest forever.
    • Exclude giant log directories and unused tmp dumps.
    • Do not exclude images/, template overrides, or extension folders you still use.

    Professional adds regex filters, off-site directory includes, and extra database includes for multi-DB setups.

    Step 4: Run Backup Now

    1. Go to Components → Akeeba Backup → Backup Now.
    2. Add a short description (for example pre-j5-upgrade-2026-09-17).
    3. Start the backup and leave the browser tab open until it reports success. Do not navigate away on shared hosts with aggressive session limits; if the UI stalls, check Akeeba’s log and ALICE analyser rather than starting five parallel jobs.
    4. Open Manage Backups / Administer Backup Files and confirm the archive size looks sane (not a few kilobytes).

    If the job fails with timeout, memory, or “AJAX” errors, lower the partitioning size in Configuration, increase PHP max_execution_time / memory where allowed, or run during low traffic. Large media sites often need tuned chunk sizes more than they need a different product.

    Step 5: Download and store a copy off the server

    A backup that exists only on the same disk as the live site dies with the server.

    1. Download the archive from Manage Backups, or pull it over SFTP.
    2. Store it on encrypted disk, object storage, or another host.
    3. With Professional, configure post-processing to Amazon S3, Google Drive, OneDrive, Dropbox, SFTP, or other supported remotes, then enable remote quotas so old cloud copies rotate.
    4. Apply local quota rules so the web disk does not fill with archives.

    Step 6: Restore with Kickstart (the correct way)

    Do not treat an Akeeba archive like a random zip of a fresh Joomla package. Akeeba embeds a restoration script. The standard portable restore path:

    1. Provision an empty directory (or clean target) on the destination server with a working PHP and a MySQL/MariaDB database ready.
    2. Upload the backup archive (.jpa, .jps, or .zip) and the current Kickstart PHP file from Akeeba into that directory.
    3. Browse to kickstart.php, extract the archive, then continue into the restoration (Angie) wizard.
    4. Enter the new database credentials, site URL, and confirm configuration.php is written correctly.
    5. Delete Kickstart and leftover installation / restoration files after a successful login.
    6. Clear caches, recheck HTTPS, and test key pages (home, login, checkout, admin).

    Professional can also restore some full-site archives from inside the component on the same site. Site Transfer Wizard helps move archives over FTP. For unattended restores, Akeeba UNiTE is the CLI path.

    If you only have a host “files + SQL” dump without Akeeba’s restoration script, restore files, import SQL, then hand-edit configuration.php. That works, but it is slower and easier to get wrong than Kickstart.

    Step 7: Automate (cron, Scheduled Tasks, CLI)

    Manual Backup Now is perfect before upgrades. Production sites also need automation.

    • Professional: native CLI backup script, Joomla CLI integration (cli/joomla.php), Joomla Scheduled Tasks, front-end / remote backup API, and Remote CLI / UNiTE ecosystems.
    • Core: schedule is limited; many small sites download manually or rely on host jobs plus periodic Akeeba runs.
    • Always verify the first automated job actually produced a remote or downloaded file, not only a green UI message.

    Step 8: Prove the backup with a restore drill

    Quarterly (or after any major profile change):

    1. Restore the latest archive to a staging subdomain or local environment.
    2. Log into administrator, open a few articles, submit a contact form, and place a test order if you run ecommerce.
    3. Note restore time. That number is your real RTO (recovery time objective).
    4. Fix profile filters if something critical was missing.

    Special cases

    Before a Joomla or PHP upgrade

    Take a named full backup, download it off-site, then upgrade. If the site white-screens, restore first and debug on staging. Pair this with our upgrade and security checklists when you move majors.

    After a hack

    Do not blindly restore an infected archive over a cleaned host. Prefer a known-clean backup from before the compromise, then patch and harden. See How to repair a hacked Joomla website.

    Multisite / multiple databases

    Core backs up the main Joomla DB. Professional can include extra MySQL databases and off-site directories when your architecture needs them.

    Very large media libraries

    Exclude regenerated caches, use JPA, tune part size, and consider storing bulky static media in object storage with a separate sync if archives become multi-gigabyte every night.

    Security checklist for backup archives

    • Block web access to the output directory
    • Rotate and delete old archives with quotas
    • Prefer off-site copies for ransomware and host failure
    • Use JPS encryption (Professional) for sensitive data at rest when appropriate
    • Limit who can run Akeeba via Joomla ACL
    • Never commit backup archives to public git repositories

    Key takeaways

    1. A Joomla backup is files + database + a tested restore path, not a random zip of the template.
    2. Akeeba Backup Core covers one-click backup and Kickstart migration; Professional adds cloud, scheduling, CLI, and encryption.
    3. Store at least one copy off the production server and enforce quotas.
    4. Restore with Kickstart (or Pro in-component restore), then delete installer tools.
    5. Run a restore drill. Untested backups fail when you need them.

    Frequently asked questions

    What is the best way to backup a Joomla website?

    Use Akeeba Backup for a portable full-site archive, keep a copy off-site, and test restore with Kickstart. Add host snapshots as a secondary layer.

    Is Akeeba Backup free?

    Akeeba Backup Core is free for standard backup and Kickstart restore. Professional is paid and adds cloud storage, automation, CLI, encrypted JPS, and more.

    Does Akeeba work on Joomla 5 and Joomla 6?

    Yes, when you install a current Akeeba package built for your Joomla major. Always download from Akeeba’s official site, not random mirrors.

    Where should I store Joomla backup files?

    Outside the public web root when possible, plus an off-site copy (S3, Drive, SFTP, or local encrypted disk). Never leave archives openly downloadable.

    How often should I backup Joomla?

    Before every upgrade or risky change, and on a schedule that matches content change rate. Daily is common for shops and membership sites; weekly may suffice for static brochure sites.

    Can I restore an Akeeba backup like a new Joomla install zip?

    No. Use Kickstart (or Professional’s restore tools) so the embedded restoration script can rewrite configuration and import the database correctly.

    Are host cPanel backups enough?

    They help in a host-side disaster but are a poor primary plan for moving hosts or granular recovery. Keep a portable Akeeba archive as well.

    What if Backup Now fails halfway?

    Read the Akeeba log, reduce part size / memory pressure, exclude huge cache folders, and retry. Do not assume a partial archive is restorable.

    Can Infyways set this up for us?

    Yes. We configure Akeeba profiles, off-site storage, and restore drills for Joomla sites. Contact Infyways for backup and maintenance help.

  • How to Show Heureka Reviews on Your Website

    How to Show Heureka Reviews on Your Website

    Heureka reviews on your website come from the Verified by Customers program (Ověřeno zákazníky). Heureka does not give you a public reviews API. You display shop and product ratings with secret-key XML exports, plus official certificate icons and widgets from Heureka administration. The practical path for most stores is a custom Joomla module, WordPress plugin, or CMS integration that syncs those feeds safely and matches your theme.

    Infyways builds that integration. We already shipped a production Joomla module for estilofina.sk. Packages start at USD 149. This guide covers DIY XML setup and when to hire us for Joomla, WordPress, Magento, OpenCart, Shopify, or custom PHP.

    What you will learn

    • How Verified by Customers shop and product XML exports work (CZ and SK)
    • How official badges and widgets differ from parsed review lists
    • The legal notice Heureka expects when you republish verified reviews
    • Why caching and cron sync beat live XML on every page view
    • What Infyways delivers in a paid Heureka reviews plugin or module from USD 149

    Why put Heureka reviews on your own site

    Heureka is the trust layer for many Czech and Slovak shops. Showing those same verified ratings on your product pages, homepage, and checkout reduces tab-switching and keeps social proof where buyers decide.

    You get three building blocks from Heureka:

    1. Shop review XML (last about 500 store reviews)
    2. Product review XML (product reviews from roughly the last 6 months)
    3. Verified by Customers icons and widgets (auto-updating certificate UI)

    Exports refresh about every 6 hours. Icons and widgets follow your current certificate status (blue or gold). If you lose the certificate, Heureka stops showing those embeds automatically.

    Official references:

    DIY vs custom plugin: which path fits

    Approach Best for Limits
    Paste Heureka icon / widget code Quick trust badge on footer or sidebar No custom layout, no product-page review list, no theme match
    WooCommerce / third-party importer WordPress shops that already use that stack Rare outside WooCommerce; limited design and caching control
    Custom Joomla module / WP plugin / CMS module Stores that want shop + product reviews, cron sync, schema, and brand styling Needs a developer once; then you own the control panel
    Infyways Heureka integration (from USD 149) Joomla, WordPress, Magento, OpenCart, Shopify, custom PHP Scoped build with support and handoff

    If you only need the blue or gold badge, use Heureka’s SVG icon codes. If you want testimonials, product ratings, and a design that matches your store, you need a parser and a front-end component. That is the paid build.

    Step 1: Join Verified by Customers and get your export key

    You must already send orders through the Verified by Customers script and earn enough feedback for a certificate. Heureka awards blue or gold automatically from recommendation rates over the tracked windows (blue around 90% recommend over 180 days; gold around 97% over 90 days, with higher review volume). Exact thresholds can change. Confirm current rules in Heureka administration.

    In Heureka admin, open the Verified by Customers section and copy:

    • Shop review export URL
    • Product review export URL
    • Icon and widget embed codes

    Typical shapes:

    https://www.heureka.cz/direct/dotaznik/export-review.php?key=YOUR_SECRET_KEY
    https://www.heureka.sk/direct/dotaznik/export-review.php?key=YOUR_SECRET_KEY
    https://www.heureka.cz/direct/dotaznik/export-product-review.php?key=YOUR_SECRET_KEY

    Treat the key like a password. Do not commit it to public repos. Prefer server-side fetch and cache over exposing the full URL in browser JavaScript.

    Step 2: Understand the shop review XML

    Shop exports wrap reviews under a root reviews element. Each review commonly includes fields such as:

    • rating_id
    • order_id
    • unix_timestamp
    • delivery_time, transport_quality, communication, web_usability (scores often 0.5 to 5)
    • recommends / recommendation signal
    • pros, cons, summary
    • reaction (store reply, when present)

    Example structure:

    <reviews>
      <review>
        <rating_id>XXXXXX</rating_id>
        <unix_timestamp>1453155494</unix_timestamp>
        <delivery_time>5</delivery_time>
        <transport_quality>5</transport_quality>
        <communication>5</communication>
        <pros><![CDATA[Fast delivery]]></pros>
        <cons><![CDATA[]]></cons>
        <summary><![CDATA[Great shop]]></summary>
        <order_id>123</order_id>
      </review>
    </reviews>

    Field names can vary slightly by market and export generation. Always inspect your live feed before hard-coding a schema.

    Step 3: Understand the product review XML

    Product exports use a products root. Each product carries identifiers (name, URL, price, EAN, and related IDs) plus nested reviews. Each product review typically includes:

    • rating_id and rating_id_type (offer or product)
    • unix_timestamp
    • rating (0 to 5 in half-star steps)
    • pros, cons, summary
    • recommends

    Optional filter on the export URL:

    &from=2026-01-01 00:00:00

    That shortens the default ~6 month window to reviews created from that timestamp onward.

    For product reviews to accumulate, send a stable ITEM_ID in both your Heureka product feed and the Verified by Customers order script. Do not recycle ITEM_ID values across different products.

    Step 4: Add official badges and widgets

    Certificate icons and side widgets are separate from XML parsing. Heureka generates HTML/SVG snippets that reflect your live rating and recommendation percentage. Prefer SVG so mobile layouts stay sharp.

    Blue vs gold is certificate status, not a different XML format. When eligibility drops, Heureka hides those embeds. Your custom review list from XML can still show historical text reviews unless you choose to gate it behind certificate status yourself.

    Step 5: Add the required authenticity notice

    If you republish consumer reviews, EU consumer rules expect transparent origin wording. Heureka recommends language similar to this (adapt for SK/CZ legal counsel):

    Verified reviews come from customers who have purchased goods or services from us. They are collected via completed customer satisfaction questionnaires within the “Verified by Customers” program provided by Heureka Group a.s. Satisfaction questionnaires are sent only to customers who purchased from us.

    Put that near the review block. Infyways includes a configurable notice in every integration.

    Step 6: Cache, cron, and performance (do not hit XML on every request)

    Feeds update about every 6 hours. Fetching Heureka on each page view is slow, brittle, and unnecessary.

    Production pattern:

    1. Cron or scheduled task pulls shop and product XML every few hours
    2. Parse and store reviews in your CMS (database table, cache, or custom fields)
    3. Front end reads local data only
    4. Fail soft if Heureka is unreachable (keep last good cache)

    That is how our estilofina.sk Joomla module is designed to behave in production: admin URL + display options, then reliable front-end output.

    What Infyways builds for you

    Heureka Reviews Integration starts at USD 149. Scope scales with CMS and features.

    Included capabilities

    • Shop reviews from Heureka XML export (CZ and/or SK)
    • Product reviews on product detail pages
    • Official Verified by Customers badge / widget placement
    • Caching + cron sync (not live XML on every view)
    • Schema / rich-snippet friendly markup where appropriate
    • Multilingual support for Czech and Slovak feeds
    • Design match to your store theme (colors, typography, carousel or grid)
    • Admin settings: feed URL/key, count, minimum rating, layout, legal notice text

    Platforms we cover

    • Joomla module (proven on estilofina.sk)
    • WordPress plugin (WooCommerce or classic themes)
    • Magento, OpenCart, Shopify, and custom PHP
    Joomla module settings for Heureka XML URL, badge, and review layout
    Front-end Heureka review testimonials styled to match the store

    Proof: estilofina.sk

    We delivered a custom Joomla module for estilofina.sk that shows the Heureka badge plus latest reviews and ratings from the XML feed, with backend parameters for feed URL, testimonial height, and badge options. The same architecture ports to WordPress and other CMS stacks.

    Pricing

    Package Starting price Typical deliverable
    Starter badge + shop reviews USD 149 Module/plugin, cron cache, theme-styled shop reviews, legal notice
    Shop + product reviews Custom quote Product-page mapping, ITEM_ID alignment, schema
    Multi-market CZ + SK Custom quote Dual feeds, language-aware display
    Full design + carousel + ongoing support Custom quote Pixel-matched UI and maintenance

    Want Heureka reviews live on your site without building the parser yourself? Contact Infyways and request a Heureka Reviews Integration. Mention your CMS and whether you need shop reviews, product reviews, or both.

    Key takeaways

    1. Heureka reviews on your site come from XML exports and certificate widgets, not a public API.
    2. Shop feeds cover recent store reviews; product feeds cover roughly six months of product ratings.
    3. Always cache and sync on a schedule. Do not call the export URL on every page view.
    4. Add clear verified-origin wording when you republish reviews.
    5. Infyways ships Joomla, WordPress, and any-CMS integrations from USD 149, with a live Joomla reference on estilofina.sk.

    Frequently asked questions

    Is there a public Heureka reviews API?

    No. Merchants use secret-key XML exports from Verified by Customers plus official icon and widget codes from Heureka administration.

    How often do Heureka review exports update?

    About every 6 hours. Design your sync around that cadence.

    Can I show Heureka reviews on Joomla?

    Yes. Infyways already built a production Joomla module for estilofina.sk. We can deliver the same pattern for your template.

    Do you support WordPress and other CMS platforms?

    Yes. WordPress plugins, Magento, OpenCart, Shopify, and custom PHP are all in scope. Starting packages begin at USD 149.

    What is the difference between the badge and the XML list?

    The badge/widget is Heureka’s embed for certificate status and summary rating. The XML list is your own UI for individual shop or product reviews.

    Do I need both heureka.cz and heureka.sk feeds?

    Only if you sell into both markets with separate Verified by Customers setups. We can wire one or both feeds.

    Will this work without a Verified by Customers certificate?

    XML exports require the service and your key. Official icons and widgets only display while you hold a valid certificate.

    How do I get a quote?

    Send your CMS, Heureka market (CZ/SK), and whether you need shop reviews, product reviews, or badges via the contact form. Packages start at USD 149.

  • Joomla Backward Compatibility Plugin: The Definitive Guide

    Joomla Backward Compatibility Plugin: The Definitive Guide

    The Joomla Behaviour – Backward Compatibility plugin is a temporary bridge that restores selected legacy classes and assets so older extensions can keep running after a major Joomla upgrade. It is not a performance plugin, a security plugin, or proof that an extension is fully compatible. On Joomla 5 it bridges Joomla 4-era code. On Joomla 6, the separate Behaviour – Backward Compatibility 6 plugin bridges selected Joomla 5-era code. You should keep the appropriate bridge enabled while it is needed, then update or replace dependent extensions and prove the site works with it disabled.

    The most important detail is easy to miss: Joomla 5.4 has two compatibility plugins, and they have opposite roles during an upgrade to Joomla 6. The unnumbered Joomla 5 plugin must be disabled. The Joomla 6 plugin must be enabled. Joomla's pre-update checker enforces this configuration before Live Update can continue.

    This guide explains the history, purpose, options, overhead, risks, safe disable test, recovery procedure, developer migration work, and exact settings for Joomla 4.4, 5.x, and 6.x. It is based on the official Joomla compatibility plugin documentation, Joomla 5.4 to 6.x migration documentation, backward compatibility policy, and current Joomla source.

    What you will learn

    • Why Joomla created compatibility plugins
    • When the first plugin appeared and how the bridge model evolved
    • Which plugin belongs to Joomla 5 and which belongs to Joomla 6
    • What every option actually loads
    • Whether leaving the plugin enabled affects speed, security, or upgrades
    • When you can safely disable it
    • How to find the extension that still depends on it
    • How to recover if disabling it breaks the frontend or Administrator
    • What extension developers must change for native compatibility

    For hands-on upgrade help, see Joomla upgrade services or hire Joomla developers.

    The short answer for every Joomla version

    Your site Plugin state What it means
    Joomla 4.4 preparing for Joomla 5 Behaviour – Backward Compatibility is staged for the Joomla 5 transition The bridge becomes active for the major upgrade
    Joomla 5.0 to 5.3 Unnumbered plugin often enabled Older Joomla 4 extensions may still depend on class aliases or asset shims
    Joomla 5.4 staying on Joomla 5 Unnumbered plugin may remain enabled temporarily Disable it on staging to discover technical debt
    Joomla 5.4 preparing for Joomla 6 Disable unnumbered plugin; enable Backward Compatibility 6 Required by the pre-update checker
    Joomla 6 upgraded from 5.4 Backward Compatibility 6 is normally enabled It protects the first boot while extensions transition
    Fresh Joomla 6 installation Backward Compatibility 6 is installed but disabled by default New extensions should not need the bridge
    Joomla 6 after every extension passes native testing Backward Compatibility 6 can be disabled This is the desired end state

    Current context as of September 2026: Joomla 6.1.3 and 5.4.8 are the latest stable maintenance releases. Joomla 5.4 remains the bridge line to Joomla 6. Check the Joomla roadmap before planning production work.

    What backward compatibility means in Joomla

    Backward compatibility means newer Joomla code continues to accept supported older APIs, data structures, or behavior for a defined period. Joomla guarantees compatibility within a major series, subject to exceptional security fixes. A new major series is where deprecated technical debt can be removed.

    Joomla's policy says deprecated code can be moved into a compatibility plugin. That lets the core become cleaner without forcing every third-party extension to be rewritten on the exact day a major version ships.

    An extension is only fully compatible with a Joomla major version when it works with that version's compatibility plugin disabled. A directory badge that says "works on Joomla 6 with compatibility plugin" is useful, but it is not the same as native Joomla 6 compatibility.

    Why Joomla introduced the plugin

    Joomla had accumulated years of deprecated APIs while moving from global class names toward PHP namespaces, replacing old JavaScript assets, and modernizing its framework.

    For example, older extensions used global classes such as JFactory, JTable, JPlugin, and JText. Namespaced replacements started arriving during the Joomla 3 era. Removing every alias at once in Joomla 5 would have broken many otherwise usable extensions.

    The compatibility plugin solved four product problems:

    1. Safer first boot after a major update. System and behaviour plugins may execute before an administrator can log in and fix them.
    2. Time for extension developers. Vendors could support the new major while removing deprecated dependencies in stages.
    3. A measurable migration path. Administrators can disable individual shims or the entire plugin to discover what remains.
    4. Cleaner core. Deprecated code can leave the main core without disappearing immediately from upgraded sites.

    It was implemented in the special behaviour plugin group because it must load before other plugins that might call a legacy class during initialization. Joomla explicitly warns third-party developers not to create their own behaviour plugins because this group exists for an internal early-loading purpose and may change in the future.

    Timeline: when it started and how it evolved

    Date / release What happened Why it matters
    Joomla 3.x era Namespaced replacements gradually superseded many global J* classes Extensions had a long deprecation runway
    Joomla 4.4 Joomla 5 transition code was staged before the major update The bridge could be ready before Joomla 5 files replaced the site
    Joomla 5.0, October 2023 Behaviour – Backward Compatibility became the Joomla 4 to 5 bridge It supplied class aliases and web asset shims
    Joomla 5.4, October 2025 Behaviour – Backward Compatibility 6 was installed and enabled as a no-op bridge seed It would already be active when Joomla 6 code arrived
    Joomla 6.0, October 2025 The old Joomla 5 bridge was replaced by Backward Compatibility 6 Selected Joomla 5-era APIs moved behind the new bridge
    Joomla 6.x today Upgraded sites can use compat6 temporarily; fresh installs keep it disabled Native compatibility remains the target

    The official Joomla 5 plugin manifest identifies version 5.0.0, while its PHP class is marked @since 4.4.0. That reflects the staging strategy: place the bridge during the final minor of the old major so it is available at the first boot of the new major.

    The two plugins people confuse

    Behaviour – Backward Compatibility

    This is the Joomla 5 compatibility plugin. Its extension element is compat, in the behaviour folder.

    It bridges selected Joomla 4-era dependencies while running Joomla 5. Before upgrading from Joomla 5.4 to Joomla 6, it must be disabled. If disabling it breaks the site, one or more extensions are not ready for Joomla 6.

    Behaviour – Backward Compatibility 6

    This is the Joomla 6 compatibility plugin. Its extension element is compat6, also in the behaviour folder.

    It is installed and enabled on Joomla 5.4 but deliberately does no compatibility work while Joomla 5 code is still running. It is waiting for the Joomla 6 codebase. It must be enabled before the Joomla 5.4 to 6 upgrade.

    After the site runs successfully on Joomla 6 and every extension is native, this plugin can be disabled.

    What the Joomla 5 plugin options do

    The Joomla 5 plugin has three separately configurable options.

    Option What it supplies What dependence looks like
    Classes Aliases Aliases for classes renamed or moved into namespaces Errors such as Class "JTable" not found after disabling
    ES5 Assets Empty compatibility entries for removed .es5 web assets WebAssetManager throws an asset-not-found exception
    Removed Assets Empty registry entries for Joomla 4 assets removed in Joomla 5 An extension requests an old CSS/JS asset by name

    The ES5 and removed-asset shims are usually empty. They prevent exceptions; they do not recreate obsolete browser code or restore an old interface. If an extension relied on the actual removed asset behavior, an empty registry entry may stop the crash but cannot guarantee that the feature still works.

    Source: Joomla 5 compatibility plugin implementation.

    What the Joomla 6 plugin options do

    Joomla 6's compat6 plugin has a different set of bridges.

    Option What it supplies Typical dependency
    Classes Aliases Aliases for renamed or moved classes Old global or moved class references
    Include Deprecated Classes Loads selected Joomla CMS classes moved into plugins/behaviour/compat6/classes Code using packages removed from Joomla 6 core
    Removed Assets Empty registry entries for assets removed from Joomla 5 to 6 Old WebAssetManager dependencies

    Concrete examples documented for Joomla 6 include the old Joomla\CMS\Input namespace and the deprecated Joomla\CMS\Filesystem package. Native code should move to Joomla\Input and Joomla\Filesystem. Joomla's removed and backward-incompatible list is the authoritative developer checklist.

    Source: compat6 implementation.

    What the plugin does not do

    The plugin is intentionally limited. It does not:

    • Make every Joomla 3 or Joomla 4 extension work on Joomla 5 or 6
    • Fix PHP version incompatibility
    • Rewrite an obsolete extension manifest
    • Repair database schemas or failed update SQL
    • Restore removed third-party libraries
    • Convert legacy event handling automatically
    • Fix template overrides after core markup changes
    • Make an abandoned extension secure
    • Replace extension updates from the vendor
    • Downgrade Joomla or reverse an upgrade

    If an extension claims support only because the compatibility plugin hides one missing class, test its complete workflow. Loading without an exception is not the same as functioning correctly.

    Benefits of keeping it enabled during transition

    Safer major upgrades

    The first request after an update may load third-party system plugins before you can reach Administrator. Early class aliases reduce the chance of an immediate fatal error.

    Controlled extension migration

    You can upgrade the site platform first, then replace or refactor extensions on staging in a managed sequence.

    Faster diagnosis

    Turning options off one at a time can reveal whether an extension depends on class aliases, deprecated classes, or asset shims.

    Longer useful life for maintained extensions

    A vendor can ship a release that works on two Joomla majors while completing native migration work.

    Does leaving it enabled hamper the website

    Usually not in a noticeable way. The plugin loads early, may include a class map, registers a namespace for legacy classes, and may add small web asset registry files. On a normal site, that overhead is generally minor compared with database queries, page builders, images, and network latency.

    However, "small runtime overhead" is not the same as "leave it forever." The larger costs are operational:

    • It can hide extensions that are not truly ready for the next major version.
    • It keeps legacy code paths available.
    • It delays vendor accountability and cleanup.
    • It can make a future major upgrade fail when that bridge is removed.
    • Troubleshooting becomes harder because the site behaves differently with and without shims.

    There is no honest universal millisecond figure. Impact depends on enabled options, opcode cache, extension code, and request type. Benchmark your site before and after on staging if performance is a concern.

    Security implications

    Enabling the official core plugin is not inherently a vulnerability. It is maintained as part of Joomla and exists for supported upgrade paths.

    The risk is dependency, not the switch itself. An old extension that requires legacy compatibility may also contain outdated coding patterns or unpatched vulnerabilities. The plugin does not audit, patch, sandbox, or secure that extension.

    Use this rule:

    Compatibility is a bridge to updated code, not permission to keep abandoned code.

    Keep Joomla core and extensions patched. Remove extensions you no longer use. Check compatibility and security notices in the Joomla Extensions Directory.

    When you can safely turn it off

    Turn off the active compatibility plugin when all these statements are true:

    1. Every installed component, module, plugin, template, and package explicitly supports your current Joomla major.
    2. The extension vendor says native support, not only "works with compatibility plugin."
    3. You tested frontend, Administrator, forms, login, search, checkout, scheduled tasks, CLI, API, and email on staging.
    4. Debug logging shows no missing legacy classes or assets.
    5. You have a tested backup and rollback point.
    6. The site remains stable through at least one representative business workflow.

    For a fresh Joomla 6 site, leave compat6 disabled unless a known extension requires it. For an upgraded Joomla 6 site, do not race to disable it on production immediately after the core update. First prove the site, update extensions, then run the disable test on staging.

    When you should not turn it off

    Do not disable it directly on production when:

    • You have no recent backup
    • You do not have staging
    • An extension vendor explicitly requires it
    • The site uses old custom code nobody has audited
    • A Joomla 5 site still throws JFactory, JTable, JPlugin, or similar legacy-class errors
    • A Joomla 6 site still uses packages documented as moved into compat6
    • A release or checkout is in progress

    Keeping it enabled temporarily is safer than causing an outage. The correct follow-up is to identify the dependency, not pretend the plugin must stay forever.

    Safe disable procedure

    Step 1: Clone production to staging

    Use the same PHP version, database engine, web server, and extensions. A different environment can hide or invent compatibility errors.

    Step 2: Update everything first

    Update Joomla within the current major. Update every extension and template. Remove unused extensions instead of merely disabling them.

    Step 3: Back up and test the restore

    A backup you have never restored is only a hopeful archive.

    Step 4: Enable maximum diagnostics on staging

    In Global Configuration:

    • Debug System: Yes
    • Error Reporting: Maximum
    • Log Deprecated API: enable if available in your Joomla version and logging configuration

    Do not leave verbose errors exposed on production.

    Step 5: Disable options one at a time

    Start with removed assets, then ES5 assets or deprecated classes, then class aliases. Clear Joomla cache after every change. This isolates the type of dependency.

    Step 6: Test more than the homepage

    Use this test matrix:

    Area Tests
    Frontend Home, article, category blog, search, contact form, multilingual switcher
    Administrator Login, article edit/save, media, menus, modules, users, configuration
    Extensions Checkout, form submission, subscriptions, imports, exports, backups
    Background Scheduled tasks, cron, queue jobs, CLI commands
    Integration REST API, webhooks, SMTP, payment callbacks
    Template Menu, modal, tabs, tooltips, JavaScript widgets, overrides

    Step 7: Disable the whole plugin

    If all individual options pass, disable the plugin and repeat the matrix. Keep logs open for fatal errors and deprecation messages.

    Step 8: Fix the dependency, then retest

    Update, replace, or refactor the responsible extension. Do not just re-enable the bridge and close the ticket.

    Joomla 5.4 to Joomla 6: exact plugin states

    Before upgrading:

    Plugin Required state on Joomla 5.4
    Behaviour – Backward Compatibility Disabled
    Behaviour – Backward Compatibility 6 Enabled

    The pre-update checker and CLI core:update verify both conditions. If either check fails, Joomla blocks the major update. This is deliberate. It prevents an incompatible Joomla 4-era extension from crashing the site halfway through a Joomla 6 update.

    Official procedure: Joomla 5 to 6 planning and upgrade.

    The correct Joomla 5 to 6 workflow

    1. Update the current site to Joomla 5.4.x.
    2. Update every extension and template.
    3. Confirm Backward Compatibility 6 is installed and enabled.
    4. Disable the unnumbered Backward Compatibility plugin.
    5. Clear cache and test the complete site while still on Joomla 5.4.
    6. If anything breaks, re-enable the old plugin and fix the extension on Joomla 5.4.
    7. Repeat until Joomla 5.4 runs without the old bridge.
    8. Back up and verify restore.
    9. Run Joomla's pre-update check.
    10. Upgrade to Joomla 6.
    11. Test with compat6 enabled.
    12. Migrate remaining Joomla 5-era dependencies and later test compat6 disabled.

    The important safety feature is step 5. Finding the fatal error before the major update is safer than finding it during a partially completed update.

    How to identify the extension that depends on it

    Read the first useful stack frame

    A fatal error often names JTable, JFactory, JPlugin, JText, an old namespace, or a removed asset. The first stack frame inside /components, /plugins, /modules, /templates, or /administrator/components usually identifies the owner.

    Search custom and third-party code

    Examples worth searching for on a Joomla 5 site:

    JFactory
    JTable
    JPlugin
    JText
    JLoader
    JFormField
    

    Do not assume every search match is active or wrong. Vendors sometimes provide their own aliases. Use the stack trace to connect a match to a failing request.

    For Joomla 6, also search imports from removed CMS packages listed in the migration guide, such as:

    use Joomla\CMS\Input\Input;
    use Joomla\CMS\Filesystem\File;
    use Joomla\CMS\Filesystem\Folder;
    

    Replace them using the official Joomla 6 migration notes rather than blind search-and-replace.

    Disable extensions in batches on staging

    When the stack trace is unclear, disable non-core system plugins in small batches. System plugins can execute on every request and are frequent causes of an Administrator lockout.

    Check WebAssetManager exceptions

    An error naming an asset instead of a class points to ES5 or removed-asset compatibility. Update the extension's asset declaration and calls.

    Recovery when disabling the plugin breaks the site

    Fast recovery through Administrator

    If Administrator still works, open System → Manage → Plugins, search Backward Compatibility, and enable the plugin again. Clear cache.

    Database recovery when Administrator is down

    Open the #__extensions table (replace #__ with your table prefix). Find:

    • folder = behaviour, element = compat for the Joomla 5 bridge
    • folder = behaviour, element = compat6 for the Joomla 6 bridge

    Set enabled = 1 for the plugin you need to restore. Do not enable both blindly during a Joomla 5.4 to 6 upgrade attempt. Restore the state appropriate for the Joomla version, then fix the underlying extension on staging.

    Restore instead of downgrading

    Joomla does not support downgrading a core upgrade. If the update itself failed or data changed, restore the pre-upgrade backup. Do not copy old core files over a newer database and call it a rollback.

    Can you uninstall the compatibility plugin

    Do not uninstall or delete this core plugin. Disable it when it is no longer needed.

    Keeping the files installed lets Joomla updates maintain them and gives you a supported recovery path. Manually deleting core plugin files can create database/file mismatches and complicate later updates.

    Can you disable only some options

    Yes, and that is the best diagnostic method.

    On Joomla 5, an extension may need class aliases but not ES5 or removed assets. On Joomla 6, it may need deprecated classes but not removed asset placeholders. Turn options off individually on staging, clear cache, and run the test matrix.

    Partial disablement reduces the compatibility surface while showing the vendor exactly what remains.

    Extension developer migration checklist

    An extension developer should:

    1. Replace global J* class names with supported namespaced classes.
    2. Replace removed CMS packages with current framework packages where Joomla documents a replacement.
    3. Stop requesting removed ES5 or WebAssetManager entries.
    4. Use supported concrete event classes and subscriber patterns where applicable.
    5. Test installation, update, uninstall, and schema changes.
    6. Test frontend, Administrator, CLI, API, and scheduled-task contexts.
    7. Run the extension with all compatibility options disabled.
    8. Declare compatibility accurately in the update server and Joomla Extensions Directory.

    The Joomla backward compatibility policy explains what core promises and what it does not. Internal, private, final, and third-party APIs are not automatically protected.

    Common errors after disabling

    Error or symptom Likely dependency Correct response
    Class "JTable" not found Joomla 4-era global class alias Update/refactor the extension
    Class "JPlugin" not found Very old plugin base class Use current CMSPlugin and service registration
    Web asset not found Removed or ES5 asset name Update asset JSON/calls; do not rely on empty shim
    Blank frontend but Admin works Site plugin/module/template dependency Enable debug on staging and inspect stack trace
    Both frontend and Admin fail Early-loading system/behaviour plugin Re-enable via database, then isolate extension
    Joomla 6 pre-update check blocks Wrong states for compat and compat6 Disable old plugin; enable compat6
    Site works enabled but fails disabled Extension is bridge-compatible, not native Update, replace, or refactor

    Myths and facts

    Myth Fact
    The plugin converts Joomla 4 extensions to Joomla 5 It supplies selected aliases and shims; it does not rewrite extension code
    Enabled means the site is insecure The core plugin is supported; the concern is outdated dependent extensions
    Disabled always makes Joomla faster Runtime savings are normally small; clean architecture is the bigger benefit
    Joomla 5.4 should have both plugins disabled before Joomla 6 Wrong. Old compat disabled; compat6 enabled
    A Joomla 6 badge means no bridge is needed Check whether the vendor means native compatibility or compatibility with compat6
    If the site loads, the extension is compatible You must test saves, jobs, forms, API, email, and other workflows
    Delete the plugin when done Disable it; do not delete core plugin files

    Recommended operating policy

    Use a simple policy across client sites:

    1. Record the active compatibility plugin and option states in the maintenance runbook.
    2. Review the state after every extension release cycle.
    3. Run a disabled test on staging at least quarterly.
    4. Reject new extensions that require a bridge without a vendor migration plan.
    5. Make "runs with compatibility plugin disabled" an acceptance criterion for custom extension work.
    6. Remove abandoned extensions before the next Joomla major.

    This turns the plugin from permanent mystery infrastructure into measurable migration debt.

    Key takeaways

    1. Joomla introduced compatibility plugins to make major upgrades safer while removing deprecated code from core.
    2. The Joomla 5 plugin bridges selected Joomla 4 dependencies; compat6 bridges selected Joomla 5 dependencies.
    3. On Joomla 5.4 before Joomla 6, disable the unnumbered plugin and enable Backward Compatibility 6.
    4. Leaving the correct plugin enabled usually has minor runtime overhead, but it can hide extension debt.
    5. The goal is native compatibility, proven on staging with the plugin disabled.
    6. Never delete the core plugin. Disable it and keep a tested recovery path.
    7. A successful homepage is not enough; test Admin, forms, jobs, API, email, and extension workflows.

    Frequently asked questions

    What is the Joomla Behaviour – Backward Compatibility plugin?

    It is a core transition plugin that restores selected legacy classes and asset registrations after a major Joomla upgrade so older extensions have time to become native.

    When was the plugin introduced?

    The Joomla 5 bridge was staged in Joomla 4.4 and became the compatibility layer for Joomla 5.0 in October 2023. The Joomla 6 bridge was staged in Joomla 5.4 and became active with Joomla 6.0 in October 2025.

    Should I keep the plugin enabled?

    Keep it enabled while a maintained extension genuinely needs it. Update or replace that dependency and test disabling the plugin on staging.

    Does the compatibility plugin slow down Joomla?

    Usually not noticeably. It loads aliases, optional legacy classes, and small asset registries. The bigger cost is hidden technical debt rather than page-load time.

    Is it a security risk?

    The official plugin itself is supported Joomla core code. The risk is that it may keep an old, potentially vulnerable third-party extension running. It does not patch extensions.

    Can I turn it off on Joomla 5?

    Yes, after testing. In fact, the unnumbered Joomla 5 plugin must be disabled before upgrading from Joomla 5.4 to Joomla 6.

    Which plugin must be enabled before Joomla 6?

    Behaviour – Backward Compatibility 6 (compat6) must be installed and enabled on Joomla 5.4. The unnumbered Joomla 5 plugin (compat) must be disabled.

    Can I turn off Backward Compatibility 6 after upgrading?

    Yes, once every extension and custom integration works natively on Joomla 6. Test it on staging first.

    Why did my site break when I disabled it?

    An extension, template, or custom plugin still calls a class or asset supplied by the bridge. Re-enable it, inspect the stack trace, and update or refactor the responsible extension.

    How do I re-enable it if Administrator is broken?

    In #__extensions, find the behaviour plugin with element compat or compat6 and set enabled to 1. Then clear cache and investigate the failing extension.

    Can I uninstall the plugin?

    No. Treat it as a core plugin and disable it when unused. Deleting it can create file/database mismatches and complicate updates.

    Does the plugin make a Joomla 3 extension work on Joomla 6?

    No. It only supplies selected compatibility cases from the previous major. A Joomla 3 extension may also depend on removed PHP APIs, manifests, events, libraries, and database behavior.

    How do I know an extension is natively compatible?

    It installs, updates, and passes its full workflow on the current Joomla major with the relevant compatibility plugin disabled.

    Where can Infyways help?

    Infyways provides Joomla upgrades, extension development, and support and maintenance for compatibility audits and major-version transitions.

  • Joomla Template Override Disappeared After an Update

    Joomla Template Override Disappeared After an Update

    A Joomla template override disappeared after an update because you edited the parent template (usually Cassiopeia html/), and the package put the stock files back. Child html/ is not part of that package. It stays. This is a file that vanished from disk (or was restored to vendor markup). It is not “the override never loaded.” If the PHP is still there and the public page ignores it, use Joomla template override not working instead.

    Joomla and club-template updates are allowed to replace parent files. That is how security fixes arrive. Your job is to stop storing custom PHP on a path the installer owns. Move the copy into a child template html/ folder, assign that style, and leave Cassiopeia stock. Same rule as CSS and JS: customize without editing core.

    Joomla update restoring parent html while the child html folder still holds the copy

    The update owns the parent. It does not own the child. If you customized Cassiopeia in place, the next package looks like your override “disappeared.”

    What you will learn

    • How to tell a wiped parent file from an override that never loaded
    • Why Cassiopeia html/ is not a safe home, even when Create Overrides offered it
    • How to recover markup from backup before you recreate anything
    • How to move surviving files into child html/ (including plugin plg_ copies)
    • What the template Overrides list means after the next update (stale vs gone)
    • How to keep the parent inheritable so you are not maintaining a fork

    Official references: Layout Overrides in Joomla, Child Templates, Template Overrides.

    What happened This article The other article
    FTP: html/com_content/article/default.php is gone or matches core again Yes. Parent was replaced. No
    FTP: your probe class is still in the file, public HTML is stock No Override not working
    You switched the default style to a new child and Home went stock Maybe both: files still on parent, style now child Assign and copy into the child
    Club zip reinstalled the template you renamed as “Cassiopeia custom” Yes, if that folder is what the zip overwrites Path/filename issues if the file remains
    Core layout changed and your copy still exists but looks wrong Stale override. Diff it. File did not disappear. Only if the path was always wrong

    Step 1: Confirm the file is gone (or stock) on disk

    Do not trust memory of “it used to look different.”

    1. Note the view you customized (article, blog, mod_menu, plugin Prev/Next).
    2. On the server, open parent templates/cassiopeia/html/ (or the club parent you actually edited).
    3. Compare with a stock copy: same Joomla version, unmodified Cassiopeia, or the extension’s tmpl in components/ / modules/ / plugins/.

    Outcomes:

    • Missing file: the update deleted a file that is not in the package (some hosts sync to the zip). Or you never committed it and a deploy overwrote the tree. Restore from backup first (Step 2).
    • File exists, content is vendor: the installer replaced your PHP. This is the usual Cassiopeia / extension update.
    • File exists, your markup is still there: this is not a disappearance. Go to override not working (wrong style, _default.php, alternative layout, plugin HTML).

    Also look at the child, if you have one: templates/{child}/html/. If the custom PHP is only on the parent, assigning the child after the update will look like a wipe even when the parent file was restored. The child never had a copy. That is still this article’s fix: copy into the child, do not re-edit the parent.

    Administrator overrides live under administrator/templates/atum/html/ (or an Atum child). A Joomla update can restore Atum the same way. Site and admin are separate trees.

    Step 2: Recover the last good copy from backup

    Do not recreate a 400-line article layout from a screenshot if last night’s backup still has it.

    1. Take a new backup before you copy anything around (so a bad paste has a rollback).
    2. Restore only the override files you need from the pre-update backup into a staging folder on your desk, not straight onto production parent html/.
    3. Diff against current core tmpl for this Joomla version. Core may have changed. Pasting an old override onto new Joomla can fatal. Official advice is to compare overrides after updates. The template UI Overrides (Updated Files) list is for copies that still exist and drifted from core. A replaced parent file will not show your old diff because your old file is gone.

    If you have no backup, you rebuild from Create Overrides on the child (Step 3) and re-apply the HTML you remember. That is slower. It is still safer than patching Cassiopeia again.

    Step 3: Create or open a child and put html/ there

    On Joomla 4.1, 5, and 6:

    1. System → Site Templates → Cassiopeia (inheritable parent) → Create Child Template if you do not already have one. Clicks: How to set up a Joomla child template.
    2. Open the childCreate Overrides for each component or module you had customized. That copies current core layouts into templates/{child}/html/.
    3. Merge your recovered markup into those child files. Keep new core PHP (variables, escaping) unless you know why you are dropping it.
    4. Plugin layouts: Create Overrides usually will not list them. Recreate html/plg_{group}_{element}/ by hand and paste the recovered tmpl. Guide: Joomla plugin override.

    A child does not magically inherit every parent html/ file. Same-named files in the child win. Everything you never copied still comes from the parent package. After an update, parent html/ is stock again. If you needed a customization, it must exist in the child folder.

    Do not zip-clone the whole Cassiopeia tree and call it a child. That is a fork. The next Cassiopeia security fix will not reach it, and the next vendor zip may overwrite it anyway.

    Joomla 6 Cassiopeia Extended is already a child. Put overrides on Extended (or on your own child), not on Cassiopeia parent.

    Step 4: Assign the child style, then stop editing the parent

    Creating the child does not change the public site.

    1. System → Site Template Styles. Make the child’s style default, or set it on the menu items that need the markup.
    2. Clear Cache. Test the URL as a guest if Page Cache is on.
    3. Confirm View Source has your markup (probe class).
    4. Leave templates/cassiopeia/html/ empty of custom files. If Create Overrides on the parent still looks convenient, close it. Use the child only.

    A template style duplicate is not a child. Styles store params and assignment. They still point at the same parent files. Duplicating “Cassiopeia – Default” and editing PHP in Cassiopeia will disappear again on the next update.

    Language strings do not belong in restored PHP. Use language overrides. CSS that died with the parent user.css is the CSS checklist: Joomla CSS changes not showing. Parent user.css is also wiped or orphaned when you switch to a child. Copy it into the child’s media folder.

    Step 5: After the next update, use Overrides as a stale check, not as a time machine

    When Joomla updates a layout you overrode in the child, the file does not vanish. It can become wrong relative to core (missing a new variable, old markup).

    1. Open the child in Template Manager.
    2. Check Overrides / updated-files style notices (wording varies by version).
    3. Diff your copy against the new core tmpl. Merge.

    That list does not watch user.css or user.js. Review those yourself. It also will not bring back a parent file the installer already replaced. Prevention is the child, not the notice.

    Club templates: read the vendor’s child or “custom” folder rules. If their zip replaces templates/yourname/html/, you are still on a parent-shaped path. Ask for an inheritable parent or keep a true Joomla child.

    Five checks: file gone on disk, parent was edited, backup, move to child html, assign child style

    Disk first. If the file is still there, you are on the not-working article. If it is stock or missing, backup, child html, assign the style, never edit the parent again.

    Key takeaways

    1. Disappeared means the custom PHP is gone or stock on disk after an update. Not-working means the file is still there and unused.
    2. Parent Cassiopeia html/ is owned by the installer. Child html/ is yours.
    3. Create Overrides on the parent is how this incident starts. Run it on the child.
    4. Restore from backup into the child, then diff against current core. Do not paste an old override onto new Joomla blindly.
    5. Assign the child style. Creating a child does not publish it.
    6. Plugin copies in parent html/plg_… disappear the same way. Recreate them on the child: plugin override.
    7. After future updates, diff stale child overrides. That is not a disappearance.
    8. Keep the stack in customize without editing core.

    Frequently asked questions

    Why did my Joomla template override disappear after an update?

    You stored it in the parent template. The Joomla or club package replaced those files. Move the override into a child html/ folder and assign that style.

    Is this the same as a template override not working?

    No. Not working: the file is on disk and Joomla never includes it (folder, style, _default.php, alternative layout, plugin). Disappeared: the file was restored or deleted by an update. Different checklists.

    Will a child template survive a Joomla update?

    The child folder is not in the Cassiopeia package, so your html/ copies stay. You still diff them if core layouts change. Official description: Child Templates.

    Can I copy the whole Cassiopeia folder instead of a child?

    You can. You then own a fork. Security fixes in Cassiopeia will not apply until you merge by hand. Use Create Child Template on Joomla 4.1+.

    Where do I put plugin overrides so they do not vanish?

    templates/{child}/html/plg_{group}_{element}/, same as other overrides. Manual copy: Joomla plugin override.

    The Overrides tab still lists my file. Did it disappear?

    No. That list is for overrides that exist and may be out of date versus core. A true disappearance is a missing or stock file in parent html/ after the package ran.

    Should I edit Cassiopeia html again “just this once”?

    No. That is how this article starts the next time you click Update. Use the child. Setup: Joomla child template.

    Conclusion

    When a Joomla template override disappeared after an update, believe the disk. Parent html/ comes back from the zip. Child html/ does not. Restore the last good PHP on staging, merge it into a child created with Create Child Template, assign that style, and leave Cassiopeia alone. If the file is still sitting on disk and the site ignores it, you opened the wrong guide: override not working.

    If production was customized for years inside the parent, Joomla support and maintenance can move the tree to a child without another surprise on the next security release. Layout you would rather not own: Joomla design services.

  • Joomla Template Override Not Working: Causes and Fixes

    Joomla Template Override Not Working: Causes and Fixes

    A Joomla template override is not working when Joomla never loads the PHP file you edited. The usual causes are the wrong html/ folder, a template style that is not the one assigned to the page, a filename of _default.php (a sublayout, not the layout), an alternative layout selected on the menu item or module, plugin HTML that does not live in the component override, or cache still serving the old markup. This is a file that never loaded. If the file used to work and vanished after an update, that is a different article: template override disappeared after an update.

    Create Overrides is the safe copy for components and modules. Plugin tmpl is usually copied by hand into html/plg_…. Official map: Layout Overrides in Joomla. User-manual walkthrough: Template Overrides. Put the copy on a child template, not in parent Cassiopeia.

    _default.php rejected versus default.php in html/com_content/article

    The layout Joomla looks for is default.php. A leading underscore is a sublayout. The assigned template style must be the folder that contains the file.

    What you will learn

    • How to prove the override file is the one PHP included
    • Why Create Overrides for com_ and mod_ is safer than a hand-made path
    • Why plugin HTML is usually html/plg_…, not the article default.php
    • Why _default.php never replaces default.php
    • What an alternative layout on the menu item actually selects
    • Why cache and the wrong template style look like a “dead” override
    What you see Likely cause Wrong rabbit hole
    Stock markup, your PHP comment missing Wrong folder, wrong template style, or _default.php Editing components/
    Override works on Home, not on a landing page That menu item uses another template style Recreating the override
    Article body changed, Prev/Next did not Page navigation is a plugin layout More com_content PHP
    Blog looks stock, single article changed You overrode article/default.php. The blog uses articles/… (or blog.php) Cache only
    File on disk, still stock Alternative layout selected, or cache Reinstalling the component
    Child looks stock Override still sits in parent html/ “Overrides are broken”

    Step 1: Prove which template is assigned, then prove the file is included

    Overrides are files on a template. They are not a Global Configuration switch.

    1. Open the public URL that should use the override.
    2. System → Site Template Styles. Note the default (star).
    3. Open that menu item. Template Style may be a different style (child vs parent, or a club template).

    If the page uses cassiopeia_brand and you edited templates/cassiopeia/html/…, Joomla will not load your copy. Child html/ wins for that style. Parent Cassiopeia html/ is unused when the child is assigned. The reverse is also true: assign the parent, and the child’s override is ignored.

    Prove inclusion:

    1. On the file you believe is active, add a unique class on a wrapper you already have, for example js-override-probe. Do not use a core-edit in components/.
    2. System → Maintenance → Clear Cache. Test logged out if Page Cache is on.
    3. View Source. Search for js-override-probe.

    If the class is missing, Joomla did not include that file. Keep going. If the class is present and the page still “looks stock,” you changed the wrong markup, or CSS is hiding it: Joomla CSS changes not showing.

    Step 2: Use Create Overrides for components and modules

    Hand-built folders are how silent misses happen.

    1. System → Templates → Site Templates → open the active template (the child).
    2. Open Create Overrides.
    3. Pick the component view (com_contentarticle, category, …) or the module (mod_login, mod_menu, …).
    4. Joomla copies into templates/{template}/html/com_… or html/mod_….
    5. Edit that copy only.

    Typical paths:

    • Article: templates/{child}/html/com_content/article/default.php
    • Category blog: templates/{child}/html/com_content/category/blog.php (and often blog_item.php as a sublayout)
    • Module: templates/{child}/html/mod_login/default.php

    Wrong folders that fail silently:

    • html/com_content/articles/ when the view is article (singular) or the reverse
    • html/modules/mod_login/ (extra modules segment)
    • html/com_content/article/tmpl/default.php (no extra tmpl under html)
    • An override on Atum while you are looking at the site

    Create Overrides exists so the path matches what Joomla searches. Official folder rules: Layout Overrides in Joomla. Joomla 4 layout notes: Template Layouts.

    JLayouts (Read more, images, fields chrome) are not always the view default.php. They live under html/layouts/… after you override them from the Layouts list. If you changed article/default.php and the intro image is still stock, you needed html/layouts/joomla/content/…. The user manual shows the LayoutHelper::render mapping: Template Overrides.

    Step 3: Name the file default.php, not _default.php

    The layout file is default.php. A leading underscore marks a sublayout. Joomla will not use _default.php as the main view.

    Create Overrides copies default.php. Some views also copy default_logout.php, blog_item.php, and similar. Those extra files are included from the main layout ($this->loadTemplate('item') looks for {layout}_item.php). They do not replace default.php.

    If you renamed the copy to _default.php because a blog said “underscore means override,” you hid the file from the layout resolver. Rename it back to default.php.

    If you only edited blog_item.php while the menu item still uses the default layout (not blog), that sublayout is never included. Match the layout name Joomla is actually rendering (next step).

    Step 4: Check Alternative Layout on the menu item, module, or article

    Joomla can select a file that is not default.php.

    On the menu item: Options (or the Blog / Article tab) → Layout / Alternative Layout. Values such as blog, a template-specific layout, or a custom mylayout.php mean your default.php override is idle for that view.

    On a module: Advanced → Alternative Layout. A module can use default.php on one instance and a custom layout on another. You overrode the file the instance is not using.

    On an article: some views let the article pick a layout. If that is set, it wins for that article.

    Fix:

    • Set Alternative Layout back to default (or inherited), or
    • Create or copy the override with the same basename as the selected layout (blog.php, mylayout.php), still without a leading underscore.

    A custom alternative layout is a second file in html/com_…/. It is not a child-template feature by itself. The child only decides which template’s html/ is searched.

    Step 5: If the HTML comes from a plugin, do not expect a component override

    Content plugins inject markup after (or beside) the component layout. Prev/Next, vote, some field types, and many extra buttons are plugin tmpl files.

    Overriding html/com_content/article/default.php will not restyle page navigation. You need html/plg_content_pagenavigation/default.php (and a plugin that actually calls getLayoutPath). Create Overrides usually does not list plugins. You copy tmpl by hand.

    Full path, tmpl test, and what cannot be overridden: Joomla plugin override.

    If the string is only a label, use a language override instead of PHP.

    Step 6: Clear cache, then decide if the file was never going to survive an update

    After a path fix:

    1. Clear Cache (and Page Cache for guests).
    2. Hard refresh.
    3. Search View Source for your probe class again.

    If the override used to appear and the PHP file is gone from disk after a Joomla or template update, stop this article. You edited the parent. Read template override disappeared after an update.

    If the file is still there and still unused, you are still on folder, style, filename, alternative layout, or plugin output.

    Keep new overrides on the child so the next Cassiopeia package cannot replace them. Policy: customize without editing core. Visual markup you do not want to maintain: Joomla design services.

    Five checks: folder, template style, default.php, alternative layout, plugin output

    Folder path, then the assigned style, then default.php versus a sublayout, then Alternative Layout, then plugin HTML. Cache last.

    Key takeaways

    1. An override that “does nothing” did not load. Prove it with a probe class in View Source after Clear Cache.
    2. Create Overrides for com_ and mod_ on the active child. Hand-typed folders fail silently.
    3. Plugin output is html/plg_{group}_{element}/, usually manual. Guide: plugin override.
    4. The main file is default.php. _default.php is a sublayout. blog_item.php does not replace blog.php.
    5. Alternative Layout on the menu item or module selects a different basename. Override that file, or set layout back to default.
    6. Child html/ wins only when that child’s style is assigned. Parent and child are not a merge of every PHP file.
    7. JLayouts live under html/layouts/, not always in the view default.php.
    8. A file that vanished from disk after an update is not this diagnosis. Use the disappeared checklist.

    Frequently asked questions

    Why is my Joomla template override not working?

    Joomla is not including that PHP file. The folder does not match the view, the assigned template style is a different template, the file is named _default.php, Alternative Layout points at another basename, or the HTML comes from a plugin. Prove it with a probe class in View Source.

    Should the override file be named _default.php?

    No. Name it default.php (or blog.php if that is the layout in use). A leading underscore is a sublayout. Create Overrides already uses the correct names.

    Why did Create Overrides copy default.php and default_logout.php?

    default_logout.php is a sublayout of the login module’s default layout. Edit the file that prints the markup you care about. Deleting default.php when you only wanted logout is correct if you do not want to override the login form. The user manual does exactly that: Template Overrides.

    Can I override a plugin from the article layout?

    No. Plugin HTML that uses tmpl is overridden under html/plg_…. See Joomla plugin override.

    Does a child template automatically use the parent html folder?

    No. Same-named files in the child win. Files you never copied stay on the parent. An override that exists only on the parent is unused while the child style is assigned.

    I updated Joomla and the override vanished. Is that this article?

    No. That is the parent getting restored. Use Joomla template override disappeared after an update.

    Where are the official override rules?

    Layout Overrides in Joomla and Understanding Output Overrides. Child placement: Child Templates.

    Conclusion

    When a Joomla template override is not working, stop editing components/ and stop renaming files with a leading underscore. Assign the child style, put default.php (or the alternative layout’s real name) in the matching html/com_ or html/mod_ folder, and treat plugin markup as html/plg_. A probe class in View Source tells you in one reload whether PHP included the file. If the file used to exist and the disk is stock after an update, switch to the disappeared guide and move the work into a child.

    Need the markup rebuilt without another silent path? Joomla design services or Joomla support and maintenance.

  • Joomla JavaScript Not Working

    Joomla JavaScript Not Working

    Joomla JavaScript is not working when the browser never executes the file you think you added, or it executes and throws before your code runs. Open the console first. Then confirm user.js is requested from media/templates/site/{template}/js/user.js on the active template (a child does not load the parent’s user.js). Typical failures after that are $ is not defined (jQuery is not on the page), an ES module in a classic deferred script, script order, Content-Security-Policy, or another extension overwriting the same global.

    This article is why it fails. The how-to for adding a file the supported way is Add custom JavaScript to Joomla. Keep custom JS on a child template, not in core index.php. Same overlay rule as CSS: customize without editing core.

    Console error, missing user.js, and jQuery dollar undefined

    Read the console before you add another script tag. $ is not shipped on Cassiopeia by default. CSP can block a file that 200s in Network.

    What you will learn

    • How to separate a 404 path from a runtime exception
    • Where Cassiopeia user.js lives (and why the child ignores the parent file)
    • Why $ and jQuery fail on Joomla 4, 5, and 6 front ends
    • What defer and ES modules do to order
    • How the HTTP Headers plugin (CSP) blocks inline or third-party scripts
    • How to spot a conflict without disabling the whole site in public

    Official references: Web Asset Manager, Adding JavaScript and CSS to the page, Cassiopeia Template Customisation, HTTP Headers plugin.

    What you see Likely cause Wrong rabbit hole
    Console Failed to load resource / 404 user.js on the parent, old templates/…/js/ path, or user.js.js Rewriting the script
    $ is not defined / jQuery is not defined Cassiopeia does not load jQuery unless an extension called it Copy-pasting a Joomla 3 snippet
    Cannot use import statement outside a module ES import inside Cassiopeia’s classic user.js (deferred, not type="module") More defer
    Script in Network 200, nothing happens Error earlier in the same file, wrong selector, or you tested a page that does not include the node Cache only
    Console CSP Refused to execute HTTP Headers plugin or server Content-Security-Policy Disabling SEF
    Works in admin, fails on the site Site template user.js vs Atum. Two templates, two files “Joomla JS is broken”
    Works logged in, fails as guest Page Cache serving HTML without your new <script>, or a guest-only extension Access on a module

    Step 1: Read the browser console before you add another file

    Do not stack a second snippet on top of a SyntaxError.

    1. Open the public page that should run the script. Use a private window so extensions and your admin session are not in the way.
    2. DevTools → Console. Reload.
    3. DevTools → Network → filter JS. Reload again.

    Write down, in this order:

    • The first red error (file name and line). Later errors are often fallout.
    • Whether user.js (or the extension file you care about) appears, and its HTTP status.
    • Whether the URL is /media/templates/site/{active-template}/js/user.js.

    A 404 is a path problem (Step 2). A 200 plus a TypeError is a runtime problem (Steps 3 to 6). No request at all means the template never registered the asset, or you pasted the script in a Custom module that is unpublished: Joomla module not showing.

    If the console is clean and the feature still “does nothing,” the script ran against markup that is not on this view. Inspect the DOM. CSS hiding the node is CSS changes not showing, not a JS failure.

    Step 2: Put user.js on the media path of the active template

    Cassiopeia loads user.js the same way it loads user.css: from the assigned template’s media folder.

    On Joomla 4.1, 5, and 6:

    media/templates/site/{template}/js/user.js

    A child named cassiopeia_brand uses media/templates/site/cassiopeia_brand/js/user.js. A child does not load the parent’s user.js. If you added the file on Cassiopeia and then assigned the child, the public page will not request the parent script.

    In Template Manager:

    1. System → Templates → Site Templates → the active template (child if you have one).
    2. New File. Select the js folder.
    3. Filename: user with no suffix. File type: .js.
    4. Create, paste, Save.

    The Joomla 4.0-era path templates/cassiopeia/js/user.js is the same class of mistake as the old CSS folder. Current Cassiopeia looks in media/. Filename user.js.js 404s for the same reason as user.css.css.

    Confirm the menu item’s Template Style. Home can use the child while the page you tested still uses the parent. Two styles, two user.js files.

    Cassiopeia typically registers user.js through the Web Asset Manager as a deferred classic script, not as type="module". That matters in Step 4.

    How to add JS through WAM, a Custom module, or an extension asset JSON: Add custom JavaScript to Joomla. This checklist stops when the file is in the right folder and the Network tab shows 200.

    Step 3: Separate jQuery snippets from vanilla and from ES modules

    Joomla 4, 5, and 6 front ends are not Joomla 3.

    Cassiopeia uses Bootstrap 5. It does not enqueue jQuery for every page. $ and jQuery exist only if some extension called the jQuery asset (jquery / jquery-noconflict in the Web Asset Manager). A blog you copied that starts with jQuery(document).ready(...) will throw $ is not defined on a stock site.

    Fixes that are honest:

    • Rewrite the snippet in vanilla JS (document.addEventListener('DOMContentLoaded', …)).
    • If you truly need jQuery, load it as a dependency of your asset, not by pasting a second copy of jQuery 1.12 into user.js. Duplicate jQuery is a classic conflict (Step 6).

    ES modules: import / export are a SyntaxError in a non-module script. Cassiopeia’s user.js is a normal deferred file. Do not put import { … } from '…' in it unless you register that file as a module asset (type="module") in joomla.asset.json. Mixing module syntax into user.js is why “I followed a Vite example and Joomla exploded.”

    document.write and inline onclick= in article HTML are separate from user.js. They fail for the same CSP reasons in Step 5, and they are harder to cache-bust. Prefer one file in the child.

    Step 4: Account for defer, order, and DOM timing

    Web Asset Manager can output defer (Cassiopeia’s user.js usually has it). Deferred scripts run in order after the document is parsed. They do not run before a script without defer that sits earlier in the HTML.

    Typical races:

    • Your user.js assumes a calendar plugin’s global already exists. That plugin’s file is deferred later, or only loads on one menu item.
    • An inline script in a Custom module runs immediately, then user.js runs later and overwrites it (or the reverse).
    • You query #mod-finder-searchword on a page that has no finder module. querySelector returns null. The next line throws. The rest of user.js never runs. Put a guard around the node, or split files.

    Do not “fix” order by pasting <script> into core index.php. Register dependencies in joomla.asset.json or load from the child the way the custom JavaScript guide describes. Official model: Web Asset Manager.

    DOMContentLoaded in a deferred user.js may have already fired. If your snippet never runs, listen for DOMContentLoaded only when document.readyState === 'loading'; otherwise run immediately.

    Step 5: Check Content-Security-Policy and mixed content

    A file can 200 in Network and still never execute.

    System → Plugins → System – HTTP Headers. If Content-Security-Policy is on, script-src may allow 'self' and block:

    • Inline <script> in a Custom module or article
    • eval / new Function (some older sliders)
    • A CDN copy of jQuery or analytics you added in user.js via a remote URL
    • unsafe-inline missing when you still have inline handlers

    The console message is explicit: Refused to execute inline script or Refused to load the script 'https://…'. That is CSP, not a Joomla path bug. Loosen the policy on staging, or move the code into user.js on the same origin so 'self' allows it. Do not turn CSP off on production to “make a snippet work.”

    HTTPS pages that still request http:// scripts are mixed content. The browser blocks them. Same class of failure as images not loading on HTTPS.

    Server-level headers (Cloudflare, nginx add_header) override or duplicate the plugin. If the plugin is off and CSP still appears in Response Headers, fix the host, not Joomla.

    Step 6: Isolate a conflict without guessing

    Two scripts can both “work” and still cancel the feature.

    Signs:

    • The console shows your console.log at the top of user.js, then a third-party file throws, then your click handler is missing.
    • Bootstrap’s data-bs-toggle stops after you load a second Bootstrap JS.
    • A Mootools-era extension and a modern module both bind window.onload.

    On staging:

    1. Backup.
    2. System → Manage → Plugins. Batch-disable recently installed system plugins (not authentication). Retest.
    3. Switch the page to stock Cassiopeia (parent style) with an empty user.js. If the extension feature returns, your script or the child’s JS is the conflict.
    4. Re-enable plugins one at a time. Ordering on the same event is Joomla extension conflict.

    Do not debug this on production by disabling the Language Filter or Page Cache in public. Staging first.

    Clear Joomla cache after JS changes. Page Cache will keep old HTML that does not include your new <script src>. Guests then look like “JS does nothing” while you, logged in, skip Page Cache and see it work. Same guest-vs-login split as cache showing old content.

    Five checks: console, jQuery vs module, defer, CSP, user.js path

    Console first. Then jQuery versus module syntax. Then defer and order. Then CSP. Then the user.js path on the active template.

    Key takeaways

    1. Joomla JavaScript not working is a console diagnosis, not a reason to paste a second <script> into core.
    2. Cassiopeia user.js is media/templates/site/{template}/js/user.js on the active template. A child does not load the parent file.
    3. New File: name user, type .js. The old templates/…/js/ path is Joomla 4.0.
    4. $ is not defined on stock Cassiopeia. Rewrite vanilla or declare jQuery as a Web Asset dependency. Do not ship two jQuery copies.
    5. import belongs in a module asset, not in default deferred user.js.
    6. Deferred order and a missing DOM node throw and abort the rest of the file.
    7. CSP from HTTP Headers or the server will refuse inline and remote scripts even when Network is 200.
    8. Add files using Add custom JavaScript to Joomla. Keep them on a child.

    Frequently asked questions

    Why is my Joomla JavaScript not working?

    The console has a 404, a $ is not defined, a module SyntaxError, a CSP refusal, or an earlier exception that stopped the file. Read the first red line. Then confirm user.js is on the assigned template’s media path.

    Where do I put user.js in Joomla 5?

    media/templates/site/{template}/js/user.js, same pattern as user.css. Create it with filename user and type .js in the template’s js folder. Official customisation notes: Cassiopeia Template Customisation.

    Does Joomla 5 still include jQuery on every page?

    No. Cassiopeia does not load jQuery unless an extension (or your asset JSON) asks for it. Joomla 3 snippets that start with $ will fail on a stock 4, 5, or 6 site.

    Can Content-Security-Policy block user.js?

    'self' allows a same-origin user.js. It still blocks inline script in articles and many CDN URLs. Check the console for Refused to execute and the HTTP Headers plugin. Docs: HTTP Headers plugin.

    Why does my script work in the administrator but not on the site?

    Administrator uses Atum (or an Atum child). The site uses Cassiopeia (or a site child). user.js is per template. Put site scripts in the site child. Put admin scripts in an administrator child.

    Should I add JavaScript in this article or in the how-to?

    Use this page to find the failure. Use Add custom JavaScript to Joomla to register the file. Do not paste into core index.php.

    I cleared cache and guests still run old JS. Why?

    System – Page Cache stores full HTML. Logged-in users skip it. Clear cache, purge the CDN, test a private window. See cache showing old content.

    Conclusion

    When Joomla JavaScript is not working, the console already knows. 404 means the user.js path (child vs parent, media/ vs the old templates/ folder). $ is not defined means a Joomla 3 habit on a Cassiopeia page. import means a module in a classic deferred file. CSP means the headers, not SEF. Conflicts mean a second Bootstrap or a system plugin on staging, not a core hack.

    Add the file the supported way, on a child, using Add custom JavaScript to Joomla. If production is a pile of inline snippets and HTTP Headers, Joomla support and maintenance is cheaper than one more script tag in index.php.

  • Convert Decimal to Binary: Simple Techniques You’ll Need to Know

    Convert Decimal to Binary: Simple Techniques You’ll Need to Know

    The decimal number system is the same one we use on a daily basis. We employ decimals while dealing with money matters, determining distances, measuring the worth of products and during arithmetic computations. However, it’s the binary system that is utilized by computers since there are only two digits involved – zero and one – and the binary system represents numbers and other kinds of data stored in digital devices.

    If you’re a beginner learner, understanding decimal to binary conversions would become a necessary skill, which might sound difficult to you but actually it’s too easy with certain steps and practice.

    What Exactly is Decimal?

    The decimal number system is also referred to as the base-10 numeral system since it employs ten digits, namely, zero till nine.

    A position in a decimal number represents the power of ten. For instance, the decimal 245 can be put forth as-

    245 = 2 × 100 + 4 × 10 + 5 × 1

    Thus

    245 = 200 + 40 + 5.

    This place value system seems simple for people to comprehend and utilize.

    And what’s a Binary number?

    Binary is actually a base-2 numeral system where only two digits are used instead of ten:

    0 and 1.

    Each place in a binary number corresponds to the powers of two starting from right to left like-

    1, 2, 4, 8, 16, 32, 64, 128 and so on.

    Consider the binary 1011

    This is expandable as-

    1 × 8 + 0 × 4 + 1 × 2 + 1 × 1

    this gives:

    8 + 0 + 2 + 1 = 11

    Hence, 1011 in binary is 11 in decimal.

    How to convert it to binary from decimal?

    You must have come across so many methods, but the division by 2 method is too easy when converting a whole decimal number to binary.

    Keep dividing by 2 and writing down the remainder each time. Continue doing this until the quotient has become zero and then read the recorded remainders from bottom to top.

    Let’s convert a few numbers for proper understanding;

    Example 1: Convert 10 to binary

    Divide 10 by 2 to begin with-

    10 ÷ 2 = 5 remainder 0

    Now,

    5 ÷ 2 = 2 remainder 1

    Next,

    2 ÷ 2 = 1 remainder 0

    Finally,

    1 ÷ 2 = 0 remainder 1

    And finally, read from bottom to top-

    1010

    Hence, 10 in decimal is equivalent to 1010 in binary. We can now check the answer using place values:

    1010 = 1 × 8 + 0 × 4 + 1 × 2 + 0 × 1

    = 8 + 2

    = 10

    So the answer is definitely correct.

    Example 2: Convert 13 to binary

    Keep repeating step 1 with the number 13-

    13 ÷ 2 = 6 remainder 1

    Then,

    6 ÷ 2 = 3 remainder 0

    Next,

    3 ÷ 2 = 1 remainder 1

    Finally,

    1 ÷ 2 = 0 remainder 1

    Hence, read from bottom to top-

    1101

    And thus, 13 in decimal is equivalent to 1101 in binary. Check using place values again:

    1101 = 1 × 8 + 1 × 4 + 0 × 2 + 1 × 1

    = 8 + 4 + 1

    = 13.

    Example 3: Convert 25 to binary

    Let’s try a bigger number and convert it:

    25 ÷ 2 = 12 remainder 1

    12 ÷ 2 = 6 remainder 0

    6 ÷ 2 = 3 remainder 0

    3 ÷ 2 = 1 remainder 1

    1 ÷ 2 = 0 remainder 1

    Reading remainders from bottom to top we’ve:

    11001

    Hence, 25 in decimal is equivalent to 11001 in binary. Let’s put it up to check-

    11001 = 1 × 16 + 1 × 8 + 0 × 4 + 0 × 2 + 1 × 1

    = 16 + 8 + 1

    = 25.

    Alternative method: using powers of 2

    Another basic method to convert a decimal number into a binary number would be to find out powers of 2 which add up to the decimal number and hence determine a binary value. Let’s find out the binary representation for decimal 18.

    Powers of 2 are: 1, 2, 4, 8, 16, 32 and so on.

    To sum 18, we require:

    16 + 2 = 18.

    So for 16 we will place a 1, then 0 for 8, 0 for 4, 1 for 2, and 0 for 1, hence,

    10010.

    Thus, 18 in decimal is equivalent to 10010 in binary.

    This method is useful as it helps you know what particular position in a binary number represents.

    Some errors made by beginners

    There are a few errors commonly made by students when they are converting decimal numbers into binary numbers. Reading the remainders in the wrong order is one, then forgetting remainders (which have a value of 0 or 1), not continuing until the quotient has reached zero or incorrectly remembering what an equivalent place value represents. They mix them up; 10 is not the same as 2, but binary 10 is 2. In binary numbers, any position represented in place value stands for some power of 2 instead of 10.

    Importance of decimal to binary conversion

    Understanding decimal to binary conversion helps people understand how computers store different kinds of information. The values such as 0 or 1 each stand for 1 bit, which helps computers process information. Other subjects like digital logic, computer architecture or binary computation can also be understood.

    When you need to check a conversion or work with different number-system values, a Binary Converter can also be useful for getting a quick result while learning the manual process.

    What a user could think at the end of the session?

    Converting decimal to binary can be seen as a task which depends on a few rules in the division method where numbers continue to get divided by 2 and recording the remainder each time until the quotient becomes zero and then reading remainders from bottom to top and hence obtaining binary values like:

    10 = 1010, 13 = 1101, 18 = 10010, 25 = 11001, as demonstrated above using these binary values, this conversion task may seem much fun.