Adding Custom Joomla Module Chrome (Styles)

Module Chromes are ways of adding different styles to modules displayed with your template. They allow the users of your template to easily select from pre-defined module styles. For example, you could give your users the option to show the login form on a white background with a blue border, a grey background with curved borders, or with no additional style added at all. The administrator can select a module chrome option from the advanced tab of the module settings for any module(shown in screenshot).

Selecting a module style

Cassiopeia, the default Joomla 4/5 template, has two module chrome options. One is “card” and the other is “noCard”. This is what the login form looks like in the sidebar with each option selected.

Defining Module Chromes

Module Chromes are added by creating a new php file for each chrome/style under your template’s directory at joomla-root/templates/your-template/html/layouts/chromes

A good base to start with is the noCard chrome from Cassiopeia. You can just copy it from templates/cassiopeia/html/layouts/chromes/noCard.php to your template’s chromes folder.

Rename the chrome file to whatever you would like. Pick a name representative of the style you are using. For this example, I’m going to call mine blackBorder. It’s going to display modules with a black border around them.

noCard.php looks like this:

<?php

/**
 * @package     Joomla.Site
 * @subpackage  Templates.cassiopeia
 *
 * @copyright   (C) 2020 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\Utilities\ArrayHelper;

$module  = $displayData['module'];
$params  = $displayData['params'];
$attribs = $displayData['attribs'];

if ($module->content === null || $module->content === '') {
    return;
}

$moduleTag              = $params->get('module_tag', 'div');
$moduleAttribs          = [];
$moduleAttribs['class'] = $module->position . ' no-card ' . htmlspecialchars($params->get('moduleclass_sfx', ''), ENT_QUOTES, 'UTF-8');
$headerTag              = htmlspecialchars($params->get('header_tag', 'h3'), ENT_QUOTES, 'UTF-8');
$headerClass            = htmlspecialchars($params->get('header_class', ''), ENT_QUOTES, 'UTF-8');
$headerAttribs          = [];

// Only output a header class if one is set
if ($headerClass !== '') {
    $headerAttribs['class'] = $headerClass;
}

// Only add aria if the moduleTag is not a div
if ($moduleTag !== 'div') {
    if ($module->showtitle) :
        $moduleAttribs['aria-labelledby'] = 'mod-' . $module->id;
        $headerAttribs['id']              = 'mod-' . $module->id;
    else :
        $moduleAttribs['aria-label'] = $module->title;
    endif;
}

$header = '<' . $headerTag . ' ' . ArrayHelper::toString($headerAttribs) . '>' . $module->title . '</' . $headerTag . '>';
?>
<<?php echo $moduleTag; ?> <?php echo ArrayHelper::toString($moduleAttribs); ?>>
    <?php if ($module->showtitle) : ?>
        <?php echo $header; ?>
    <?php endif; ?>
    <?php echo $module->content; ?>
</<?php echo $moduleTag; ?>>Code language: PHP (php)

I have copied noCard.php from cassiopeia, renamed it to “blankBorder.php” and placed it in the chromes folder of the template I’m working with.

You can leave most of the file alone. We’re most concerned with the last few lines of code, where the module is actually displayed.

The module starts off with the module tag defined in the module settings under the advanced tab. The default tag is “div” so the module will appear in a div.

<<?php echo $moduleTag; ?> <?php echo ArrayHelper::toString($moduleAttribs); ?>>Code language: PHP (php)

The next lines check the module settings and see if it should display the title. If so, it displays the title by echoing the $header variable set previously.

<?php if ($module->showtitle) : ?>
    <?php echo $header; ?>
<?php endif; ?>Code language: PHP (php)

Finally, the content of the module itself is displayed with this code:

<?php echo $module->content; ?>Code language: PHP (php)

And then it ends with the module tag closing.

Modifying It

At a basic level, the only code you really need to display the module is $module->content;

Here is what it would look like if I just wanted to display the module content, with no set parent element, and no heading:

<?php
/**
 * @package     Joomla.Site
 * @subpackage  Templates.kevinsguides
 *
 * @copyright   (C) 2020 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\Utilities\ArrayHelper;

$module  = $displayData['module'];

?>

<?php echo $module->content; ?>Code language: PHP (php)

Next, I’ll add a black border and a white background using inline css styles:

<?php
/**
 * @package     Joomla.Site
 * @subpackage  Templates.kevinsguides
 *
 * @copyright   (C) 2020 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

defined('_JEXEC') or die;

use Joomla\Utilities\ArrayHelper;

$module  = $displayData['module'];

?>


<div style="border: 5px solid black; background: white;">
        <?php echo $module->content; ?>
</div>Code language: PHP (php)

Depending on your cache settings, you may need to clear the Joomla cache or re-save the module to see your changes:

Finally, I’ll add some code to show the module title again.

defined('_JEXEC') or die;

use Joomla\Utilities\ArrayHelper;

$module  = $displayData['module'];

?>


<div style="border: 5px solid black; background: white;">
<h3><?php echo $module->title; ?></h3>
        <?php echo $module->content; ?>
</div>Code language: PHP (php)

That’s it! It’s ugly, but that’s the general idea. You can add custom classes, styles, etc. to the chromes as needed.

0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments