Templates & Frontend
Conditional Layouts in Joomla Templates
A sidebar that leaves a gaping hole when its modules are unpublished is the mark of a template nobody finished. The fix is a handful of conditions in index.php: ask what is actually on the page, then emit only the markup that has something…
Count before you print
countModules() tells you how many published modules a position holds for the current page. Wrap the position — and the markup around it — in that check:
<?php if ($this->countModules('sidebar-left')) : ?>
<aside class="sidebar">
<jdoc:include type="modules" name="sidebar-left" style="card" />
</aside>
<?php endif; ?>
The wrapper has to be inside the condition, not around it. Putting only the jdoc:include inside is the classic mistake: the modules disappear and an empty <aside> keeps its width, padding and border.
Let the content area react
Decide the layout once at the top of the file, then use the result in your markup:
<?php
$hasSidebar = $this->countModules('sidebar-left') || $this->countModules('sidebar-right');
?>
<main class="content<?php echo $hasSidebar ? '' : ' content--wide'; ?>">
<jdoc:include type="message" />
<jdoc:include type="component" />
</main>
Declaring the variables at the top rather than repeating the calls inline keeps the template readable and means one place to change when positions are renamed.
Joomla also accepts a small expression syntax, which is handy when several positions share a wrapper:
<?php if ($this->countModules('top-a or top-b')) : ?>
Branch on the page, not just on modules
The other half of conditional layout is knowing which page you are rendering. Read it from the input:
use Joomla\CMS\Factory;
$app = Factory::getApplication();
$input = $app->getInput();
$option = $input->getCmd('option');
$view = $input->getCmd('view');
$menu = $app->getMenu()->getActive();
$isHome = $menu !== null && $menu->home;
That gives you the three conditions most templates need: the front page, a particular component, and a particular view within it. A common use is suppressing the breadcrumb trail on the front page, where it has nothing to say.
Restricting a block to logged-in visitors
Check the identity rather than the session:
if (!Factory::getApplication()->getIdentity()->guest) {
// visible to signed-in users only
}
Use this for presentation, never for protecting content. Hiding markup in a template is not access control — anything genuinely restricted belongs behind Joomla's access levels, which are enforced before the template ever runs.
A note on page class suffixes
Before adding a condition, check whether a page class suffix would do the job. Menu items can pass a class onto the page, which often replaces a PHP branch with a line of CSS — easier to maintain and cheaper to reason about later.