ThemeBuilder for Confluence Server and DC

Working with Flags

Flags allow you to simplify switching logic and improve performance within your themes. A flag is a simple named register that stores one of the following states:

  • true - The flag is set

  • false - The flag is not set

If you use a flag that hasn’t been defined, it’s treated as having a state that’s 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 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 persistence.

See the FlagLogic in Skins page for more information.

How to Set a Flag

To set, and subsequently unset, 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 unset flags in this manner are as follows: * Panel Show Macro * Panel Hide macro * Bubbles Show Macro * Bubbles Hide Macro

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 unset a flag.

How to Unset a Flag

To unset or clear a flag, set its 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 the state to 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 to 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 to the following:

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, like the markup as follows:

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}

Macros that Support Flags

All ThemeBuilder macros support flags from Confluence 5 onwards.

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 to 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 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 is explained below:

  • 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

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 an example, look at the markup included here:

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 many times when a state is 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 configuration 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. This is an ideal use case for flags.

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

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 you are—​registered or staff.

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

Where to Define Flags

We recommend using the flagLogic panel in the 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.

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/Type

Level of Persistance

Permission Check

Request

Not persisted, flag will be reset each time the page is loaded

No permission check required since this flag can only affect the current user

Session

Persisted against the user’s session, flag will be reset once the user closes and re-opens their browser

No permission check required since this flag can only affect the current user

User

Persisted against the user’s preferences, flag will remain but will only be available once the user logs in

User must be logged in

Page

Persisted against the current page, flag will be present when the current page is viewed by any user permitted to view the page

User must have write permission on the page/blog to set flag

Space

Persisted against the current space, flag will be present when any page in the space is viewed

User must be a space or site admin to set the flag

Global

Persisted for all spaces and global pages, flag will always be present

User must be a site admin to set the flag

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

Flag Target Priority

When a flag is read, no target type is supplied, which 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, the next step will be checked, and if a flag is found either in the true or false state, 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’s useful to provide links which allow users to set flags by clicking on something. This facility is provided through the Set Flag Link Macro.