Saturday, March 27, 2010

joomla module chrome - advanced styling

The normal way of styling Module Headers is to add a Module Class Suffix in
Extensions > Modules > YourModule
and then pick it up in the template css file using a selector like moduletable-moduleclasssuffix. But what if you want to do more? What if you want a module header where the H3 color is gray, but the first word is blue? Or the last word is blue?

This article will show you how to modify h3 titles using Joomla's template overrides with module chrome and a bit help from the preg_replace function.



Step 1 – What's the Module Chrome?


Open the module you want to style up in Extensions > Module Manager and find out what position it's set to render in. In this example, the module is in the position: footer.

Next open up index.php in your default template folder and find out if any module chrome has been applied to the position: footer. See the example below.

index.php:
<div id="somediv">
<jdoc:include type="modules" name="footer" style="xhtml" />
</div>

Ok, the module chrome is xhtml. That's great because we're going to use the xhtml chrome to create a template override. Only xhtml and rounded chrome have a h3 header built in, so any other style is useless for this particular example. Other styles you might see are outline, none, table, horz. But none of these have h3 headers so this example won't work with those styles. Default Joomla module chrome can be found in templates > system > html > modules.php and this is the file that Joomla consults if these styles are used.

Step 2 – is there a template override in your default template?


Open up your default template and check if there is a folder called html. If there is, open it up and check for a file on the root of that folder – modules.php. This is where the template overrides happen, and where we'll put the new module chrome style that'll do all the magic.

If the html folder isn't present, then add it under your default template and put in a copy of modules.php from templates > system > html > modules.php. (Copy over the blank index.html while you're at it, for security sake).

If you've just copied modules.php over from the systems template then open it and delete all the functions inside it except for the xhtml chrome function. So to begin with, your default template's html > modules.php file will look like this:
<?php
// no direct access
defined('_JEXEC') or die('Restricted access');
function modChrome_xhtml ($module, &$params, &$attribs)
{
if (!empty ($module->content)) : ?>
<div class="moduletable<?php echo $params->get('moduleclass_sfx'); ?>">
<?php if ($module->showtitle != 0) : ?>
<h3><?php echo $module->title; ?></h3>
<?php endif; ?>
<?php echo $module->content; ?>
</div>
<?php endif;
}
?>

Since you can't just overwrite the system's default chrome names, you'll need to change the name of the chrome, eg to fancyxhtml
function modChrome_fancyxhtml ($module, &$params, &$attribs){

Now open up your default template's index.php and change the chrome name in the position you want it to show up in –
<div id="somediv">
<jdoc:include type="modules" name="footer" style="fancyxhtml" />
</div>

Step 3 – Add a Module Class Suffix to the module(s) that you want fancy styling for


Go back to Extensions > Module Manager and open up any modules in the footer position (or whatever position you've chosen) that you're going to use the fancy styles for. In Advanced Parameters add the following in Module Class Suffix –
-fancystyle


The reason to add the module class suffix is so that when we rewrite the fancyxhtml chrome (in templates > yourdefaulttemplate > html > modules.php), it will be the exactly the same as xhtml chrome, UNLESS the module class suffix is –fancystyle, in which case the fancy titles will show up. Otherwise, it'll render the same as ordinary xhtml chrome.

Step 4 – Coding the fancyxhtml chrome


In the html > modules.php file in your default template change the fancyxhtml chrome function as follows:
<?php
// no direct access
defined('_JEXEC') or die('Restricted access');

function modChrome_fancyxhtml ($module, &$params, &$attribs) {
if (!empty ($module->content)) : ?>
<div class="moduletable<?php echo $params->get('moduleclass_sfx'); ?>">
<?php
if ($module->showtitle != 0) :
if ($params->get('moduleclass_sfx')==='-fancystyle') :
$pattern = '/([\S]+)$/'; //match the last word
$title = preg_replace($pattern, "<span class="twotone">$1</span>",$module->title);
else :
$title = $module->title;
endif;
echo '<h3>' . $title . '</h3>';
endif;
echo $module->content;
?>
</div>
<?php endif;
} //end function
?>

If you want to apply the twotone style to the first word instead of the last word, just change the pattern to:
$pattern = '/^([\S]+)/'; //match the first word instead

Basic explanation of pattern matching:
\S - means match anything that is NOT a space.
[\S]+ - match any char that is NOT a space, 1 or more times
([\S]+) - the bracket picks up the entire match as a variable
([\S]+)$ - pick it up at the end of the string ($)
^([\S]+) - pick it up at the start of the string (^)
$n - substitute the variable from the nth bracket

If you want to know more about the incredibly versatile preg_replace functions start with http://php.net/manual/en/function.preg-replace.php

Step 5 – CSS for Styling


In the css file for your default template you could pick up the h3 styling as in:
.moduletable-fancystyle {background-color: #eeeeee;}
.moduletable-fancystyle h3 { color: #999999; }
.moduletable-fancystyle h3 .twotone { color: #0000FF; }



If you were to View > Source, you'd see:
<div class="moduletable-fancystyle">
<h3>Fancy <span class='twotone'>Module</span></h3><p>This is my fancy module with 2 tone colors in H3</p></div>

No comments:

Post a Comment