switch, on, case, default, break - Apache FreeMarker Manual

Unsupported web browser - Use a modern browser to view this website!

- Home
- Manual
- Java API

- Contribute
- Report a Bug
- Download

Manual
Previous Next

# switch, on, case, default, break

## Synopsis

Recommended form (`on`-based), but this is only supported since FreeMarker 2.3.34:

    <#switch value>
      <#on refValue1>
        ... (Handles refValue1)
      <#on refValue2, refValue3>
        ... (Handles both refValue2 and refValue3))
      ...
      <#on refValueN>
        ...
      <#default>
        ...
    </#switch>

Deprecated legacy form (`case`-based):

    <#switch value>
      <#case refValue1>
        ... (Handles refValue1)
        <#break>
      <#case refValue2>
      <#case refValue3>
        ... (Handles both refValue2 and refValue3)
        <#break>
      ...
      <#case refValueN>
        ...
        <#break>
      <#default>
        ...
    </#switch>

Where:

- `value`, `refValue1`, etc.: Expressions evaluates to scalars of the same type.

Additional rules:

- A `switch` block either have `on`-s, or `case`-s, but not both.

- `default`: Optional, can occur at most once. Must be after the `on`-s. There's no ordering restriction when used with `case`-s.

- `break`:

  - If the `switch` uses `case` then `break` immediately exits from the closes enclosing `switch`. This is used to prevent fall-through into the next `case`, or into the following (adjacent) `default`. (To be precise, `break` behaves as described if the `switch` doesn't contain `on`, and thus also if all it contains is a `default`.)

  - If the `switch` uses `on` then `break` is not supported by `switch` directly, but naturally can be used when the `switch` is inside something else that supports `break` (like inside a list).

  - With `case`, `continue` does the same as `break`. This is an old bug that works for backward compatibility, but don't utilize it. With `on`, this is fixed.

## Description

Note:

Using this directive with `case` is not recommended, as it's error-prone because of the fall-through behavior. Starting from FreeMarker 2.3.34, use `on` instead of `case`. In earlier versions use `elseif`-s instead.

Switch is used to choose a fragment of template depending on the value of an expression, and is a shorthand instead using `if`-`elseif`-`else`:

Template

    <#switch animal.size>
      <#on "small">
         Processed if animal.size was "small"
      <#on "medium">
         Processed if animal.size was "medium"
      <#on "large", "extra large">
         Processed if animal.size was "large" or "extra large"
      <#default>
         Processed if animal.size is neither of the above
    </#switch>

Before FreeMarker 2.3.24, `on` wasn't supported, only `case` (note the usage of `break`, and the intentional omission of it after `<#case "large">`):

Template

    <#switch animal.size>
      <#case "small">
         Processed if animal.size was "small"
         <#break>
      <#case "medium">
         Processed if animal.size was "medium"
         <#break>
      <#case "large">
      <#case "extra large">
         Processed if animal.size was "large" or "extra large"
         <#break>
      <#default>
         Processed if animal.size is neither of the above
    </#switch>

Above examples are basically equivalent with this:

Template

    <#assign value = animal.size>
    <#if value == "small">
       Processed if animal.size was "small"
    <#elseif value == "medium">
       Processed if animal.size was "medium"
    <#elseif value == "large" || value == "extra large">
       Processed if animal.size was "large" or "extra large"
    <#else>
       Processed if animal.size is neither of the above
    </#if>

That is, when the `switch` directive is processed, it chooses an `on` or `case` directive where a `refValue` equals with `value`, and continues the processing of the template there. If there is no `on` or `case` directive with appropriate `refValue`, then it continues processing at the `default` directive, if that exists, otherwise it continues the processing after the end-tag of `switch`.

Be careful with `case`'s fall-through behavior! It means that after processing have jumped on the matching `case`, it will not leave the `switch` directive when it reaches another `case` or `default`, only when it reaches a `break`. Example:

Template

    <#switch x>
      <#case 1>
        1
      <#case 2>
        2
      <#default>
        d
    </#switch>

If `x` is `1`, then it will print `1 2 d` (actually with more white-space between); if `x` is `2` then it will print `2 d`; if `x` is `3` then it will print `d`. This is usually unintended, or if it is intended then probably not obvious for the reader, and that's why `on` is recommended over `case`.

Previous Next