Token Swaps

Token swaps enable you to place what I call “front-end variables” in your AsciiDoc or other page elements that can be altered either by an act of the user or a URL query string. Use this method to reduce the number of builds you perform just to alter small bits of text.

Once a user makes a selection (or has been directed to a specific URL), the swaps remain in play for the duration of their session.

Swap Configuration

Like other handlers, swaps are defined in the versioning data object. Name a swap object whatever you wish, and then give it the property verb: swap.

A swap can be triggered by a select dropdown or radio buttons.

Swaps can have a dict: property that establishes default tokens. They must have an swap.opts: property that defines the “slates” of tokens. These slates are what is being chosen during a swap.

Even though tokens are broken down to separate dicts and slates, tokens must be unique across all dictionaries. At expression time, swaps alter the value of every token bearing that slug.

Token Expression

To express a token inside AsciiDoc text, use one of the following methods.

inline role

This option uses AsciiDoc’s inline semantics to wrap text in a .tok class with a secondary class matching the slug of the token. For example, [.tok.token_name]#Default Text# declares that we want to offer a token for swapping, and it is named token_name and has an inline default set as Default Text.

hard token

As an alternative that is easy to store in an AsciiDoc attribute (see Storing Tokens as AsciiDoc Attributes below), use a token formatted like so: <$tok.token_name>. Replace token_name with the slug value for your token. There is no option for default text at this time.

Examples

It’s probably best to start showing you some swaps.

Patch Version Switcher

We will start with a simple example, and likely the most common implementation: a patch-version switcher. If the only thing that changes in your docs between patch versions is the patch version itself, use this trick to let users choose the precise product version they are using or installing without changing pages (and without duplicate builds).

On the right-hand sidebar, there is a selectbox labeled Select your patch version:.

Watch what happens to this text (<$tok.vrsn>) when you change the patch version, sourced as <$tok.vrsn>.

And here is another version (0.2.0) sourced differently ([.tok.vrsn]*0.2.0*).

This set of swaps is registered as a version handler.

features:
  actions:
    versioning:
      ...
      patch-swap-0_2:
    verb: swap
    form: select
    spot: "#sidebar-right .sidebar-end"
    show:
      text: "Choose your patch version:"
      icon: fa fa-wrench
    swap:
      pick: 0.2.0
      slug: vrsn (1)
      opts: ['0.2.0','0.2.1','0.2.2'] (2)

In this example, the swap pivots on a single token and a single set of values.

1 The slug: property names the token.
2 The opts: property in this case is a simple array of scalars.

Token Slates

A swap handler will alter every instance of a token on a page at once, but if you want a handler to swap (every instance of) multiple different tokens, you’ll need some dictionaries.

Let’s say I wanted to distribute two more editions of AsciiDocsy: “freemium” platform and a commercial version, in addition to the free and open-source version. Obviously these docs would be largely identical to the free version, but they might have some different contents.

First we need to define tokens for swapping. Let’s go with theme, company, and company_url, which will have different values given different slates (listed under the opts: property).

Defining a swap dictionary
features:
  actions:
    versioning:
      ...
      theme-name-tokens:
    verb: swap
    form: select
    spot: "#sidebar-right .sidebar-end"
    show:
      text: "AsciiDocsy Edition:"
      icon: fa fa-font
    swap:
      pick: foss
      dict: (1)
        company: DocOps.org
        company_url: https://www.docopslab.org
        theme: AsciiDocsy
      opts: (2)
        - text: FOSS
          slug: foss
          dict:
            slogan: Free docs for everyone!
        - text: Freemium
          slug: freemium
          dict: (3)
            theme: AsciiDocsy Premium
            company_url: https://www.docopslab.com
            slogan: Free docs until you're a big deal (then chip in).
        - text: SellOut
          slug: sellout
          dict: (3)
            theme: ACMEDocsy
            company: AsciiDocs4Sale.com
            company_url: https://asciidocs4sale.com
            slogan: No free docs.

The top-level dict: 2 object defines the default dictionary. Thereafter, slates (items in opts: 2) can override the defaults as needed using a nested dict: 3 (x2) property of their own.

Here we see the first slate (foss) simply uses the default dictionary while each of the next two define overrides.

Now that our tokens are defined, we can start placing them inside our AsciiDoc content.

The <$tok.theme> theme, brought to you by <$tok.company> (link:<$tok.company_url>[website]), is really awesome.

The company slogan is <$tok.slogan>.
Limitation: As you can see in the above example, token swaps inside HTML element attributes (such as href here) are not yet working.
Example 1. Renders

The <$tok.theme> theme, brought to you by <$tok.company> (website), is really awesome.

The company slogan is <$tok.slogan>.

Storing Tokens as AsciiDoc Attributes

Placing AsciiDocsy swap tokens directly in AsciiDoc syntax does not carry over to non-AsciiDocsy output. For this and other reasons, the preferred way to handle swap tokens is by defining them with AsciiDoc attributes.

Provide different values to all your way you can override the token syntax with an explicit value anytime you wish at build-time.

This method easier to manage and looks nicer on the page, as well.

Example: hard tokens stored as attributes
The [.tok.theme]#{theme}# theme, brought to you by [.tok.company]#{company}# (link:{company_url}[[website]), is really awesome.
Example 2. Renders

The AsciiDocsy theme, brought to you by DocOps.Lab (website), is really awesome.

Without storing your tokens as attributes, you are stuck with those tokens in alternative formats that lack frontend manipulation via JavaScript, such as PDF.

Toggle Piggy-backing

If a swap and a toggle have the same set of options, the swap can piggy-back on the toggle. This means the toggle will now perform two actions:

  1. It will show any content bearing the “role” class defined for the toggle (while hiding content bearing toggled-off classes).

  2. It will also swap any tokens for values assigned to the slate that goes with that role/slug.

Let’s look at an example.

features:
  actions:
    versioning:
      ...
  user-os-swap:
    verb: swap
    form: "#user-os-toggle"
    spot: "#sidebar-right .sidebar-end"
    swap:
      opts:
        - slug: os-mac
          dict:
            your_os: Your operaing system is very classy.
            you: You appreciate good design and are willing to pay for it.
        - slug: os-nix
          dict:
            your_os: Your operating system is very... rugged.
            you: You like the illusion that you take charge of your devices.
        - slug: os-win
          dict:
            your_os: Your operating system is practical.
            you: You don't overthink things.
Example 3. See the swap in action

Use the OS selector in the right-hand sidebar to swap slates.

your OS

MacOS Linux/Unix Windows

something about your technology

<$tok.your_os>

something about you

<$tok.you>

Swap source
your OS::
[.os-mac]#MacOS# [.os-nix]#Linux/Unix# [.os-win]#Windows#

something about your technology::
<$tok.your_os>

something about you::
<$tok.you>