The tabs are stored on a separate page within the space and then imported in to the left sidebar...

The Basics

We create the tab effect in two key stages:

The actual implementation of this is quite verbose - so verbose that we're already thinking of ways to make it cleaner (we'll update this tutorial when we do).

We start with a block of wiki notation like the following, on the Tabs page (which also contains the tab images as page attachments):

{builder-show:title=Home}
 {menulink:home|tooltip=Home|class=stab}!Tabs^tab0.gif!{menulink}
 {bshow:About}{menulink:wikipage|page=About|tooltip=About}!Tabs^tab4.gif!{menulink}{bshow}
 {bshow:Forum}{menulink:wikipage|page=Forum|tooltip=Forum}!Tabs^tab6.gif!{menulink}{bshow}
 {menulink:news|tooltip=News}!Tabs^tab3.gif!{menulink}
 {bshow:Tutorials}{menulink:wikipage|page=Tutorials|tooltip=Tutorials}!Tabs^tab7.gif!{menulink}{bshow}
 {bshow:Documentation}{menulink:wikipage|page=Documentation|tooltip=Documentation}!Tabs^tab8.gif!{menulink}{bshow}
 {bshow:Support}{menulink:wikipage|page=Support|tooltip=Support}!Tabs^tab1.gif!{menulink}{bshow}
 {bshow:Development}{menulink:wikipage|page=Development|tooltip=Development}!Tabs^tab2.gif!{menulink}{bshow}
 {menulink:index|tooltip=Navigate}!Tabs^tab5.gif!{menulink}
 {style}.atb-leftslider {background-color:#cbffcf;}{style}
{builder-show}

In itself, this is fairly simple syntax - it's just a load of images with links wrapped round them. The active tag is marked by a class=stab ("selected tab") in the menulink that wraps the tab image - we'll explain why later in 4 - CSS.

The notation shown above will only be shown when you're looking at the page with title "Home" - otherwise it'll be hidden. There is a similar block of wiki notation for each of the other tabs that will show all tabs with the relevant tab selected depending on what you are looking at.

bshow macro

One of the limitations of Confluence is that you can't nest macros and this posed a problem because we wanted to use the builder-show macro within another builder-show macro.

To get round this problem we created a user macro called "bshow", set it to have a body (unprocessed) and output wiki notation. The macro template is as follows:

{builder-show:page=${param0}}${body}{builder-show}

When you then call:

{bshow:About}{menulink:wikipage|page=About|tooltip=About}!Tabs^tab4.gif!{menulink}{bshow}

The actual output is rendered as:

{builder-show:title=About}{menulink:wikipage|page=About|tooltip=About}!Tabs^tab4.gif!{menulink}{builder-show}

This effectively allows us to nest one builder-show macro within another and solves our problem.

Inline style

For the selected tab, we also use an inline style to set the background colour of the left slider bar to the same colour as the selected tab:

 {style}.atb-leftslider {background-color:#cbffcf;}{style}

This is a bit hacky but it has the major benefit of giving us complete control over the tab colours on a space by space basis and also ensuring the correct slider bar colour is set only when the associated tab is selected.

The full notation

We mentioned at the start of the tutorial that the full wiki notation was somewhat verbose - here it is in full:

{builder-show:title=Home}
 {menulink:home|tooltip=Home|class=stab}!Tabs^tab0.gif!{menulink}
 {bshow:About}{menulink:wikipage|page=About|tooltip=About}!Tabs^tab4.gif!{menulink}{bshow}
 {bshow:Forum}{menulink:wikipage|page=Forum|tooltip=Forum}!Tabs^tab6.gif!{menulink}{bshow}
 {menulink:news|tooltip=News}!Tabs^tab3.gif!{menulink}
 {bshow:Tutorials}{menulink:wikipage|page=Tutorials|tooltip=Tutorials}!Tabs^tab7.gif!{menulink}{bshow}
 {bshow:Documentation}{menulink:wikipage|page=Documentation|tooltip=Documentation}!Tabs^tab8.gif!{menulink}{bshow}
 {bshow:Support}{menulink:wikipage|page=Support|tooltip=Support}!Tabs^tab1.gif!{menulink}{bshow}
 {bshow:Development}{menulink:wikipage|page=Development|tooltip=Development}!Tabs^tab2.gif!{menulink}{bshow}
 {menulink:index|tooltip=Navigate}!Tabs^tab5.gif!{menulink}
 {style}.atb-leftslider {background-color:#cbffcf;}{style}
{builder-show}{builder-show:title=About|recurse=true}
 {menulink:home|tooltip=Home}!Tabs^tab0.gif!{menulink}
 {menulink:wikipage|page=About|tooltip=About|class=stab}!Tabs^tab4.gif!{menulink}
 {bshow:Forum}{menulink:wikipage|page=Forum|tooltip=Forum}!Tabs^tab6.gif!{menulink}{bshow}
 {menulink:news|tooltip=News}!Tabs^tab3.gif!{menulink}
 {bshow:Tutorials}{menulink:wikipage|page=Tutorials|tooltip=Tutorials}!Tabs^tab7.gif!{menulink}{bshow}
 {bshow:Documentation}{menulink:wikipage|page=Documentation|tooltip=Documentation}!Tabs^tab8.gif!{menulink}{bshow}
 {bshow:Support}{menulink:wikipage|page=Support|tooltip=Support}!Tabs^tab1.gif!{menulink}{bshow}
 {bshow:Development}{menulink:wikipage|page=Development|tooltip=Development}!Tabs^tab2.gif!{menulink}{bshow}
 {menulink:index|tooltip=Navigate}!Tabs^tab5.gif!{menulink}
 {style}.atb-leftslider {background-color:#e0fef6;}{style}
{builder-show}{builder-show:title=Forum|recurse=true}
 {menulink:home|tooltip=Home}!Tabs^tab0.gif!{menulink}
 {bshow:About}{menulink:wikipage|page=About|tooltip=About}!Tabs^tab4.gif!{menulink}{bshow}
 {menulink:wikipage|page=Forum|tooltip=Forum|class=stab}!Tabs^tab6.gif!{menulink}
 {menulink:news|tooltip=News}!Tabs^tab3.gif!{menulink}
 {bshow:Tutorials}{menulink:wikipage|page=Tutorials|tooltip=Tutorials}!Tabs^tab7.gif!{menulink}{bshow}
 {bshow:Documentation}{menulink:wikipage|page=Documentation|tooltip=Documentation}!Tabs^tab8.gif!{menulink}{bshow}
 {bshow:Support}{menulink:wikipage|page=Support|tooltip=Support}!Tabs^tab1.gif!{menulink}{bshow}
 {bshow:Development}{menulink:wikipage|page=Development|tooltip=Development}!Tabs^tab2.gif!{menulink}{bshow}
 {menulink:index|tooltip=Navigate}!Tabs^tab5.gif!{menulink}
 {style}.atb-leftslider {background-color:#ffe4ce;}{style}
{builder-show}{builder-show:context=blogpost,space-blogposts}
 {menulink:home|tooltip=Home}!Tabs^tab0.gif!{menulink}
 {bshow:About}{menulink:wikipage|page=About|tooltip=About}!Tabs^tab4.gif!{menulink}{bshow}
 {bshow:Forum}{menulink:wikipage|page=Forum|tooltip=Forum}!Tabs^tab6.gif!{menulink}{bshow}
 {menulink:news|tooltip=News|class=stab}!Tabs^tab3.gif!{menulink}
 {bshow:Tutorials}{menulink:wikipage|page=Tutorials|tooltip=Tutorials}!Tabs^tab7.gif!{menulink}{bshow}
 {bshow:Documentation}{menulink:wikipage|page=Documentation|tooltip=Documentation}!Tabs^tab8.gif!{menulink}{bshow}
 {bshow:Support}{menulink:wikipage|page=Support|tooltip=Support}!Tabs^tab1.gif!{menulink}{bshow}
 {bshow:Development}{menulink:wikipage|page=Development|tooltip=Development}!Tabs^tab2.gif!{menulink}{bshow}
 {menulink:index|tooltip=Navigate}!Tabs^tab5.gif!{menulink}
 {style}.atb-leftslider {background-color:#ffcbcb;}{style}
{builder-show}{builder-show:title=Tutorials|recurse=true}
 {menulink:home|tooltip=Home}!Tabs^tab0.gif!{menulink}
 {bshow:About}{menulink:wikipage|page=About|tooltip=About}!Tabs^tab4.gif!{menulink}{bshow}
 {bshow:Forum}{menulink:wikipage|page=Forum|tooltip=Forum}!Tabs^tab6.gif!{menulink}{bshow}
 {menulink:news|tooltip=News}!Tabs^tab3.gif!{menulink}
 {menulink:wikipage|page=Tutorials|tooltip=Tutorials|class=stab}!Tabs^tab7.gif!{menulink}
 {bshow:Documentation}{menulink:wikipage|page=Documentation|tooltip=Documentation}!Tabs^tab8.gif!{menulink}{bshow}
 {bshow:Support}{menulink:wikipage|page=Support|tooltip=Support}!Tabs^tab1.gif!{menulink}{bshow}
 {bshow:Development}{menulink:wikipage|page=Development|tooltip=Development}!Tabs^tab2.gif!{menulink}{bshow}
 {menulink:index|tooltip=Navigate}!Tabs^tab5.gif!{menulink}
 {style}.atb-leftslider {background-color:#e4ffcb;}{style}
{builder-show}{builder-show:title=Documentation|recurse=true}
 {menulink:home|tooltip=Home}!Tabs^tab0.gif!{menulink}
 {bshow:About}{menulink:wikipage|page=About|tooltip=About}!Tabs^tab4.gif!{menulink}{bshow}
 {bshow:Forum}{menulink:wikipage|page=Forum|tooltip=Forum}!Tabs^tab6.gif!{menulink}{bshow}
 {menulink:news|tooltip=News}!Tabs^tab3.gif!{menulink}
 {bshow:Tutorials}{menulink:wikipage|page=Tutorials|tooltip=Tutorials}!Tabs^tab7.gif!{menulink}{bshow}
 {menulink:wikipage|page=Documentation|tooltip=Documentation|class=stab}!Tabs^tab8.gif!{menulink}
 {bshow:Support}{menulink:wikipage|page=Support|tooltip=Support}!Tabs^tab1.gif!{menulink}{bshow}
 {bshow:Development}{menulink:wikipage|page=Development|tooltip=Development}!Tabs^tab2.gif!{menulink}{bshow}
 {menulink:index|tooltip=Navigate}!Tabs^tab5.gif!{menulink}
 {style}.atb-leftslider {background-color:#cbe6ff;}{style}
{builder-show}{builder-show:title=Support|recurse=true}
 {menulink:home|tooltip=Home}!Tabs^tab0.gif!{menulink}
 {bshow:About}{menulink:wikipage|page=About|tooltip=About}!Tabs^tab4.gif!{menulink}{bshow}
 {bshow:Forum}{menulink:wikipage|page=Forum|tooltip=Forum}!Tabs^tab6.gif!{menulink}{bshow}
 {menulink:news|tooltip=News}!Tabs^tab3.gif!{menulink}
 {bshow:Tutorials}{menulink:wikipage|page=Tutorials|tooltip=Tutorials}!Tabs^tab7.gif!{menulink}{bshow}
 {bshow:Documentation}{menulink:wikipage|page=Documentation|tooltip=Documentation}!Tabs^tab8.gif!{menulink}{bshow}
 {menulink:wikipage|page=Support|tooltip=Support|class=stab}!Tabs^tab1.gif!{menulink}
 {bshow:Development}{menulink:wikipage|page=Development|tooltip=Development}!Tabs^tab2.gif!{menulink}{bshow}
 {menulink:index|tooltip=Navigate}!Tabs^tab5.gif!{menulink}
 {style}.atb-leftslider {background-color:#fffed1;}{style}
{builder-show}{builder-show:title=Development|recurse=true}
 {menulink:home|tooltip=Home}!Tabs^tab0.gif!{menulink}
 {bshow:About}{menulink:wikipage|page=About|tooltip=About}!Tabs^tab4.gif!{menulink}{bshow}
 {bshow:Forum}{menulink:wikipage|page=Forum|tooltip=Forum}!Tabs^tab6.gif!{menulink}{bshow}
 {menulink:news|tooltip=News}!Tabs^tab3.gif!{menulink}
 {bshow:Tutorials}{menulink:wikipage|page=Tutorials|tooltip=Tutorials}!Tabs^tab7.gif!{menulink}{bshow}
 {bshow:Documentation}{menulink:wikipage|page=Documentation|tooltip=Documentation}!Tabs^tab8.gif!{menulink}{bshow}
 {bshow:Support}{menulink:wikipage|page=Support|tooltip=Support}!Tabs^tab1.gif!{menulink}{bshow}
 {menulink:wikipage|page=Development|tooltip=Development|class=stab}!Tabs^tab2.gif!{menulink}
 {menulink:index|tooltip=Navigate}!Tabs^tab5.gif!{menulink}
 {style}.atb-leftslider {background-color:#d3caff;}{style}
{builder-show}{builder-show:context=space-pages}
 {menulink:home|tooltip=Home}!Tabs^tab0.gif!{menulink}
 {bshow:About}{menulink:wikipage|page=About|tooltip=About}!Tabs^tab4.gif!{menulink}{bshow}
 {bshow:Forum}{menulink:wikipage|page=Forum|tooltip=Forum}!Tabs^tab6.gif!{menulink}{bshow}
 {menulink:news|tooltip=News}!Tabs^tab3.gif!{menulink}
 {bshow:Tutorials}{menulink:wikipage|page=Tutorials|tooltip=Tutorials}!Tabs^tab7.gif!{menulink}{bshow}
 {bshow:Documentation}{menulink:wikipage|page=Documentation|tooltip=Documentation}!Tabs^tab8.gif!{menulink}{bshow}
 {bshow:Support}{menulink:wikipage|page=Support|tooltip=Support}!Tabs^tab1.gif!{menulink}{bshow}
 {bshow:Development}{menulink:wikipage|page=Development|tooltip=Development}!Tabs^tab2.gif!{menulink}{bshow}
 {menulink:index|tooltip=Navigate|class=stab}!Tabs^tab5.gif!{menulink}
 {style}.atb-leftslider {background-color:#ffcdfe;}{style}
{builder-show}

It's a bit nasty - lots of duplication, but luckily fairly low processing overhead as only one chunk at most will be rendered by the server depending on your location within the space.

You'll also notice that if you are in an area not covered by the tabs, no tabs will appear - we could have added another block of notation which had no selected tab, however we decided not to because we were in a rush!


Next page: 4 - CSS