Page 1 of 2

pass parameters to module chrome?

Posted: Mon Nov 20, 2006 10:16 pm
by mike_dowler
sorry for the complete newbie question, but I had a crazy idea..

I have set up a modules.php file in my template/html folder to create a custom output chrome (rounded corners using css).

Is it at all possible to pass a parameter to the function when calling it?  I would like to be able to have a single layout style, and insert class names for different colour schemes, which are then defined in css.

so, for example in my template index, I would have my <jdoc ... style="rounded(whiteonblue)", or <jdoc ... style="rounded(yellowonpink)" or whatever

in the modules.php i would have:

Code: Select all

function modChrome_rounded($colour)
which inserts

Code: Select all

<div class="$colour">
I could then define the different $colour versions in css.  Would this work at all? The alternative is to have lots of similar functions in modules.php, but that would be harder for others to edit...

Mike

Re: pass parameters to module chrome?

Posted: Mon Nov 20, 2006 10:41 pm
by Jinx
Sure this is possible, u just add your extra paramaters as attributes to the jdoc statement. Like :

Code: Select all

<jdoc:include type="modules" name="left" class="blue" />
Then in your modChrome the extra attributes can be accessed through the attribs array like

Code: Select all

function modChrome_rounded($module, &$params, &$attribs)
{
?>
	<div class="<?php echo $attribs['class'] ?>">
                <?php echo $module->content; ?>
	</div>		
<?php
}
}

Re: pass parameters to module chrome?

Posted: Mon Nov 20, 2006 11:27 pm
by mike_dowler
Jinx,

THANK YOU!!!  :-*

worked a treat!  I love it when I have an idea and can actually make it work.

Mike

Re: pass parameters to module chrome?

Posted: Mon Nov 20, 2006 11:58 pm
by Jinx
Your welcome :) Have fun playing with Joomla! 1.5 !

Re: pass parameters to module chrome?

Posted: Thu Sep 13, 2007 9:08 am
by BernardE
Hi

How is this different from the traditional module class suffix?

Re: pass parameters to module chrome?

Posted: Thu Sep 13, 2007 1:02 pm
by mike_dowler
The module class suffix is applied to individual modules, and changes the CSS class applied to that module, based on the modChrome used.  (e.g 'xhtml', 'raw', etc).  (Provided that the modCHrome incorporates the suffix, which all the standard ones do!)

The function modChrome_rounded in my earlier post is about creating a new style of modChrome, which can be called using the <jdoc... style="blah"... statement in the template.  The new modChrome will then be applied to each and every module in the particular template position (and hence called by the <jdoc.... statement).  It therefore overrides the default modChrome styles.  My question was about passing a parameter to that function.

Note that Jinx' use of 'class=...' is slightly misleading, as this has nothing to do with CSS classes - it's just a parameter.  It could equally well have been 'favourite_colour=....' or 'colour_of_bathroom=...'. The point is simply that it is included among the parameters sent to the modChrome_rounded function, and can then be retrieved by name.

HTH, Mike

Re: pass parameters to module chrome?

Posted: Fri Sep 14, 2007 5:51 am
by BernardE
Mike

I still do not see what can be achieved with custom module chrome that cannot be done with a class suffix (together with the default module chrome). I understand the logic of the rounded corners chrome, because you need the 4 div's to handle your four image placements to get the rounded corner look, but appart from that I do not see what you can do with module chrome.

I can see you can make structural changes to the way the module is presented, but there should be no CSS in the function. The example jinx gives defines a class in the function - can the same effect not be achieved by simple making use of xhtml module chrome and a class suffix?

Regards

Re: pass parameters to module chrome?

Posted: Fri Sep 14, 2007 12:51 pm
by mike_dowler
Sorry - I understand now.  There are a number of reasons why you might want to use a custom modChrome:

1)  To make the chosen module appearance the 'default'.  If a user of a template installs a new module, they will expect it to adopt the 'look' of the other modules in that template position.  If you rely simply on the suffix, this will need to be set for the new module on installation.  (A badly written module might not even make use of the suffix!) It is rather counter-intuitive to apply an extra setting (i.e. the class suffix) to every module, simply to achieve a default appearance.  In my view, suffixes should be used for exceptions, not the default.

2) To make the HTML output more human-readable.  I am thinking here particularly of nested divs.  At present, only the outer div in the standard XHTML chrome is given the suffix (IIRC).  It can be difficult to work out which of the inner divs is which, especially if the module output itself contains further divs. The CSS relies on the nesting level to differentiate, but because of the way CSS inherits, it is also necessary to include CSS for the module divs to 'undo' the CSS relating to the chrome.  I prefer to explicitly label the divs in the chrome, and then assign CSS to each individually, rather than relying on the nesting position.  That way, it is easier for me to spot the chrome divs in my HTML as well.

3) To allow parameters to apply to inner divs in the chrome, rather than just the outer one.  Suppose I have a series of nested divs, of which the third in the series can have one of two background colours.  It makes no sense to apply different classes to the outer two divs, even though they will be styled the same way.  With my custom chrome, I can set the third div to have a variable CSS class, while that of the outer divs remains static.

4) To add non-CSS effects.  Suppose I want to include some different HTML (i.e. not just divs).  I can only do this with modChrome.  I appreciate that I am not taking advantage of this in the example above, and that you realise this, but nevertheless I think this could be a useful feature.

5) Because it's so easy in J!1.5!!  If it gives me even just one of the benefits above, and it is so easy to do, then why not?  Plus, it has helped me to learn how to develop for Joomla!

I agree completely that Jinx' basic example isn't itself much use - he was just illustrating how it works in theory.  My implementation is a bit more complex than that.  Also, there isn't any CSS in the function (not quite sure what your point was here) - just a class name.  The CSS itself is in the usual file.  Since the modChrome and the rest of the template are dependent on each other, I see no harm in this.

Hope that helps, Mike

Re: pass parameters to module chrome?

Posted: Mon Sep 17, 2007 8:10 pm
by BernardE
Hi Mike

Thanks for that extensive explanation. I understand and agree with all your points. I have been working away a bit and I have started to see a little bit of the usefulness of modChrome. I assume more uses will become apparent as you play around with it.
mike_dowler wrote: Also, there isn't any CSS in the function (not quite sure what your point was here) - just a class name.
You are correct, what I said there is actually rubbish - as you say it is only a class name, not CSS.

Anyway, thanks
Bernard

Re: pass parameters to module chrome?

Posted: Mon Sep 17, 2007 8:43 pm
by mike_dowler
Cool - glad to help. Hope you have fun playing!!  8)

Re: pass parameters to module chrome?

Posted: Mon Sep 17, 2007 9:33 pm
by Jinx
BernardE wrote: ... I have been working away a bit and I have started to see a little bit of the usefulness of modChrome. I assume more uses will become apparent as you play around with it.
The new way of doing things in 1.5 does take a bit of time to get used too, but I'm happy to see that you are getting the hang of it and start the see the flexibility created by the new system.

@Mike : Thanks for the work explaining the new system always good to see people helping each other out. Would you be interested in doing a more formal write-up that can be used by the documentation team ? I would be happy to collaborate on it just don't have the time to do it myself at the moment.

Johan

Re: pass parameters to module chrome?

Posted: Sun Sep 23, 2007 7:35 pm
by mike_dowler
Jinx - I'll see what I can do

Mike

Re: pass parameters to module chrome?

Posted: Mon Aug 25, 2008 2:58 pm
by phil_
This thread helped me learn about chrome for Joomla!, which is a great feature. What do you guys think of this idea for a chrome? I wanted something that would identify first and last modules using css classes. Also, it will give a numbered css class name for each. This lets me add specific styles to the first, last, or any number module, in a very flexible way.

Code: Select all

function modChrome_count($module, &$params, &$attribs)
{
	if (!empty ($module->content)) : 
		$document = &JFactory::getDocument();
		static $modulenumber = 1;
		$class = $params->get('moduleclass_sfx');
		$class .= ' module-number-'.$modulenumber;
		if( $modulenumber == 1 ) {
			$class .= ' first';
		} else if ( $modulenumber == $document->countModules( $attribs['name'] ) ) {
			$class .= ' last';
		}
		$modulenumber++;
		?>
		<div class="moduletable<?php echo $class; ?>">
		<?php if ($module->showtitle != 0) : ?>
			<h3><?php echo $module->title; ?></h3>
		<?php endif; ?>
			<?php echo $module->content; ?>
		</div>
	<?php endif;	
}
*NOTE: You must clear the module cache if you change the order of your modules that use this function, or they will not have the correct css class names assigned. Once the module cache is cleared, it should regenerate the correct css classes.

Re: pass parameters to module chrome?

Posted: Sun Dec 07, 2008 2:37 pm
by carsten888
I want to hide the chrome of a module from within the modulecode (dynamically) when the module does not output anything.

As a workaround I tried to the set the class of the chrome like so:

Code: Select all

$params->def('moduleclass_sfx','display_none');
so the module would be hidden with css, but that does not work.

how to hide the chrome of a module when it is empty?
or
how to set the class-name of a module dynamically from within the module?

Re: pass parameters to module chrome?

Posted: Sun Dec 07, 2008 8:30 pm
by phil_
carsten888 wrote:I want to hide the chrome of a module from within the modulecode (dynamically) when the module does not output anything.

As a workaround I tried to the set the class of the chrome like so:

Code: Select all

$params->def('moduleclass_sfx','display_none');
so the module would be hidden with css, but that does not work.

how to hide the chrome of a module when it is empty?
or
how to set the class-name of a module dynamically from within the module?
You might want to do this...

Code: Select all

<?php if ( $this->countModules( 'user2' ) ) : ?>								
    <jdoc:include type="modules" name="user2" style="xhtml" />
<?php endif;?>
this will only display the chrome / module content if a module is published to the position.

Re: pass parameters to module chrome?

Posted: Mon Dec 08, 2008 9:28 am
by carsten888
this will only display the chrome / module content if a module is published to the position.
thank you, but that is not what I need here.
the module is published. I want to hide the chrome when the module does not have any output, from within the module code.

mod_example/mod_example.php

Code: Select all

$today = get_day($time);
//get stuff from database
$database->setQuery("SELECT something FROM #__table WHERE date='$today'");
$result_array = $database->loadResultArray();	
$result_thing = $result_array[0];

//check if there is output
if($result_thing!=''){
//display stuff
echo 'today:<br />';
echo $result_thing;
}else{
//hide chrome
//do something magical to hide the chrome this thing is loaded in.
}
In the example I take something from the database that is date-specific. So when there is nothing in the db to match today, it does not just show an empty chrome. Of course I could show a message like 'nothing here today', but that is not what I'm after.

Can that be done at all?
:)

Re: pass parameters to module chrome?

Posted: Mon Dec 08, 2008 5:16 pm
by phil_
carsten888 wrote: Can that be done at all?
:)
Yes, it could be done. In the chrome there are some objects that have all the module information, parameters, variables, etc... You could assign some property to this object in your module code. So in the chrome it could be accessed, and then using an if statement, you can control the output.

Basically, in your module code, you need to create a variable that knows whether to show or hide. And then use that information in the chrome.

Re: pass parameters to module chrome?

Posted: Mon Dec 08, 2008 9:07 pm
by mike_dowler
Typically, the variable would be

Code: Select all

$module->content
(no need to create a new variable!), so you would wrap your custom Module chrome in:

Code: Select all

if ($module->content) {
...
}
Note that you can't specify this as a Module developer though - it is up to the template creator (or template user) to do this.

Re: pass parameters to module chrome?

Posted: Tue Dec 09, 2008 9:00 am
by carsten888
@phil_:
You could assign some property to this object in your module code.
how? something like

Code: Select all

$module->chrome = 0;
Basically, in your module code, you need to create a variable that knows whether to show or hide. And then use that information in the chrome.
in the chrome? do you mean in the chrome-template? I was talking about coding from the actual module code. I'm working on a component which should be installable for many users, and as there is no chrome-installer, I got to use the module code to hide the wrapper.

@mike_dowler
Note that you can't specify this as a Module developer though - it is up to the template creator (or template user) to do this.
that would also be code for use in the template, right?

Re: pass parameters to module chrome?

Posted: Tue Dec 09, 2008 4:17 pm
by phil_
carsten888 wrote:@phil_:
You could assign some property to this object in your module code.
how? something like

Code: Select all

$module->chrome = 0;
The chrome can go in your template files. see templates/beez/html/modules.php for an example.

So all the code could go in there if you want. But it sounds like you want to have some conditional stuff to determine show / hide. So it might be better for you to put more of the code into your actual module code. You can set the flag to show / hide in your module code, and then use that information in your custom chrome. So that way the chrome remains pretty simple, it would just have an if($module->something == 'show') { ....

Re: pass parameters to module chrome?

Posted: Tue Dec 09, 2008 9:05 pm
by mike_dowler
@phil_: You don't need to create new parameter. Since the default module chromes won't check for $module->chrome, you are going to have to use a custom chrome anyway. Since you are doing that, you may as well just have the chrome check for $module->content to determine whether or not the chrome is shown. The OP only wanted to hide the chrome where there is no content to show.

@carsten888: Yes, all these options are for template use only. J! is all about separating the module content from the template presentation, so it is not possible for a module developer to control the way his module is presented by the template. If that seems harsh, just think what would happen if it were not the case - commercial modules/components only working with templates from the same developer, and so on. As a module designer, your control ends with the module output.

You could try filing a feature request to have the default chromes check for $module->output before displaying anything, so that you would potentially get the effect you want for all modules. On the plus side, there are very few modules that ever display nothing, so it's hardly a catastrophic change. On the minus, there might be some users who would prefer to show the null output (though I can't think why!). The only other possibility I can think of would be a plugin, though I don't really know much about them. It might be possible for a plugin event to trigger when the module is rendered, and prevent the chrome from displaying if a module is empty. Can anyone else comment on this?

Mike

Re: pass parameters to module chrome?

Posted: Wed Dec 10, 2008 8:21 am
by carsten888
. J! is all about separating the module content from the template presentation, so it is not possible for a module developer to control the way his module is presented by the template. If that seems harsh, just think what would happen if it were not the case - commercial modules/components only working with templates from the same developer, and so on. As a module designer, your control ends with the module output.
totally agree with you. I would be happy to make an installable chrome (which would output nothing), so users of my component could actually hide modules, but Joomla does not have an installer for chromes, so that's not an option.
The only other possibility I can think of would be a plugin, though I don't really know much about them. It might be possible for a plugin event to trigger when the module is rendered, and prevent the chrome from displaying if a module is empty.
I made loads of plugins, and the thing is, Joomla does not provide any plugin-event-handlers in modules. So when a module gets rendered, no plugin gets called! :eek:

So I guess that ends my quest for a way to do this within the system.

Re: pass parameters to module chrome?

Posted: Wed Mar 04, 2009 1:01 pm
by bratter
@phil_: Thanks for the great code snippet! I think however, that if you use the same chrome in multiple positions, the static will keep incrementing, not giving the desired effect. I inserted an

Code: Select all

... {
$class .= ' last';
$modulenumber = 1;
} ...
in my equivalent of your else if clause, and it now works a treat.

Cheers,
Brendan

Edit: Initially used unset, but didn't think of its scope on a static variable, so it seems that resetting to the initial value os the only way.

Re: pass parameters to module chrome?

Posted: Sat Feb 13, 2010 7:11 pm
by lcdweb
I'd like to piggyback on this thread with a related scenario --

I would like to be able to set the module chrome directly from the module params. So, for example, I might have a module position 'left' in my template and three different chrome types that I would potentially want to apply on a module by module basis. Rather than hardcoding the chrome in the template, I'd like to set it in the module params.

To do it right, that would probably mean reworking the core module component so that I can capture the value and pass it back to the template. But in the meantime, I was thinking of using the module suffix field as it's pretty universal to most modules.

But I'm not sure how to retrieve the module param setting and include it in the template jdoc statement. Any ideas?

Re: pass parameters to module chrome?

Posted: Sat Feb 13, 2010 11:09 pm
by Chris Davenport
If you add a module parameter called 'chrome' to the module XML, then try something like this:

Code: Select all

<?php $module = JModuleHelper::getModule( 'mod_something', 'module-title' );
$params = new JParameter( $module->params );
$chrome = $params->get( 'chrome' );
?>
<jdoc:include type="modules" name="left" style="<?php echo $chrome; ?>" />
The 'module-title' is only required if more than one module instance of type 'mod_something' is present.

Regards,
Chris.

Re: pass parameters to module chrome?

Posted: Sat Feb 13, 2010 11:27 pm
by lcdweb
Yeah -- I was hoping to achieve something more universal. I don't want to have to modify each module that I'm using -- which is why I was hoping to retrieve the module suffix value. There's no way, that I'm aware of, to use JParameter to retrieve the parameters for any modules as they're pulled into the template.

Re: pass parameters to module chrome?

Posted: Sat Feb 13, 2010 11:41 pm
by Chris Davenport
The module class suffix is just another parameter, so you can retrieve it in the same way:

Code: Select all

$chrome = $module->get( 'moduleclass_sfx' );
Regards,
Chris.

EDIT: Correction: should be

Code: Select all

$chrome = $params->get( 'moduleclass_sfx' );

Re: pass parameters to module chrome?

Posted: Sat Feb 13, 2010 11:59 pm
by lcdweb
Right -- but in your sample text, you're pulling parameters for a specific module. I would like this to be universal -- pull the module class suffix parameter for ANY module called by a module position.

And if I understand the flow correctly, your code would possible have problems because it can't determine what instance(s) of a module are pulled to a page until jdoc runs. It's a cart before the horse problem that I'm running into. I want to 1) know what modules are called on the page. 2) determine what the module class suffix field value is. 3) based on that value, render jdoc with a specific type of chrome. But *I think* (unsure) that 1 doesn't happen until 3 happens.

Re: pass parameters to module chrome?

Posted: Sun Feb 14, 2010 12:15 am
by Chris Davenport
Well, presumably you know which module positions you have available, so you can call JModuleHelper::getModules( 'position' ) for each of them. That returns an array of modules that will be rendered for that page in that module position. Then you can retrieve the module class suffix for each of them, decide which chrome style to apply, then construct the jdoc statements accordingly.

Note that all PHP code is executed before any of the jdoc statements are parsed, so it is okay to construct jdoc statements using PHP.

Regards,
Chris.

Re: pass parameters to module chrome?

Posted: Sun Feb 14, 2010 12:27 am
by lcdweb
ok, that sounds promising. i'll play with it.
thanks for the leads --