User Macros For Creating Tabs

Have you ever wanted to create tabs on your page? Well, of course you have! Tabs are a great way of organizing a page to keep it looking uncluttered. Below are two user macros you can create that will give you the ability to put tabs on your Confluence pages.

How it looks in the editor

image.png

How it looks when viewing the page

image.png

image.png

The User Macro Code

Macro Name:
tab_group

Macro Title:
Tab Group

Description:
This macro is used with the Tab macro. It controls the tab direction and responsiveness of the tab macros within it.

Macro Body Processing:
Rendered

Template:

## Developed by: Davin Studer
## Date created: 03/31/2022
## @param Vertical:title=Vertical Orientation|type=boolean|desc=Display the tabs vertically vs horizontally.|default=false
## @param Responsive:title=Responsive|type=boolean|desc=If checked tabs that overrun the width of the screen will be placed inside a menu.|default=false

##############################
## Create a unique id value ##
##############################
#set( $id=$action.dateFormatter.calendar.timeInMillis )

###########################################################################
## These are used for getting around velocity issues when writing jQuery ##
###########################################################################
#set( $d = '$' )
#set( $p = '#' )

#if ( $paramVertical == true )
    #set( $direction = "vertical-tabs" )
#else
    #set( $direction = "horizontal-tabs" )
#end

#if ( $paramResponsive == true )
    #set( $responsive = ' data-aui-responsive="true"' )
#else
    #set( $responsive = "" )
#end

<div id="tabGroup$id" class="aui-tabs $direction"$responsive>
<ul class="tabs-menu"> </ul>
$!body
</div>

<script type="text/javascript">
    AJS.toInit(function(){
        var html$id = '';
        //Only one active tab
        if(AJS.${d}('#tabGroup$id > .tabs-pane.active-pane').length > 1 || AJS.${d}('#tabGroup$id > .tabs-pane.active-pane').length == 0) {
            AJS.${d}('#tabGroup$id > .tabs-pane.active-pane').removeClass('active-pane');
            var firstTab$id = AJS.${d}('#tabGroup$id > .tabs-pane').get(0);
            AJS.${d}(firstTab$id).addClass('active-pane');
        }
        
        AJS.${d}('#tabGroup$id > .tabs-pane').each(function(index) {
            var active$id = '';
            
            if(AJS.${d}(this).hasClass('active-pane')) {
                active$id = ' active-tab';
            }
            html$id += '<li class="menu-item' + active$id + '"><a href="#' + AJS.${d}(this).attr('id') + '" id="aui-tab-uid-' + AJS.${d}(this).attr('id') + '" class="tabs-menu-anchor"><strong>' + AJS.${d}(this).attr('data-tab-name') + '</strong></a></li>';
        });
        
        AJS.${d}('#tabGroup$id > .tabs-menu').append(html$id);
        
        AJS.tabs.setup();
        
        // Prevent scrolling the page to the tab
        AJS.${d}(".tabs-menu-anchor").click(function(e){
            AJS.tabs.change(AJS.${d}(this), e)
            e.preventDefault()
            e.stopImmediatePropagation();
        });
    });
</script>

 

Macro Name:
tab

Macro Title:
Tab

Description:
This macro is used with the Tab Group macro. Place one or more of these inside a Tab Group macro to create tabs on your page.

Macro Body Processing:
Rendered

Template:

## Developed by: Davin Studer
## Date created: 03/31/2022
## @param TabName:title=Tab Name|type=string|required=true|desc=Specify a name for this tab.
## @param TabID:title=Tab ID|type=string|required=false|desc=Specify a id for this tab. (optional)
## @param Active:title=Active|type=boolean|desc=Only one tab may be the active one. (optional)|default=false
 
##############################
## Create a unique id value ##
##############################
#set( $id=$action.dateFormatter.calendar.timeInMillis )

#if ( $paramActive == true )
    #set( $active = " active-pane" )
#else
    #set( $active = "" )
#end

#if ( $paramTabID && $paramTabID != "" )
    #set( $tabID = "tab_$paramTabID" )
#else
    #set( $tabID = "tab_$id" )
#end

<div class="tabs-pane$!active" id="$tabID" data-tab-name="$!paramTabName">
$!body
</div>

 

19 comments

Rafael Corredor
Contributor
April 1, 2022

Hi,

 

Thank you for this one.  It is very useful.

I would be great to have a repository with this and other existing user macros.  One option could be to have something similar to this space for JIRA Admin: https://jaus.atlassian.net/wiki/spaces/JAUS/overview 

Like # people like this
Davin Studer
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
April 1, 2022

I've thought for a long time it would be nice to have a place where people could do this ... kinda like the Atlassian Marketplace but for user macros.

Like Nicolai Sibler likes this
Nicolai Sibler
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
April 12, 2022

Thanks @Davin Studer , wonderful job!

Could you please point out where to incease the width of the tab's titles when displayed vertically (or to word wrap the line)?

Sorry for bothering, but in German we just need some more space for our beloved word monstrosities ;-)

tabs.jpg

Like # people like this
Davin Studer
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
April 12, 2022

This is actually using built-in Atlassian UI functionality. So, it would behave the same way with anything that uses their UI framework. A quick look at the CSS and it looks like this is the rule that is constraining the width. So, you would need to override that CSS rule.

.aui-tabs.vertical-tabs>.tabs-menu {
width: 11em;
}
Like # people like this
Larry Peery December 30, 2022

Hi @Nicolai Sibler

Were you able to get the vertical tab names to wrap?

Thanks,
Larry

Larry Peery December 30, 2022

Adding style="white-space: normal;" to the <strong> attribute within the <li><a href...> in the tab group macro worked for me.

<strong style="white-space: normal;">' + AJS.${d}(this).attr('data-tab-name') + '</strong></a></li>';

Annotation 2022-12-30 142009.png

Andrew C.
I'm New Here
I'm New Here
Those new to the Atlassian Community have posted less than three times. Give them a warm welcome!
May 18, 2023

This may be a bad place for this, but I am at a loss.   I am trying to lock/freeze the tabs in place on the page as you scroll.  If you page your tab is linked to has a lot of content and you have to scroll the tabs get lost and then you have to scroll back.   Is there any way to lock/freeze the tab container/tab group in its place?

Rafał Żydek
Contributor
May 24, 2023

Are there problems with usage on Confluence 8? I'm not able to make it works on Confluence 8 DC. Sometime I cannot see anything, sometime the list of tabs is duplicated

Definition:

2.png

Result

1.png

Update: problem exist only if you have columns / divided layout of the page.

 

Update#2

I made a fix for confluence 8.

Replace

AJS.${d}('#tabGroup$id > .tabs-menu').append(html$id);
AJS.tabs.setup();

with

if (AJS.${d}('#tabGroup$id > .tabs-menu').html().length<2){
  AJS.${d}('#tabGroup$id > .tabs-menu').append(html$id);
  AJS.tabs.setup();
}
Larry Peery June 6, 2023

We are having similar issues with Confluence 8. We did try the replacement listed above but were not able to resolve the issue.

Confluence Server 8.2.0

Is anyone else facing this?

The Edit Screen...

Confluence 8 Edit Tab.png

The Published page...

Confluence 8 Display Tab.png

Rafał Żydek
Contributor
June 28, 2023

I fixed issue by workaround, below tab_group code:

if ( AJS.${d}('#tabGroup$id > .tabs-menu').html().length < 2 ){
AJS.${d}('#tabGroup$id > .tabs-menu').append(html$id);
AJS.tabs.setup();

}

 Full code:

## @param Vertical:title=Vertical Orientation|type=boolean|desc=Display the tabs vertically vs horizontally.|default=false
## @param Responsive:title=Responsive|type=boolean|desc=If checked tabs that overrun the width of the screen will be placed inside a menu.|default=false

##############################
## Create a unique id value ##
##############################
#set( $id=$action.dateFormatter.calendar.timeInMillis )

###########################################################################
## These are used for getting around velocity issues when writing jQuery ##
###########################################################################
#set( $d = '$' )
#set( $p = '#' )

#if ( $paramVertical == true )
#set( $direction = "vertical-tabs" )
#else
#set( $direction = "horizontal-tabs" )
#end

#if ( $paramResponsive == true )
#set( $responsive = ' data-aui-responsive="true"' )
#else
#set( $responsive = "" )
#end

<div id="tabGroup$id" class="aui-tabs $direction"$responsive>
<ul class="tabs-menu"> </ul>
$!body
</div>

<script type="text/javascript">
AJS.toInit(function(){
var html$id = '';
//Only one active tab
if(AJS.${d}('#tabGroup$id > .tabs-pane.active-pane').length > 1 || AJS.${d}('#tabGroup$id > .tabs-pane.active-pane').length == 0) {
AJS.${d}('#tabGroup$id > .tabs-pane.active-pane').removeClass('active-pane');
var firstTab$id = AJS.${d}('#tabGroup$id > .tabs-pane').get(0);
AJS.${d}(firstTab$id).addClass('active-pane');
}

AJS.${d}('#tabGroup$id > .tabs-pane').each(function(index) {

var active$id = '';

if(AJS.${d}(this).hasClass('active-pane')) {
active$id = ' active-tab';
}


html$id += '<li class="menu-item' + active$id + '"><a href="#' + AJS.${d}(this).attr('id') + '" id="aui-tab-uid-' + AJS.${d}(this).attr('id') + '" class="tabs-menu-anchor"><strong>' + AJS.${d}(this).attr('data-tab-name') + '</strong></a></li>';

});

//Adding tabs
if ( AJS.${d}('#tabGroup$id > .tabs-menu').html().length < 2 ){
AJS.${d}('#tabGroup$id > .tabs-menu').append(html$id);
AJS.tabs.setup();

}

// Prevent scrolling the page to the tab
AJS.${d}(".tabs-menu-anchor").click(function(e){
AJS.tabs.change(AJS.${d}(this), e)
e.preventDefault()
e.stopImmediatePropagation();
});
});
</script>

Be aware that macro TAB have vulnerability and allow users iject <scripts>. My code for tab macro to avoid that:

 

## @param TabName:title=Tab Name|type=string|required=true|desc=Specify a name for this tab.
## @param TabID:title=Tab ID|type=string|required=false|desc=Specify a id for this tab. (optional)
## @param Active:title=Active|type=boolean|desc=Only one tab may be the active one. (optional)|default=false

##############################
## Create a unique id value ##
##############################
#set( $id=$action.dateFormatter.calendar.timeInMillis )

#if ( $paramActive == true )
#set( $active = " active-pane" )
#else
#set( $active = "" )
#end

#####################
## Replace < char ##
#####################
#set( $tabName = $paramTabName.replace('&lt;','') )
#set( $tabID = $paramTabID.replace('&lt;','') )

 
#if ( $paramTabID && $paramTabID != "" )
#set( $tabID = "tab_$paramTabID" )
#else
#set( $tabID = "tab_$id" )
#end

<div class="tabs-pane$!active" id="$tabID" data-tab-name="$tabName">
$!body
</div>
E Noonan
I'm New Here
I'm New Here
Those new to the Atlassian Community have posted less than three times. Give them a warm welcome!
August 29, 2023

I know this is an old thread, but maybe someone will see it.  

Do you have to buy the tab macro from Atlassian to use this user macro?  I ask because the cost on the marketplace for the tab macro is exorbitant for a company with more than 10 users using Confluence.

Jill Skjøndal Grefsrud October 3, 2023

Two questions: 

Do the tabs "load" individually, so that heavy pages with large amounts of content will appear lighter and load faster if tabs are added? 

Will a Ctrl+F / F3 search work for the whole page or only for the activated tab? 

Thanks in advance! :) 

Phil Bustin
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
October 31, 2023

I don't see detailed instructions this post for where and how to create a template that contains tabs.

Nicolai Sibler
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 8, 2023

@Phil Bustin

Instructions to set up this user macro in your Server/DC instance (excerpt from Writing User Macros):

  1. Go to Administration  > General Configuration > User Macros
  2. Choose Create a User Macro
  3. Enter the macro details (see article above)
  4. Click Add
Phil Bustin
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 8, 2023

Thanks, Nicolai.  In our Sandbox, in Confluence > Administration > General Configuration, there is no Macro item.  

In Confluence > Configuration > navigation pane > Administration, there is only Macro Usgage.

Maybe I need to be assigned a different type of Administrator privilege.

 

Parker.Odom
I'm New Here
I'm New Here
Those new to the Atlassian Community have posted less than three times. Give them a warm welcome!
December 22, 2023

I see this is an old thread, but maybe someone might have the same issue. We upgraded to Confluence Datacenter 7.19.17 to patch the security vulnerabilities that Atlassian published. Since then, our tab functionality using the above code snippets no longer works. Did Atlassian change something that breaks this function?

Larry Peery December 26, 2023

We just upgraded to Confluence Data Center 8.5.4. The tab macro now does not display on a published page. The content does show when in edit mode.

In the "User Macro" section we see this...

User Macro tab_group may use context keys [ action ] which are not set in system property macro.required.velocity.context.keys. If the macro is not rendered as expected, try to manually add those keys into the system property.

and...

User Macro tab may use context keys [ action ] which are not set in system property macro.required.velocity.context.keys. If the macro is not rendered as expected, try to manually add those keys into the system property.

Has anyone found a resolution to this?

Thanks in advance! :) 

Nicolai Sibler
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
January 3, 2024

@Larry Peery The solution is to do what you are asked to do ;-) Your SysAdmin has to configure the system properties.

Background: CONFSERVER-82741

See also here and here 

Daphnis Hessling March 13, 2024

We tried the fix provided by @Rafał Żydek unfortunately our Tabs are still not being rendered in view page mode. We only get the horizontal grey line described before..
We are on Confluence DC 8.8.0. and added the aforementioned property in our system properties.. Does anyone have a fix maybe?

Many thanks in advance!

Like Matthias likes this

Comment

Log in or Sign up to comment
TAGS
AUG Leaders

Atlassian Community Events