Skip to end of metadata
Go to start of metadata

What are Flags?

Flags allow you simplify switching logic and improve performance within your themes.

A flag is a simple named register that stores a state:

  • true - The flag is set
  • false - The flag is not set

If you use a flag that's not been defined, it's treated as having state false.

Several macros are flag-aware, allowing you to toggle them on or off based on the state of one or more flags. You can also use flags to toggle the effect of parts of your CSS style sheets.

Flags also apply flag-FLAGNAME classes to the body element of the theme so that they can be used for triggering css customisations.

Flags can be set against a variety of targets each of which has a different level of persistance.

Flags in Skins

How do I set a flag?

To set, and subsequently un-set a flag, you use the set-flag macro, for example the following markup will set a flag called foo, and then un-set it:

Storage Format

<ac:macro ac:name="set-flag">
   <ac:parameter ac:name="name">foo</ac:parameter>
</ac:macro>

<ac:macro ac:name="set-flag">
   <ac:parameter ac:name="name">foo</ac:parameter>
   <ac:parameter ac:name="state">false</ac:parameter>
</ac:macro> 

Wiki Markup

{set-flag:foo}
{set-flag:foo|state=false}

 

You can set flags in a wiki page or in a theme panel.

In most cases, you'll want to conditionally set a flag based on some other criteria, for example:

Storage Format

<ac:macro ac:name="panel-show">
    <ac:parameter ac:name="title">Forum</ac:parameter>
	<ac:parameter ac:name="recurse">true</ac:parameter>
	<ac:rich-text-body>  
		<ac:macro ac:name="set-flag">
		   <ac:parameter ac:name="name">in-the-forum</ac:parameter>
		</ac:macro>
	</ac:rich-text-body>
</ac:macro>	

Wiki Markup

{panel-show:title=Forum|recurse=true}
 {set-flag:in-the-forum}
{panel-show}

 

The markup above would set the 'in-the-forum' flag only when the user is looking a page called 'Forum' or any of it's child pages (due to the 'recurse=true').

The macros most commonly used to set and un-set flags in this manner are:

These show/hide macros will show or hide their contents based on the parameters you set, allowing you to determine when the set-flag macro is triggered to set or un-set a flag.

How do I unset a flag?

To un-set (clear) a flag, set it's state to false:

Storage Format

<ac:macro ac:name="set-flag">
   <ac:parameter ac:name="name">in-the-forum</ac:parameter>
   <ac:parameter ac:name="state">false</ac:parameter>
</ac:macro> 

Wiki Markup

{set-flag:in-the-forum|state=false}

 

You can also completely remove a flag by setting remove:

Storage Format

<ac:macro ac:name="set-flag">
   <ac:parameter ac:name="name">in-the-forum</ac:parameter>
   <ac:parameter ac:name="state">remove</ac:parameter>
</ac:macro> 

Wiki Markup

{set-flag:in-the-forum|state=remove}

What can I do with flags?

You can use flags to toggle the rendering of other macros and wiki markup. For example, using our 'in-the-forum' flag above we could show some extra content in a theme sidebar when that flag is set:

Storage Format

<ac:macro ac:name="panel-show">
    <ac:parameter ac:name="flag">in-the-forum,foo</ac:parameter>
	<ac:rich-text-body>  
	this stuff will only be shown when either the 'in-the-forum' and/or 'foo' flag has been set
	</ac:rich-text-body>
</ac:macro>	

Wiki Markup

{panel-show:flag=in-the-forum,foo}
 this stuff will only be shown when either the 'in-the-forum' and/or 'foo' flag has been set
{panel-show}

 

Or we could show some content when the flag is not set:

Storage Format

<ac:macro ac:name="panel-show">
    <ac:parameter ac:name="notflag">in-the-forum,foo</ac:parameter>
	<ac:rich-text-body>  
		this stuff will only be shown if neither the 'in-the-forum' and 'foo' flags have been set
		(in other words, if the 'in-the-forum' or 'foo' flags are set, ths won't be shown)
	</ac:rich-text-body>
</ac:macro>	

<ac:macro ac:name="panel-hide">
    <ac:parameter ac:name="flag">in-the-forum,foo</ac:parameter>
	<ac:rich-text-body>  
		this is does the same as the panel-show markup shown above, we've changed 'notflag' to 'flag'
		so it gets hidden when either of the flags are set
	</ac:rich-text-body>
</ac:macro>	

Wiki Markup

{panel-show:notflag=in-the-forum,foo}
 this stuff will only be shown if neither the 'in-the-forum' and 'foo' flags have been set
 (in other words, if the 'in-the-forum' or 'foo' flags are set, ths won't be shown)
{panel-show}

{panel-hide:flag=in-the-forum,foo}
 this is does the same as the panel-show markup shown above, we've changed 'notflag' to 'flag'
 so it gets hidden when either of the flags are set
{panel-hide}

 

Which macros support flags?

The flag parameters are as follows:

  • flag – defines which flags must be set in order for the macro to be processed
  • notflag – defines which flags must not be set in order for the macro to be processed.

When should I use flags?

Flags become useful in more complex theme customisations because they allow you to separate out a lot of the logic that determines what should be displayed to the end-user. We'll cover some of the key use cases below...

Setting defaults

There are many cases where you'll want to set a default state and then override it with a known state based on various criteria. If none of the known-states are found, you'll be left with the default state.

A simple example is determining whether a user is logged in or not, and whether they are a member of staff:

Storage Format

<ac:macro ac:name="set-flag">
   <ac:parameter ac:name="name">anonymous-user</ac:parameter>
</ac:macro>

<ac:macro ac:name="panel-show">
    <ac:parameter ac:name="group">confluence-users</ac:parameter>
	<ac:rich-text-body>  
		<ac:macro ac:name="set-flag">
		   <ac:parameter ac:name="name">anonymous-user</ac:parameter>
		   <ac:parameter ac:name="clear">true</ac:parameter>
		</ac:macro>
		<ac:macro ac:name="set-flag">
		   <ac:parameter ac:name="name">registered-user</ac:parameter>
		</ac:macro>	

		<ac:macro ac:name="panel-show">
			<ac:parameter ac:name="group">staff-group</ac:parameter>
			<ac:rich-text-body>  
				<ac:macro ac:name="set-flag">
				   <ac:parameter ac:name="name">staff-user</ac:parameter>
				</ac:macro>	
			</ac:rich-text-body>
		</ac:macro>			
	</ac:rich-text-body>
</ac:macro>	

Wiki Markup

{set-flag:anonymous-user}

{panel-show:group=confluence-users}

  {set-flag:anonymous-user|clear=true}
  {set-flag:registered-user}

  {panel-show:group=staff-group}
    {set-flag:staff-user}
  {panel-show}

{panel-show}

 

The result will be:

  • If the user is not logged in, only the anonymous-user flag will be set. (Default state)
  • If the user is logged in, the 'anonymous-user' flag will be un-set (cleared) and the 'registered-user' flag will be set
  • If the user is logged in and is also a member of your 'staff-group', the 'staff-user' flag will be set in addition to the 'registered-user' flag

Important: Flags should never be treated as a security mechanism. In the example above, a user could set the staff-user flag from a wiki page. You could override any flags set by users by defining some more defaults at the start of your flag logic, for example:

Storage Format

<ac:macro ac:name="set-flag">
	<ac:parameter ac:name="name">registered-user</ac:parameter>
	<ac:parameter ac:name="state">false</ac:parameter>		   
</ac:macro>	
<ac:macro ac:name="set-flag">
	<ac:parameter ac:name="name">staff-user</ac:parameter>
	<ac:parameter ac:name="state">false</ac:parameter>
</ac:macro>			

Wiki Markup

{set-flag:registered-user|state=false}
{set-flag:staff-user|state=false}

 

Improved performance

There are lots of times when a state will be used several times in a theme layout. Although lots of caching is used in Builder and Confluence, if you're repeatedly checking for a specific state (particularly complex states based on several criteria) it can degrade performance and make your theme config really messy.

One of the most common scenarios we've found so far in themes we've developed for customers is whether or not to show an edit button and other links related to page editing. The general logic runs along these lines:

  • Don't show the edit features on top-level pages or the home page
  • Only show edit features if the user is logged in (regardless of permissions for anonymous users)
  • Only show edit features in the 'Documentation' area of a space if the user is a member of staff

There's obviously quite a few things that need to be checked to confirm whether the edit features should be shown, and in many cases the outcome will be performed in several locations and across multiple theme panels. An ideal use case for flags!

Based on the flags set by earlier examples, the logic to do this would be:

Storage Format

<ac:macro ac:name="panel-hide">
    <ac:parameter ac:name="page"><at:var at:name="parent," />home</ac:parameter>
	<ac:rich-text-body>  
		<ac:macro ac:name="set-flag">
			<ac:parameter ac:name="name">top-level-page</ac:parameter>
		</ac:macro>	
	</ac:rich-text-body>
</ac:macro>	

<ac:macro ac:name="panel-show">
    <ac:parameter ac:name="flag">registered-user</ac:parameter>
    <ac:parameter ac:name="notflag">top-level-page</ac:parameter>	
	<ac:rich-text-body>  
		<ac:macro ac:name="set-flag">
			<ac:parameter ac:name="name">show-edit</ac:parameter>
		</ac:macro>	
	</ac:rich-text-body>
</ac:macro>	

<ac:macro ac:name="panel-show">
    <ac:parameter ac:name="page">Documentation</ac:parameter>
	<ac:parameter ac:name="recurse">true</ac:parameter>	
    <ac:parameter ac:name="notflag">staff-user</ac:parameter>		
	<ac:rich-text-body>  
		<ac:macro ac:name="set-flag">
			<ac:parameter ac:name="name">show-edit</ac:parameter>
			<ac:parameter ac:name="state">false</ac:parameter>			
		</ac:macro>	
	</ac:rich-text-body>
</ac:macro>			

Wiki Markup

{panel-hide:page=<at:var at:name="parent," />home}
  {set-flag:top-level-page}
{panel-hide}

{panel-show:flag=registered-user|notflag=top-level-page}
  {set-flag:show-edit}
{panel-show}

{panel-show:page=Documentation|recurse=true|notflag=staff-user}
  {set-flag:show-edit|state=false}
{panel-show}

 

You can now toggle the edit links anywhere in your theme based on the 'show-edit' flag. This way you don't need to keep checking where you are in a space (top level pages, home page, documentation section) and the type of user (registered or staff).

Any developer looking at the flag logic above will see several optimisations that can be made - this is key reason for separating out the flag logic in to a wiki page so it's easier to modify...

Where should flags be defined?

We recommend using the flaglogic panel in ThemeBuilder Skin Editor to store the flag logic for the following reasons:

  • De-cluttering - reduce amount of markup in your theme panels
  • Maintainability - separate the flag logic from the theme customisation

CSS customisation with flags

When a flag is set, a class will be added to the HTML <body> tag. Let's take the 'in-the-forum' flag we described earlier as an example:

<body class="flag-in-the-forum" ...

As you can see, the class is prefixed with 'flag-' so remember that when you're using it in your style sheet.

So, let's say you want to change the colour of the heading 1 style when you're in a forum, you could use this CSS in the CSS Tab:

.flag-in-the-forum h1 {
 color: #0f0;
}

Flag Targets

Flags may be targeted against different types of scenarios, for instance a user can set a flag against themselves - this is useful when implementing user-preferences, such as whether to show a sidebar or not.

Target/TypeLevel of PersistancePermission Check
RequestNot persisted, flag will be reset each time the page is loadedNo permission check required since this flag can only affect the current user
SessionPersisted against the user's session, flag will be reset once the user closes and re-opens their browserNo permission check required since this flag can only affect the current user
UserPersisted against the user's preferences, flag will remain but will only be available once the user logs inUser must be logged in
PagePersisted against the current page, flag will be present when the current page is viewed by any user permitted to view the pageUser must have write permission on the page/blog to set flag
SpacePersisted against the current space, flag will be present when any page in the space is viewedUser must be a space or site admin to set the flag
GlobalPersisted for all spaces and global pages, flag will always be presentUser must be a site admin to set the flag

If a user does not have permission to set a flag, then their request will be ignored.

Flag Target Priority

When a flag is 'read' no target type is supplied, this allows you to create default states for flags and enable customisation by end users.

The following order is used when checking for a flag, if a flag is not defined then the next step will be checked, if a flag is found either in the true or false state then it's value will be used:

  1. Request
  2. Session
  3. User
  4. Page
  5. Space
  6. Global

Setting flags based on user interaction

At times it useful to provide links that allow users to set flags by clicking on something, this facility is provided through the set-flag-link macro