Extension talk:Tabber
[edit] Thank you for this excellent extension! :D
It does just what I wanted, and more.
I like that you can put anything in a tab, yes: anything. Kudos. --Jacmoe 18:03, 25 April 2009 (UTC)
- thanks for the feedback! --Kenyu73 00:08, 26 April 2009 (UTC)
[edit] error msg Undefined variable: htmlTabs
Undefined variable: htmlTabs in ... on line 34
did you test this in different browsers? - just curious. Thinking of putting it on a public site.
Thanks! Evgeny Fadeev 23:48, 26 April 2009 (UTC)
- I think this is a warning, not an error correct? I didn't really go though and initialize the variables so trivial could pop up. I'll clean this up on the next release package though.
-
- Encountered the same problem. Fixed it by defining htmlTabs as nothing. Here's the code:
<?php
# Credits
$wgExtensionCredits['parserhook'][] = array(
'name'=>'Tabber',
'author'=>'Eric Fortin',
'url'=>'http://www.mediawiki.org/wiki/Extension:Tabber',
'description'=>'Create tabs that contain wiki compatible based data',
'version'=>'1.0'
);
$wgExtensionFunctions[] = "wfTabber";
// function adds the wiki extension
function wfTabber() {
global $wgParser;
$wgParser->setHook( "tabber", "renderTabber" );
}
function renderTabber( $paramstring, $params = array() ){
global $wgParser, $wgScriptPath;
$wgParser->disableCache();
$path = $wgScriptPath . '/extensions/tabber/';
$htmlHeader = '<script type="text/javascript" src="'.$path.'tabber.js"></script>'
. '<link rel="stylesheet" href="'.$path.'tabber.css" TYPE="text/css" MEDIA="screen">'
. '<div class="tabber">';
$htmlFooter = '</div>';
$htmlTabs = '';
$arr = explode("|-|", $paramstring);
foreach($arr as $tab){
$htmlTabs .= buildTab($tab);
}
return $htmlHeader . $htmlTabs . $htmlFooter;
}
function buildTab($tab){
global $wgParser;
if( trim($tab) == '' ) return '';
$arr = split("=",$tab);
$tabName = array_shift( $arr );
$tabBody = $wgParser->recursiveTagParse( implode("=",$arr) );
$tab = '<div class="tabbertab" title='.$tabName.'>'
. '<p>'.$tabBody.'</p>'
. '</div>';
return $tab;
}
[edit] edit section links within tabs don't work
I'm getting a message like this when I click on edit tab:
You tried to edit a section that doesn't exist. Since there is no section 2, there's no place to save your edit. Evgeny Fadeev 23:53, 26 April 2009 (UTC)
- I may have to add __NOEDITSECTION__ to the page to remove the section edits. I remember having the same issue with my presentation extension too. I'm not sure if they're really compatible in this manner. I'll dig a bit deeper though.
- same error:
- Cannot find section
- You tried to edit a section that does not exist. It may have been moved or deleted while you were viewing the page.
- Return to Generator.
- I added __NOEDITSECTION__ in between the <tabber> </tabber> tags and the section edit buttons disappeared. Igottheconch 20:49, 22 March 2011 (UTC)
- same error:
Is there a way to make the edit section links work, rather than just disable them?
[edit] tab wrapping
when I make browser window narrower then width of combined tabs, vertical spacing of tabs appears less then their height. so they are right on top of each other
Evgeny Fadeev 23:58, 26 April 2009 (UTC)
- I knew about this issue, but I'm not really sure currently how to fix that one. JavaScript doesn't have a "NOWRAP" like HTML (=. I haven't done much in the original authors JavaScript code so I'll have to walk though it.
[edit] behavior switch magic word
Do you think it would be nicer to have a magic word like:
__TABSECTIONS__
and have tabs generated from the section structure? maybe it might be possible to do it through javascript alone.
Cheers, Evgeny. Evgeny Fadeev 00:03, 27 April 2009 (UTC)
[edit] paragraphs glued
the extension seems to cause consecutive paragraphs to be combined into one.
makes text harder to read.
Evgeny Fadeev 00:27, 27 April 2009 (UTC)
- This one is interesting... dunno why its removing the extra whitespace. It shouldn't?!? I'll have to debug that one for sure! As a workaround, use <br> tags.
- reason
- a problem with <p> tags
Tabber Version 1.01
Workaround: Wrap your first or second paragraph in <p>paragraph tags</p>, and all of your paragraphs will be fine.
Problem:
<tabber> tab1= paragraph1 paragraph2 </tabber>
The paragraphs are combined because the extension adds a <p> in fornt and a </p> in back, so that the final HTML is
<p> paragraph1 paragraph2 </p>
So that's why the paragraphs seem to stick together.
If I wrap one of the paragraphs in <p> tags, everything is fine:
<tabber> tab1= paragraph1 <p>paragraph2</p> </tabber>
becomes
<p> paragraph1 </p><p>paragraph2</p>
--mendel 15:11, 15 July 2010 (UTC)
- Thanks for posting the issues you found. I have though of using sections, but that would limit the tabs to the page level (ie: wouldn't be able to add tabs to a table that contains links and such). I'll see what I can do about the other bugs you've mentioned too.
- Thanks! Eric
-
- Hi Eric.
-
- Take a look at this: http://www.bennadel.com/index.cfm?dax=blog:1563.view
-
- maybe it's possible to mark up tabs with html comments, then have js build the tabs in browser?
-
- That way everything would work normally even if javascript is off.
-
- Evgeny Fadeev 17:51, 27 April 2009 (UTC)
[edit] Auto Rotate
It would be nice to have an auto rotate from Tab to Tab so that it can function like a featured content box as well. Anyone know how to do this? please e-mail me: kdanko@finestationery.com
[edit] Favourite Tab
I'm using this extension on my main page and it would be really neat to be able to mark one tab as my favourite tab, to be automatically selected when I go to the wiki! Generally, I'm finding that most users use just one of the tabs most of the time, so I guess it would be a user-specific setting. Anyone have any ideas of how this could be achieved?
[edit] Problem space in the tabs
Hello,
I can not put as many words as a tab. How to save 2 or 3 words in a tab?
Thank you
If you want to give a tab a name that contains a space (for example, My Tab), you need to put double quotes around the tab name:
<tabber> "My Tab"=My tab contents. </tabber>
--79.141.36.39 10:43, 14 September 2009 (UTC)
- Using
instead of spaces should work also. It also should prevent tab name wrapping, I think. --63.175.18.130 18:29, 2 December 2010 (UTC)
[edit] Tabber with templates
Is there a way to use tabber with mediawiki Templates? Tabber doesn't seem to be able to interpret the parameters being passed to it. Any hints on how to make this work or am I just SOL? :)
<tabber>
{{sometemplate}}={{:Main_Page}}
|-|
{{{tab2|A Tab}}}=Text here
|-|
{{{tab3|Another Tab}}}={{:User:Tromo}}
</tabber>
Thanks, --Cforrest 22:11, 1 October 2009 (UTC)
- Any template variable I try tu use inside the <tabber> doesn't seem to get expanded. I wrote a mail to the author about this, maybe he finds the time to change it.
- Marcus 80.171.52.229 08:27, 4 October 2009 (UTC)
- Solution
The problem is caused by MediaWiki; it doesn't expand templates and template variables inside extension tags. Use the #tag magic word to circumvent this:
{{#tag:tabber|
"{{MediaWiki:tagline}}"={{{1|expands}}}
}}
|
<tabber>
"{{MediaWiki:tagline}}"={{{1|does not expand}}}
</tabber>
|
--mendel 15:26, 15 July 2010 (UTC)
[edit] Header
Header (second level: ==header== seems not to work if I {{:include} an article in a tab. I see the chapter in the table of contents and in the article itself, but not in the included articel-Bert
[edit] Parametres
Someone know how to use parametres in tabber? I cannot make him understand it. When I use some parametres, it just repeats it's name. Example:
<tabber>
Example={{{1}}}
|-|
Example2={{{2}}}
</tabber>
How to make it "understand" that variables? 85.89.189.241 16:55, 6 December 2009 (UTC)
-
- See above, Extension_talk:Tabber#Solution. --mendel 15:29, 15 July 2010 (UTC)
[edit] Incorrectly handles alignment
- E.g. this would be displayed fine:
<tabber> tab1=[[Image.01.png]] |-| tab2=[[Image.02.png]] </tabber>
- BUT if you try to align images:
<tabber> tab1=[[Image.01.png|left]] |-| tab2=[[Image.02.png|right]] </tabber>
tab borders appear as containing no text or images (one empty line), although tabs can be switched and tab data changes according to tabs you click.
- When aligning images, tabs' height seems to depend on the amount of text only, because if you enter something like this:
<tabber> tab1=Some text [[Image.01.png|left]] |-| tab2=Some other text [[Image.02.png|right]] </tabber>
the image will fit the tab only if there's enough text to provide for the tab's height.
[edit] Floating images
The problem is that the images float. The solution would be for the developer to add some tag with clear:both; to end of the tabbertab div. (You could probably kludge that with some site javascript.)
Fortunately, there is a simple workaround: add the tag yourself. If you're using a {{clear}} template on your wiki, that will do fine.
Examples:
<tabber> tab1=[[File:Wiki.png|left]] <p style="clear:both;" /> </tabber> |
<tabber>
tab1=[[File:Wiki.png|left]]
{{clear}}
</tabber>
|
--mendel 15:51, 15 July 2010 (UTC)
[edit] Cannot have tables in tabs
Hi, this is a great extension, but I'm having an issue where if a tab has a table in it, then it all just breaks! Also doesn't work if used within a template. Has anyone got this working with tables and templates?
Thanks!
mitchelln 11:55, 26 January 2010 (UTC)
re I'm using tabber with table-Templates and TableEdit Extension. No issues so far!
[edit] Issues with headers
I'm having a similar problem to the user above who couldn't get ==header== to work. If I include headers in a tab, the header itself doesn't appear but the rest of the text is formatted fine. If I don't include at least one, I get the running together of paragraphs that Evgeny Fadeev mentioned above. Other than that the extension is fantastic!
[edit] h2 and h3 headers disabled in tabber.css
tabber.css disables these headers by default; the culprits are the follwing lines near the end:
/* If desired, hide the heading since a heading is provided by the tab */
.tabberlive .tabbertab h2 {
display:none;
}
.tabberlive .tabbertab h3 {
display:none;
}
Workarounds: (use either)
- (preferred): have a site admin delete these lines from the tabber.css in the installed extension
- override the formatting by having a sysop add the following line to MediaWiki:common.css:
.tabberlive .tabbertab h2, .tabberlive .tabbertab h3 { display:block !important; } - use =level1= or ====level 4==== headers instead.
--mendel 16:06, 15 July 2010 (UTC)
[edit] nested tabber
how to use a taaber iside another tabber?
follow the easy steps as below and find the solution : step 1 : Extension:tabber should installed in your wiki Step 2: add the below code to your page where you want to use the nested tabber
<tabber>
First Tab =
Example Text 1
{{#tag:tabber|
Inner Tab 1 =
Example Text 3
{{!}}-{{!}}
Inner Tab 2 =
Example Text 4
}}
|-|
Second Tab =
Example Text 2
</tabber>
--Rishi.comm 11:44, 21 October 2011 (UTC)
[edit] How to refer to tab page
I would like to link to an article, described in a tab page. How should I define the link ? The only address I see is the address of the page, containing the tabber. When I manually choose a tab-page from the tabber, the URL of that page is the same, so apparently it is not possible to link directly to the tab-page by using a unique URL. Tried linking to it using section reference, but that doesn't work either.
--83.85.117.14 13:24, 12 April 2010 (UTC)
Found a solution: editing the tab-page gives you the URL of that page, which you can then use in the link. Don't know if this is the "official" solution, but at least it is one that works
- Yes, it would be great if a future version of tabber could parse the URL to find if any of the tab names are used as #anchor, and open that. --mendel 16:10, 15 July 2010 (UTC)
-
- Agree, that would be super cool Tsx11 04:46, 20 July 2010 (UTC)
[edit] Tabber prevents headers from showing
Pages containing Tabber display the headers wrongly. Only the first level used is displayed, all the other levels are ignored. They only show up, when you edit the page (so effectively the Tabber is gone) This makes pages containing a tabber rather unreadable.
Very good!
Thanks! Grat job! Congrats author.
Congratulations to author, you are a genius. 201.89.152.134 06:02, 5 June 2010 (UTC)
- Only level 2 and level 3 headers are affected. See Extension_talk:Tabber#h2_and_h3_headers_disabled_in_tabber.css above for a solution/workaround. --mendel 16:12, 15 July 2010 (UTC)
[edit] More Tabs not correctly break
hello there. how can i break the tabs?
it looks not good if i do something like this: http://img94.imageshack.us/img94/416/tabsz.jpg can someone help?
[Prof.Liebstrumpf] 13:13, 30 June 2010 (UTC)
- I can't get them to break like that at all, what wiki are you on? Can you link me to your page? --mendel 16:43, 15 July 2010 (UTC)
-
- I tested on MediaWiki v1.15.3. (localhost). The other version is v1.15.1 and have same probs.
- I tested on MediaWiki v1.15.3. (localhost). The other version is v1.15.1 and have same probs.
Link to the Testside: http://www.wonderkingwiki.de/index.php?title=Monster
I think its not breaking correctly because i wrote the tabs in " " [Prof.Liebstrumpf]
[edit] Extension broken in 1.15.4?
Hi,
I am in the process of migrating a wiki to a new setup (details below). I have tabbed pages using v1.0 of this extension working on the 1.15.1 wiki, but when I transfer them to the 1.15.4 wiki (also using v1.0 of the extension), the tabs are no longer functional and I see the text from all the tabs on the one page.
(I am aware the Apache and MySQL versions are a slight downgrade - I'm trying to keep to versions that will definitely work with my Linux kernel version)
| Current server | New server |
|---|---|
| Windows (XP-SP3) | Linux (SUSE-11.1) |
| Apache 2.2 | Apache 2.0 |
| MySQL 5.1.30 | MySQL 5.0.67 |
| PHP 5.2.8 | PHP 5.2.13 |
| Mediawiki 1.15.1 | Mediawiki 1.15.4 |
Has anyone else experienced this problem? Has a code change broken this extension somehow? Or is there some other reason based on my new setup?
AerosAtar 15:23, 24 July 2010 (UTC)
- I am having the same problem.
Product Version MediaWiki 1.15.5 (r77381) PHP 5.3.2-1ubuntu4.5 (apache2handler) MySQL 5.1.41-3ubuntu12.7 |
| Not working in 1.15.5 |
|---|
WIKIA WORKS
Wikia fixed this problem though:
MediaWiki 1.15.5 Wikia releases/20101129 (code r31083, configuration r26289) PHP 5.2.10-2ubuntu6.5 (apache2handler) MySQL 5.0.91-b22.lucid.0-log |
| Works on wikia with wikia skin and with monobook |
|---|
Tabber broke when wikia got their abhorrent new wikia/oasis skin. See the discussion here:
Here is the solution they used:
Here is the file:
Adamtheclown 21:53, 9 December 2010 (UTC)
- In trac.wikia-code.com, click the plain text button on the bottom of the page to download the file.
- I replaced tabber.js with the new wikia tabber.js and nothing happened. I used ?action=purge and it did not work. Adamtheclown 22:13, 9 December 2010 (UTC)
- I then replaced all three files with the wikia files, and it still did not work:
- Adamtheclown 22:19, 9 December 2010 (UTC)
- version from 12 months ago which worked on wikia 15.4 or 15.5:
- Tabber still does not work, even when purging the pages. Adamtheclown 22:31, 9 December 2010 (UTC)
- Other sites have tabber without an extension, for example:
- Coding at n:en:MediaWiki:Common.js and n:en:MediaWiki:Common.css
- Some wikia sites also. Adamtheclown 22:44, 9 December 2010 (UTC)
- Wow, I'm amazed you actually found the tabber stuff on wikinews. Especially that subpage, I didn't even remember it existed. Bawolff 23:54, 9 December 2010 (UTC)
- Google. :) Found your talk page archive when searching for tabber. Adamtheclown 04:23, 10 December 2010 (UTC)
- Wow, I'm amazed you actually found the tabber stuff on wikinews. Especially that subpage, I didn't even remember it existed. Bawolff 23:54, 9 December 2010 (UTC)
Tabber works for 1.16: http://gyazo.com/d03689b40813ee7187af7c9a9f04c264.png Bawolff's extension works too on 1.16 only, but not on 1.15.5:
I added the following, copying and pasting these pages from Wikinews:
-
- User:Trav/monobook.js (my user name)
- User:Trav/sandbox/tabs (my user name)
- User:Bawolff/tabber.js
- MediaWiki:Common.css
- MediaWiki:Common.js
- MediaWiki:NavigationTabs.js
So it appears like tabber does not work for 15.4 and 15.5
...but works for 1.16 and according to AerosAtar 1.15.1.
Adamtheclown 04:23, 10 December 2010 (UTC)
- screen shot of failing to get tabber to work on 1.15.4: http://gyazo.com/ccdd9d1f9ac0e400332f4d3934f9bc2f.png Adamtheclown 05:25, 10 December 2010 (UTC)
[edit] Tabber extension and Bawolff's wikinews tabs work in 1.15.4 and 1.15.5
I refreshed the page (ctrl+r), and Bawolff's tabs worked in
- 1.15.4: http://gyazo.com/08aff4a1e739739d9d2a90ad3b5193d1.png and
- 1.15.5: http://gyazo.com/e176b871216e8df87fbd12acaccca8e6.png Adamtheclown 05:27, 10 December 2010 (UTC)
- Refreshed pages with tabber on mediawiki 1.15.5: http://gyazo.com/38a5a2b328b0949289f6ee3fadc3c5c4.png it works too. Adamtheclown 05:34, 10 December 2010 (UTC)
[edit] Fix for 1.15.4 and 1.15.5
Adding a portion of MediaWiki:Common.js and MediaWiki:Common.css tabber code from wikinews makes this tabber extension work in 1.15.4 and 1.15.5 on all pages on your wiki. The other pages listed above are unneeded.
Here is the mediawiki:monobook.js I took from wikinews which allowed the extension to work.
Note that some of the code above the tabber section in mediawiki:monobook.js is required to make this extension work. I removed a lot of the coding not needed but not all of it.
| mediawiki:monobook.js |
|---|
/* Any JavaScript here will be loaded for all users on every page load. Some other stuff is located at [[mediawiki:monobook.js]] */
//The jslint stuff just covers the editintro for wikipedians for now.
/*global wgPageName, addOnloadHook, wgNamespaceNumber, getElementsByClassName */
/*jslint white: true, browser: true, undef: true, nomen: true, eqeqeq: true, bitwise: true, regexp: true, newcap: true, immed: true, indent: 1 */
/*members April, August, December, February, January, July, June, March,
May, November, October, September, UTC, dateFunc, dateRegex,
getElementById, getElementsByTagName, getTime, href, indexOf, length,
oldNews, parseDate, referrer, replace, title
*/
/*Avoid importScript() as it seems to slow down page-load time*/
// Adding functions to import external scripts
importedScripts = {}; // object keeping track of included scripts, so a script ain't included twice
function importScript( page ) {
page = encodeURIComponent(page.replace(/ /g, '_' ));
if (importedScripts[page]) return; else importedScripts[page] = true;
var scriptElem = document.createElement( 'script' );
scriptElem.setAttribute( 'type' , 'text/javascript' );
//increment the scrver to force hard refresh
scriptElem.setAttribute( 'src' , wgScript + '?title=' + page + '&action=raw&ctype=text/javascript' + '&scrver=7');
document.getElementsByTagName( 'head' )[0].appendChild( scriptElem );
}
function importStylesheet( page ) {
page = encodeURIComponent(page.replace(/ /g, '_' ));
if (importedScripts[page]) return; else importedScripts[page] = true;
if (document.createStyleSheet) {
document.createStyleSheet(wgScript + '?title=' + page + "&action=raw&ctype=text/css");
} else {
var styleElem = document.createElement('style');
styleElem.setAttribute('type', 'text/css');
styleElem.appendChild(document.createTextNode('@import "' + wgScript + '?title=' + page + '&action=raw&ctype=text/css";'));
document.getElementsByTagName('head')[0].appendChild(styleElem);
}
}
// for backwards compatibility
var addLoadEvent = addOnloadHook;
// Provides an easy way to disable load dependent features
function delLoadEvent(func) {
for (var i = 0; i < onloadFuncts.length; i++) {
if (onloadFuncts[i] == func)
onloadFuncts.splice(i, 1);
}
}
// hasClass()
// Description: Uses regular expressions and caching for better performance.
// Maintainers: w:User:Mike Dillon, w:User:R. Koot, w:User:SG
var hasClass = (function () {
var reCache = {};
return function (element, className) {
return (reCache[className] ? reCache[className] : (reCache[className] = new RegExp("(?:\\s|^)" + className + "(?:\\s|$)"))).test(element.className);
};
})();
// name of project
var wgProject = wgServer.replace("http://", "");
/*
==Tabber code==
*/
/*
This was originally from http://www.barelyfitz.com/projects/tabber/
This has been modified very slightly for wikinews by [[user:Bawolff]] (you can use any of my modifications under the same license as the original author specified)
Please note, only the tabber code is under the MIT license. (the rest is probably either cc-by, GPL, or some combination thereof. its not really clear)
Note i'm slowly modifying to use hasClass() as it is supposedly more efficient
==================================================
$Id: tabber.js,v 1.9 2006/04/27 20:51:51 pat Exp $
tabber.js by Patrick Fitzgerald pat@barelyfitz.com
Documentation can be found at the following URL:
http://www.barelyfitz.com/projects/tabber/
==================================================*/
function tabberObj(argsObj)
{
var arg; /* name of an argument to override */
/* Element for the main tabber div. If you supply this in argsObj,
then the init() method will be called.
*/
this.div = null;
/* Class of the main tabber div */
this.classMain = "tabber";
/* Rename classMain to classMainLive after tabifying
(so a different style can be applied)
*/
this.classMainLive = "tabberlive";
/* Class of each DIV that contains a tab */
this.classTab = "tabbertab";
/* Class to indicate which tab should be active on startup */
this.classTabDefault = "tabbertabdefault";
/* Class for the navigation UL */
this.classNav = "tabbernav";
/* add space between tabs to force line break. use class UseTabBreaks*/
this.spaceTabs = false;
/* When a tab is to be hidden, instead of setting display='none', we
set the class of the div to classTabHide. In your screen
stylesheet you should set classTabHide to display:none. In your
print stylesheet you should set display:block to ensure that all
the information is printed.
*/
this.classTabHide = "tabbertabhide";
/* Class to set the navigation LI when the tab is active, so you can
use a different style on the active tab.
*/
this.classNavActive = "tabberactive";
/* Elements that might contain the title for the tab, only used if a
title is not specified in the TITLE attribute of DIV classTab.
*/
this.titleElements = ['h2','h3','h4','h5','h6'];
/* Should we strip out the HTML from the innerHTML of the title elements?
This should usually be true.
*/
this.titleElementsStripHTML = true;
/* If the user specified the tab names using a TITLE attribute on
the DIV, then the browser will display a tooltip whenever the
mouse is over the DIV. To prevent this tooltip, we can remove the
TITLE attribute after getting the tab name.
*/
this.removeTitle = true;
/* If you want to add an id to each link set this to true */
this.addLinkId = false;
/* If addIds==true, then you can set a format for the ids.
<tabberid> will be replaced with the id of the main tabber div.
<tabnumberzero> will be replaced with the tab number
(tab numbers starting at zero)
<tabnumberone> will be replaced with the tab number
(tab numbers starting at one)
<tabtitle> will be replaced by the tab title
(with all non-alphanumeric characters removed)
*/
this.linkIdFormat = '<tabberid>nav<tabnumberone>';
/* You can override the defaults listed above by passing in an object:
var mytab = new tabber({property:value,property:value});
*/
for (arg in argsObj) { this[arg] = argsObj[arg]; }
/* Create regular expressions for the class names; Note: if you
change the class names after a new object is created you must
also change these regular expressions.
*/
this.REclassMain = new RegExp('\\b' + this.classMain + '\\b', 'gi');
this.REclassMainLive = new RegExp('\\b' + this.classMainLive + '\\b', 'gi');
this.REclassTab = new RegExp('\\b' + this.classTab + '\\b', 'gi');
this.REclassTabDefault = new RegExp('\\b' + this.classTabDefault + '\\b', 'gi');
this.REclassTabHide = new RegExp('\\b' + this.classTabHide + '\\b', 'gi');
/* Array of objects holding info about each tab */
this.tabs = new Array();
/* If the main tabber div was specified, call init() now */
if (this.div) {
this.init(this.div);
/* We don't need the main div anymore, and to prevent a memory leak
in IE, we must remove the circular reference between the div
and the tabber object. */
this.div = null;
}
}
/*--------------------------------------------------
Methods for tabberObj
--------------------------------------------------*/
tabberObj.prototype.init = function(e)
{
/* Set up the tabber interface.
e = element (the main containing div)
Example:
init(document.getElementById('mytabberdiv'))
*/
var
childNodes, /* child nodes of the tabber div */
i, i2, /* loop indices */
t, /* object to store info about a single tab */
defaultTab=0, /* which tab to select by default */
DOM_ul, /* tabbernav list */
DOM_li, /* tabbernav list item */
DOM_a, /* tabbernav link */
aId, /* A unique id for DOM_a */
headingElement; /* searching for text to use in the tab */
/* Verify that the browser supports DOM scripting */
if (!document.getElementsByTagName) { return false; }
/* If the main DIV has an ID then save it. */
if (e.id) {
this.id = e.id;
}
/* Clear the tabs array (but it should normally be empty) */
this.tabs.length = 0;
/* Loop through an array of all the child nodes within our tabber element. */
childNodes = e.childNodes;
for(i=0; i < childNodes.length; i++) {
/* Find the nodes where class="tabbertab" */
if(childNodes[i].className &&
hasClass(childNodes[i], this.classTab)) {
/* Create a new object to save info about this tab */
t = new Object();
/* Save a pointer to the div for this tab */
t.div = childNodes[i];
/* Add the new object to the array of tabs */
this.tabs[this.tabs.length] = t;
/* If the class name contains classTabDefault,
then select this tab by default.
*/
if (childNodes[i].className.match(this.REclassTabDefault)) {
defaultTab = this.tabs.length-1;
}
}
}
/* Create a new UL list to hold the tab headings */
DOM_ul = document.createElement("ul");
DOM_ul.className = this.classNav;
/* Loop through each tab we found */
for (i=0; i < this.tabs.length; i++) {
t = this.tabs[i];
/* Get the label to use for this tab:
From the title attribute on the DIV,
Or from one of the this.titleElements[] elements,
Or use an automatically generated number.
*/
t.headingText = t.div.title;
/* Remove the title attribute to prevent a tooltip from appearing */
if (this.removeTitle) { t.div.title = ''; }
if (!t.headingText) {
/* Title was not defined in the title of the DIV,
So try to get the title from an element within the DIV.
Go through the list of elements in this.titleElements
(typically heading elements ['h2','h3','h4'])
*/
for (i2=0; i2<this.titleElements.length; i2++) {
headingElement = t.div.getElementsByTagName(this.titleElements[i2])[0];
if (headingElement) {
t.headingText = headingElement.innerHTML;
if (this.titleElementsStripHTML) {
t.headingText.replace(/<br>/gi," ");
t.headingText = t.headingText.replace(/<[^>]+>/g,"");
}
break;
}
}
}
if (!t.headingText) {
/* Title was not found (or is blank) so automatically generate a
number for the tab.
*/
t.headingText = i + 1;
}
/* Create a list element for the tab */
DOM_li = document.createElement("li");
/* Save a reference to this list item so we can later change it to
the "active" class */
t.li = DOM_li;
/* Create a link to activate the tab */
DOM_a = document.createElement("a");
DOM_a.appendChild(document.createTextNode(t.headingText));
DOM_a.href = "javascript:void(null);";
DOM_a.title = t.headingText;
DOM_a.onclick = this.navClick;
/* Add some properties to the link so we can identify which tab
was clicked. Later the navClick method will need this.
*/
DOM_a.tabber = this;
DOM_a.tabberIndex = i;
/* Do we need to add an id to DOM_a? */
if (this.addLinkId && this.linkIdFormat) {
/* Determine the id name */
aId = this.linkIdFormat;
aId = aId.replace(/<tabberid>/gi, this.id);
aId = aId.replace(/<tabnumberzero>/gi, i);
aId = aId.replace(/<tabnumberone>/gi, i+1);
aId = aId.replace(/<tabtitle>/gi, t.headingText.replace(/[^a-zA-Z0-9\-]/gi, ''));
DOM_a.id = aId;
}
/* Add the link to the list element */
DOM_li.appendChild(DOM_a);
/* Add the list element to the list */
DOM_ul.appendChild(DOM_li);
/* add a space to get line breaks */
if (this.spaceTabs) {
DOM_ul.appendChild(document.createTextNode(" "));
}
}
/* Add the UL list to the beginning of the tabber div */
e.insertBefore(DOM_ul, e.firstChild);
/* Make the tabber div "live" so different CSS can be applied */
e.className = e.className.replace(this.REclassMain, this.classMainLive);
/* Activate the default tab, and do not call the onclick handler */
this.tabShow(defaultTab);
/* If the user specified an onLoad function, call it now. */
if (typeof this.onLoad == 'function') {
this.onLoad({tabber:this});
}
return this;
};
tabberObj.prototype.navClick = function(event)
{
/* This method should only be called by the onClick event of an <A>
element, in which case we will determine which tab was clicked by
examining a property that we previously attached to the <A>
element.
Since this was triggered from an onClick event, the variable
"this" refers to the <A> element that triggered the onClick
event (and not to the tabberObj).
When tabberObj was initialized, we added some extra properties
to the <A> element, for the purpose of retrieving them now. Get
the tabberObj object, plus the tab number that was clicked.
*/
var
rVal, /* Return value from the user onclick function */
a, /* element that triggered the onclick event */
self, /* the tabber object */
tabberIndex, /* index of the tab that triggered the event */
onClickArgs; /* args to send the onclick function */
a = this;
if (!a.tabber) { return false; }
self = a.tabber;
tabberIndex = a.tabberIndex;
/* Remove focus from the link because it looks ugly.
I don't know if this is a good idea...
*/
a.blur();
/* If the user specified an onClick function, call it now.
If the function returns false then do not continue.
*/
if (typeof self.onClick == 'function') {
onClickArgs = {'tabber':self, 'index':tabberIndex, 'event':event};
/* IE uses a different way to access the event object */
if (!event) { onClickArgs.event = window.event; }
rVal = self.onClick(onClickArgs);
if (rVal === false) { return false; }
}
self.tabShow(tabberIndex);
return false;
};
tabberObj.prototype.tabHideAll = function()
{
var i; /* counter */
/* Hide all tabs and make all navigation links inactive */
for (i = 0; i < this.tabs.length; i++) {
this.tabHide(i);
}
};
tabberObj.prototype.tabHide = function(tabberIndex)
{
var div;
if (!this.tabs[tabberIndex]) { return false; }
/* Hide a single tab and make its navigation link inactive */
div = this.tabs[tabberIndex].div;
/* Hide the tab contents by adding classTabHide to the div */
if (!div.className.match(this.REclassTabHide)) {
div.className += ' ' + this.classTabHide;
}
this.navClearActive(tabberIndex);
return this;
};
tabberObj.prototype.tabShow = function(tabberIndex)
{
/* Show the tabberIndex tab and hide all the other tabs */
var div;
if (!this.tabs[tabberIndex]) { return false; }
/* Hide all the tabs first */
this.tabHideAll();
/* Get the div that holds this tab */
div = this.tabs[tabberIndex].div;
/* Remove classTabHide from the div */
div.className = div.className.replace(this.REclassTabHide, '');
/* Mark this tab navigation link as "active" */
this.navSetActive(tabberIndex);
/* If the user specified an onTabDisplay function, call it now. */
if (typeof this.onTabDisplay == 'function') {
this.onTabDisplay({'tabber':this, 'index':tabberIndex});
}
return this;
};
tabberObj.prototype.navSetActive = function(tabberIndex)
{
/* Note: this method does *not* enforce the rule
that only one nav item can be active at a time.
*/
/* Set classNavActive for the navigation list item */
this.tabs[tabberIndex].li.className = this.classNavActive;
return this;
};
tabberObj.prototype.navClearActive = function(tabberIndex)
{
/* Note: this method does *not* enforce the rule
that one nav should always be active.
*/
/* Remove classNavActive from the navigation list item */
this.tabs[tabberIndex].li.className = '';
return this;
};
/*==================================================*/
function tabberAutomatic(tabberArgs)
{
/* This function finds all DIV elements in the document where
class=tabber.classMain, then converts them to use the tabber
interface.
tabberArgs = an object to send to "new tabber()"
*/
var
tempObj, /* Temporary tabber object */
divs, /* Array of all divs on the page */
i; /* Loop index */
if (!tabberArgs) { tabberArgs = {}; }
/* Create a tabber object so we can get the value of classMain */
tempObj = new tabberObj(tabberArgs);
/* Find all DIV elements in the document that have class=tabber */
/* First get an array of all DIV elements and loop through them */
divs = document.getElementsByTagName("div");
for (i=0; i < divs.length; i++) {
/* Is this DIV the correct class? */
if (divs[i].className &&
hasClass(divs[i], tempObj.classMain)) {
if (hasClass(divs[i], "UseTabBreaks")) {
tabberArgs.spaceTabs = true;
}
/* Now tabify the DIV */
tabberArgs.div = divs[i];
divs[i].tabber = new tabberObj(tabberArgs);
}
}
/******
Begin special case links for the howdy template.
This is kind of ugly, but as good a place as any to stick the code.
Creates magic links for certain ids, in certain tab boxes
*/
var howdy = document.getElementById('HowdyWelcomeTemplate');
if (howdy) {
var policy = document.getElementById('HowdyWelcomeTemplatePolicy');
var talk = document.getElementById('HowdyWelcomeTemplateDiscussions');
var a;
if (talk) {
a = document.createElement('a');
a.href = "#";
a.onclick = function() {howdy.tabber.tabShow(2); return false;} //show tab 3
a.appendChild(talk.firstChild);
talk.appendChild(a);
}
if (policy) {
a = document.createElement('a');
a.href = "#";
a.onclick = function() {howdy.tabber.tabShow(1); return false;} //show tab 2
a.appendChild(policy.firstChild);
policy.appendChild(a);
}
}
/*******
End special case code for special links
*****/
return this;
}
/*==================================================*/
function tabberAutomaticOnLoad(tabberArgs)
{
/* This function adds tabberAutomatic to the window.onload event,
so it will run after the document has finished loading.
*/
// var oldOnLoad;
if (!tabberArgs) { tabberArgs = {}; }
/* Taken from: http://simon.incutio.com/archive/2004/05/26/addLoadEvent */
/*oldOnLoad = window.onload;
if (typeof window.onload != 'function') {
window.onload = function() {
tabberAutomatic(tabberArgs);
};
} else {
window.onload = function() {
oldOnLoad();
tabberAutomatic(tabberArgs);
};
}*/
//Use the wiki onload
addOnloadHook(function() {
tabberAutomatic(tabberArgs);
})
}
/*==================================================*/
/* Run tabberAutomaticOnload() unless the "manualStartup" option was specified */
if (typeof tabberOptions == 'undefined') {
tabberAutomaticOnLoad();
} else {
if (!tabberOptions['manualStartup']) {
tabberAutomaticOnLoad(tabberOptions);
}
}
/*
End Tabber. Note, code after this line probably is not under the MIT license.
*/
|
Adamtheclown 16:32, 10 December 2010 (UTC)
[edit] Revision dates not correct
Hi,
I would like to add a revision date to my pages. I am using the Magic Words Revisionxxxx for that and on each individual page this is working fine. However, when I combine all these pages using Tabber, then the revision date shown in each tab is not the date of that page, but of the main page, containing the Tabber statements.
<tabber>
{{:somepage}} <-- I want the revision date of this page and not the one of the page containing the tabber statements
|-|
</tabber>
Is there a way to get the actual revision date of the article in the tab-page ? --Hadouma 08:27, 29 July 2010 (UTC)
[edit] Template parameter doesn't work with tabber
Hello. I want to use tabber in my template. Using the structure
{{#tag:tabber|
Tab1={{{1|}}}
|-|
Tab2={{{2|}}}
}}
I have only one tab. When I'm trying to make more tabs, they are not shown. Why? Is it a bug or I did something wrong?
--Tarasius.ua 12:02, 5 August 2010 (UTC)
- Same here. If I have two Tabs, only first shows up. 85.89.162.235 23:38, 22 August 2010 (UTC)
Try:
{{#tag:tabber|
Tab1={{{1|}}}
{{!}}-{{!}}
Tab2={{{2|}}}
}}
--Fandyllic 16:41, 26 August 2010 (UTC)
[edit] TOC display not correct
When I use a Table of Contents in a tab-page, the first line in the TOC box says
Content [view] [view] [view] [view] [view]
Clicking the first [view], shows the TOC allright, and the first [view] changes to [hide], the other four remain [view]
When I edit the tab-page and the page shows without the tabber, the TOC is as it should be
--Hadouma 07:47, 6 August 2010 (UTC)
[edit] instructions for installation
for an extension that is used on so many websites, the installation instructions section is absolutely terrible. where do the zipped files go? Adamtheclown 06:19, 15 November 2010 (UTC)
[edit] tabber
| code |
|
*/
*/
*/
*/
—The preceding unsigned comment was added by 118.96.152.116 (talk • contribs) |
[edit] XSS fix
Replace the buildTab function with:
function buildTab($tab){ global $wgParser; if( trim($tab) == '' ) return ''; $arr = split("=",$tab); $tabName = array_shift( $arr ); $tabBody = $wgParser->recursiveTagParse( implode("=",$arr) ); $tab = '<div class="tabbertab" title="'.htmlspecialchars($tabName).'">' . '<p>'.$tabBody.'</p>' . '</div>'; return $tab; }
This sanitizes the tabs.
Frozen Wind 18:44, 23 December 2010 (UTC) -- amended, see below
- htmlspecialchars is important, but $tabBody is actually already safe. So the above causes double escaping on the tab body (Which is not a security vulnrability, but certainly not a good thing) and doesn't fix the issue. However you were on the right track. The recursiveTagParser outputs safe html, so you don't need to escape that. It's the tab titles ($tabName) where the problem is. What you need to do is replace the function with:
function buildTab($tab){ global $wgParser; if( trim($tab) == '' ) return ''; $arr = split("=",$tab); $tabName = array_shift( $arr ); $tabBody = $wgParser->recursiveTagParse( implode("=",$arr) ); $tab = '<div class="tabbertab" title="'.htmlspecialchars($tabName).'">' . '<p>'.$tabBody.'</p>' . '</div>'; return $tab; }
(note, there is two differences: the htmlspecialchars difference, as well as adding the two double quotes. Both are important). This also fixes the related issue of tab titles not allowing spaces in them. Bawolff 04:56, 24 December 2010 (UTC)
[edit] The solution for: „Function split() is deprecated“
The function split() is deprecated in PHP 5.3.x.
So I’ve rewritten the source code in tabber.php:
Please use the script below.
Good luck, SVG 13:15, 9 April 2011 (UTC)
- With the vulnerability fix from above included, this becomes:
<?php # Credits $wgExtensionCredits['parserhook'][] = array( 'name'=>'Tabber', 'author'=>'Eric Fortin', 'url'=>'http://www.mediawiki.org/wiki/Extension:Tabber', 'description'=>'Create tabs that contain wiki compatible based data', 'version'=>'1.2' ); $wgExtensionFunctions[] = "wfTabber"; // function adds the wiki extension function wfTabber() { global $wgParser; $wgParser->setHook( "tabber", "renderTabber" ); } function renderTabber( $paramstring, $params = array() ){ global $wgParser, $wgScriptPath; $wgParser->disableCache(); $path = $wgScriptPath . '/extensions/tabber/'; $htmlHeader = '<script type="text/javascript" src="'.$path.'tabber.js"></script>' . '<link rel="stylesheet" href="'.$path.'tabber.css" TYPE="text/css" MEDIA="screen">' . '<div class="tabber">'; $htmlFooter = '</div>'; $htmlTabs = ''; $arr = explode("|-|", $paramstring); foreach($arr as $tab){ $htmlTabs .= buildTab($tab); } return $htmlHeader . $htmlTabs . $htmlFooter; } function buildTab($tab){ global $wgParser; if( trim($tab) == '' ) return ''; $arr = preg_split("/=/",$tab); $tabName = array_shift( $arr ); $tabBody = $wgParser->recursiveTagParse( implode("=",$arr) ); $tab = '<div class="tabbertab" title="'.htmlspecialchars($tabName).'">' . '<p>'.$tabBody.'</p>' . '</div>'; return $tab; }
[edit] Compatibilty issues with MW 1.17
It seem it would not work on my MW 1.17,even with the new code above
MediaWiki 1.17.0 PHP 5.3.5-1ubuntu7.2 (apache2handler) MySQL 5.1.54-1ubuntu4
--Msevero 23:43, 18 July 2011 (UTC)
- Works for me.
- MediaWiki 1.17.0
- PHP 5.3.8 (apache2handler)
- MySQL 5.1.56-log
- -- 12.117.176.190 22:05, 31 August 2011 (UTC)
Use my fixed code above. Then it should be work. SVG 17:21, 15 September 2011 (UTC)
-
- I got it working by copying the js.code to the mediawiki.js and of course by using your code thanks for the reply. --Msevero 08:10, 22 September 2011 (UTC)
There is a problem with including tabber.js in 1.17, I know. On my wiki I added the JavaScript to my MediaWiki:Common.js. I'll look to fix this bug and want to add this extension to Wikimedia's SVN for stable release. SVG 14:47, 16 October 2011 (UTC)
[edit] Use jQuery Instead
If you are using Mediawiki 1.17 or above, it is probably easier and faster to use jQuery to implement tabs instead of this extension.
--FlyingRagnar 02:09, 29 October 2011 (UTC)
- Does one simply use the Javascript on one of their respective JS pages, to implement what you are recommending? Bud0011 01:19, 8 February 2012 (UTC).
[edit] Help
It doesn't work for me on my Wikia profile - It results in the below (shown with 2 tabs):
- Tab 1 name
- Tab 2 name
Tab 1 content
Tab 2 content
193.63.86.28 18:40, 4 December 2011 (UTC)
[edit] Edit buttons work with Extension:Livelets
What really bothered about this extension is how the edit links [edit] had to be supressed with:
- __NOEDITSECTION__ <!--this removes the edit links in article which do not work with tabber -->
because [edit] no longer worked with this extension.
But if you install Extension:Livelets and put a livelet inside the tabber coding, you can once again edit the page and keep the [edit] link. Example:
<tabber>
Hotel =
{{#live: {{Template:Hotel Bungalows}} }}
|-|
Diamond =
[[ File:Dead_island_Diamond_Bungalows.jpg|230px|right]]
[[Diamond Bungalows District]]
</tabber>
Igottheconch 19:10, 16 December 2011 (UTC)