GTMENU
From TYPO3Wiki
| Teams Committees | This project/information is related to the Content Rendering - Team |
A GTMENU is a combination of GMENU and TMENU - by applying the following IProcFunc to your GMENU it gets rendered as a normal TMENU with the graphics loaded as CSS background-images. Very nice for screenreaders et. al. This type of menu has been successfully testet with the following browsers:
Win - IE5+, all Geckoes incl. NN 7.1+, Op. 7+
MAC - IE5, Safari, all Geckoes, Op
Linux - all Geckoes (could sb. try Konqueror and tell? works perfectly here with konqueror 3.4.3 on ubuntu)
To make things happen, you need to include the following IProcFunc. Copy the function to a textfile and save it somewhere in your fileadmin directory:
Contents |
GTMENU IProcFunc
<?php
class user_gtmenu {
/**
* Renders a GMENU like a TMENU with CSS background images
* best regards to the Content Rendering Group
*
* @author Stefan Beylen for http://we-make.net <intsys@swissinfo.org>
* @author Torsten Schrade <t.schrade@connecta.ag>
* date: 2005-01-12
*/
function GTMenu($I,$conf){
//kill unneccessary JS
unset($I["linkHREF"]["onMouseover"]);
unset($I["linkHREF"]["onMouseout"]);
unset($GLOBALS['TSFE']->additionalJavaScript);
$uniqueString=substr(md5(microtime()),0,10);
$I["linkHREF"]["class"]="gt-menu gt-".$uniqueString;
$I["parts"]["image"]=$I["title"];
$conf["parentObj"]->I = $I;
$conf["parentObj"]->setATagParts();
$I = $conf["parentObj"]->I;
$I["parts"]["ATag_begin"]=$I["A1"]."<span>";
$I["parts"]["ATag_end"]="</span>".$I["A2"];
preg_match("/[^>]*alt=\"(.*?)\"[^>]*/",$I['IMG'],$match['alt']);
preg_match("/[^>]*src=\"(.*?)\"[^>]*/",$I['IMG'],$match['src']);
preg_match("/[^>]*width=\"(.*?)\"[^>]*/",$I['IMG'],$match['width']);
preg_match("/[^>]*height=\"(.*?)\"[^>]*/",$I['IMG'],$match['height']);
if($conf[parentObj]->mconf['css2TempFile']) {
// writing css to an external stylesheet / start a temporary global register for that
$GLOBALS['TSFE']->register['GTMenu_csstemp']['1'] = 'a.gt-menu{display:block;text-decoration:none;background-repeat:no-repeat;background-position: top left;vertical-align:bottom;}';
$GLOBALS['TSFE']->register['GTMenu_csstemp']['2'] = 'a.gt-menu span{display:block;height:1px;width:1px;overflow:hidden;}';
// insert additional styles in case $imgPreload = img
if($conf[parentObj]->mconf['imgPreload'] == 'img') {
$GLOBALS['TSFE']->register['GTMenu_csstemp']['3'] = 'p.hidden{position:absolute;left:-2000px;display:block;width:1px;height:1px;overflow:hidden;margin-top:1px;margin-left:1px;}';
}
// write the different <a> tag styles to this register
$aStyles = 'a.gt-'.$uniqueString.'{background-image:url(../'.$match['src'][1].');width:'.$match['width'][1].'px;height:'.$match['height'][1].'px;}';
$GLOBALS['TSFE']->register['GTMenu_csstemp'][] = $aStyles;
// RO states
if(is_array($conf[parentObj]->result['RO'])) {
$GLOBALS['TSFE']->register['GTMenu_csstemp'][] = "a.gt-".$uniqueString.":hover{background-image:url(../".$conf[parentObj]->result['RO'][$I['key']]['output_file'].");}";
}
// implode the temporary register to the final register and write the resulting string to an external stylesheet
$GLOBALS['TSFE']->register['GTMenu_css'] = implode("\n", $GLOBALS['TSFE']->register['GTMenu_csstemp']);
$GLOBALS['TSFE']->additionalHeaderData["25041"] = TSpagegen::inline2TempFile($GLOBALS['TSFE']->register['GTMenu_css'], 'css');
} else {
// write css as embedded styles (default behaviour)
$GLOBALS['TSFE']->additionalHeaderData['25041']= "\t<style type=\"text/css\">\n\t\t/** GTMenu Styles **/\n\t\ta.gt-menu{display:block;text-decoration:none;background-repeat:no-repeat;vertical-align:bottom;}\n\t\ta.gt-menu SPAN{display:block;width:1px;height:1px;overflow:hidden;text-indent:-9999px;}";
$GLOBALS['TSFE']->additionalHeaderData['25045'].= "\t\ta.gt-".$uniqueString."{background-image:url(".$match['src'][1].");width:".$match['width'][1]."px;height:".$match['height'][1]."px;}\n";
// RO states
if(is_array($conf[parentObj]->result['RO'])) {
$GLOBALS['TSFE']->additionalHeaderData['25043'] = "\t\t".'img.hidden{position:absolute;left:-2000px;display:block;width:1px;height:1px;overflow:hidden;margin-top:1px;margin-left:1px;}'."\n";
$GLOBALS['TSFE']->additionalHeaderData['25045'].= "\t\ta.gt-".$uniqueString.":hover{background-image:url(".$conf[parentObj]->result['RO'][$I['key']]['output_file'].");}\n";
}
$GLOBALS['TSFE']->additionalHeaderData['25049'] = "\t</style>";
}
// doing the image preload stuff:
switch($conf[parentObj]->mconf['imgPreload']) {
case 'js':
// $GLOBALS['TSFE']->JSImgCode is left intact
break;
case 'external':
// use a temporary register that is imploded like above
$GLOBALS['TSFE']->register['GTMenu_jstemp'][] = $GLOBALS['TSFE']->JSImgCode;
// imploding to register and writing external file
$GLOBALS['TSFE']->register['GTMenu_js'] = implode("", $GLOBALS['TSFE']->register['GTMenu_jstemp']);
$GLOBALS['TSFE']->additionalHeaderData["25050"]=TSpagegen::inline2TempFile($GLOBALS['TSFE']->register['GTMenu_js'], 'js');
unset($GLOBALS['TSFE']->JSImgCode);
break;
case 'img':
// writing hidden <img>'s just after the body tag - has to be wrapped with <p></p> for XHTML Strict
if(!is_array($conf[parentObj]->result['RO'])) {
$GLOBALS['TSFE']->pSetup['bodyTagAdd'].= '>'."\n".'<p class="hidden"><img src="'.$match['src'][1].'" class="hidden" width="'.$match['width'][1].'" height="'.$match['height'][1].'" /></p';
}
// RO states
if(is_array($conf[parentObj]->result['RO'])) {
$GLOBALS['TSFE']->pSetup['bodyTagAdd'].= '>'."\n".'<p class="hidden"><img src="'.$match['src'][1].'" width="'.$match['width'][1].'" height="'.$match['height'][1].'" />'."\n".'<img src="'.$conf[parentObj]->result['RO'][$I['key']]['output_file'].'" width="'.$match['width'][1].'" height="'.$match['height'][1].'" /></p';
}
unset($GLOBALS['TSFE']->JSImgCode);
break;
default:
unset($GLOBALS['TSFE']->JSImgCode);
break;
}
return $I;
}
}
?>
Making it work
After you've saved the IProcFunc to your fileadmin, do the following steps:
1) Go to your root template and include the library:
page.includeLibs.gtmenu = fileadmin/path/to/the/function/gtmenu.txt
2) Add the function to your TypoScript GMENU
temp.myGMENU.IProcFunc = user_gtmenu->GTMenu
TypoScript
There are 2 new TypoScript Options for a GTMENU:
1) css2TempFile -> if this is set to 1, the menustyles are written to an external stylesheet
2) imgPreload -> you can set this to 'js', 'external' or 'img'.
- 'js' = renders some JavaScript for preloading images into the page header
- 'external' = renders the JavaScript for preloading images into an external file
- 'img' = renders hidden <img>'s that correspond to the background-images just after the <body> tag
The default setting is imgPreload (not set) / css2TempFile (not set) which results in just the CSS written to the pageHeader and nothing else.
Especially with :hover enabled (RO state), there are settings where you might notice "flickers". It's always good to preload images if you have RO enabled. On the other hand, if you're just using ACT, IFSUB or CUR states, you might not need this.
Some Benchmarks
Here are some basic benchmarks that might help you finding the setting of your choice
1. no imgPreload / no css2TempFile: Parsetime - 722 ms, big flicker on :hover
2. imgPreload=img / no css2TempFile: Parsetime - 771 ms, no flicker on :hover!
3. imgPreload=js / no css2TempFile: Parsetime: 766 ms, flicker on :hover
4. imgPreload=external / no css2TempFile: Parsetime: 539 ms, no flicker on :hover!!
5. imgPreload=external / css2TempFile=1: Parsetime: 742 ms, no flicker on :hover!
6. imgPreload=js / css2TempFile=1: Parsetime: 756 ms, flicker on :hover
7. imgPreload=img / css2TempFile=1: Parsetime: 765 ms, no flicker on :hover
Of course parsetime is a rather relative value. Also, some users have found that they don't have flickers on the settings we had. So best thing might be to test for yourself. Anyway, 4. seems to be the quickest and 5. the cleanest/best choice in our opinion.
Examples
You can find a working example here: http://www.stdwarp.org/?83
Cache Problem?
whenever i use imgPreload=external or css2TempFile=1 the typo3temp/ folder fills up with 10000's of css and js files ! Hello, thanks for this remark. Plz have a look on the GTMENU discussion page (second tab above)...
