Home:mylayout, stored internally as mylayout in the article_layout key of the article's attribs).5.4
The article renders using the alternate layout selected in Layout on the article itself (components/com_content/tmpl/article/mylayout.php or its template override), exactly as it did before upgrading to 5.4.x.
The article silently falls back to default.php. No PHP notice, warning or exception is raised — HtmlView::loadTemplate() just resolves default.php because getLayout() never returns anything other than default.
The per-article Layout override (Advanced Options tab) only keeps working when the article is opened through a "Single Article" menu item whose own menu-level layout query var matches — i.e. exactly the one case where the article's own article_layout param isn't actually needed, because the menu item alternate layout mechanism handles it independently (components/com_content/src/View/Article/HtmlView.php, isset($active->query['layout']) branch).
com_content onlyJoomla\Component\Content\Site\Model\ArticleModel::getItem() builds $data->params for the single-article view. In 5.3.1 this was:
// Convert parameter fields to objects.
$registry = new Registry($data->attribs);
$data->params = clone $this->getState('params');
$data->params->merge($registry);The full article attribs registry (which includes article_layout) is unconditionally merged into $data->params.
In 5.4.7, presumably as part of the "use global / use article" per-field options work, this was changed to:
// Convert parameter fields to objects.
$registry = new Registry($data->attribs);
$data->params = clone $this->getState('params');
$globalParams = ComponentHelper::getParams('com_content', true);
$menuParamsArray = $this->getState('params')->toArray();
$articleArray = [];
foreach ($menuParamsArray as $key => $value) {
if ($value === 'use_article') {
if ($registry->get($key) != '') {
// Article has an explicit value, use it
$articleArray[$key] = $registry->get($key);
} else {
// Article is "Use Global", fall back to global component param
$articleArray[$key] = $globalParams->get($key);
}
}
}
if (\count($articleArray)) {
$data->params->merge(new Registry($articleArray));
}The wholesale $data->params->merge($registry) call was dropped. Now $data->params only ever receives keys from the article's own attribs when the corresponding menu/category param for that same key is literally the sentinel string 'use_article'. article_layout is not one of the fields that participates in that "use global/use article" selector — it's a standalone layout override — so it is never copied over anymore, no matter what the article itself has set. Every other value on $data->params ends up being whatever the active menu/category state already had, i.e. the article's own explicit settings for anything not modeled by the "use_article" convention are lost.
components/com_content/src/View/Article/HtmlView.php then reads $item->params->get('article_layout') to call setLayout(), and now always gets an empty value in this scenario, so the layout resolution in Joomla\CMS\MVC\View\HtmlView::loadTemplate() falls back to default silently (by design, via the "alternate layout can't be found, fall back to default layout" branch — except here it's not even "can't be found", the layout name was never set to begin with).
Restore the full registry merge before applying the use_article overrides, so article-level params still win as a baseline and the use_article loop only handles the specific opt-in/opt-out fields it was designed for:
$data->params = clone $this->getState('params');
$data->params->merge($registry); // <-- restore this line
$globalParams = ComponentHelper::getParams('com_content', true);
$menuParamsArray = $this->getState('params')->toArray();
$articleArray = [];
foreach ($menuParamsArray as $key => $value) {
if ($value === 'use_article') {
if ($registry->get($key) != '') {
$articleArray[$key] = $registry->get($key);
} else {
$articleArray[$key] = $globalParams->get($key);
}
}
}
if (\count($articleArray)) {
$data->params->merge(new Registry($articleArray));
}This keeps the new "use global / use article" behaviour intact for the fields it targets, while no longer discarding every other article-level param (most visibly article_layout, but potentially other custom-field-driven values too) that used to survive in 5.3.x.
I can open a PR with this change plus a regression test if that's useful — happy to follow whatever contribution process is preferred.
| Labels |
Added:
No Code Attached Yet
bug
|
||
| Status | New | ⇒ | Closed |
| Closed_Date | 0000-00-00 00:00:00 | ⇒ | 2026-07-26 13:46:38 |
| Closed_By | ⇒ | joomdonation |
Thanks for reporting @jcmelean . The issue was fixed by this PR #48060 and will be available in the next release 5.4.8. You can apply the change from that PR to your site now or wait for next release.