# Client-Side Formatting with APEX Template Directives

[Oracle APEX Template Directives](https://docs.oracle.com/en/database/oracle/application-express/22.1/htmdb/using-template-directives.html) allow you to apply client-side directives to control the display and formatting of data that is returned from SQL.

Template Directives can be used on any APEX components that support client-side rendering. These include the Cards Region and Interactive Grid. Look out for the text `Supports Template Directives` in the APEX Builder help as additional components begin to support them.

The list of directives that can be applied is `if, elseif, else, endif, case, when, otherwise, endcase, loop, endloop`.

## Benefits of APEX Template Directives
1. Simplify business logic in SQL, keeping it free of UI logic
2. Reduce the risk of Cross-Site Scripting attacks by removing the need to use 'RAW' item substitution syntax, e.g., `&P1_TAGS!RAW.`
3. Improve performance by reducing the size of the SQL results

## Template Directives Example
The goal of this example is to display cards showing people and their address information embedded in a table within each card. Many columns are not required, and we do not want to show data for columns that do not have a value. The screenshot below shows the finished product.

![Screenshot showing Oracle APEX Cards with Template Directives](https://cdn.hashnode.com/res/hashnode/image/upload/v1656450951056/z42AGEeTT.png)

### Card Region SQL
The Cards Region is based on the following SQL:
```SQL
SELECT first_name
,      last_name
,      address1
,      city 
,      state
,      zip
,      enabled_flag
,      tags
FROM   blog_people
```

### Card Region Title
We want to show a comma between the last and first name if the last name is present; otherwise, display the first name. To do this, we need to set the Title `Advanced Formatting` toggle on and enter the below Template Directive logic.

```HTML
<h3 class="a-CardView-title">
  {if ?LAST_NAME/}&LAST_NAME., &FIRST_NAME.
  {else/}&FIRST_NAME.
  {endif/}
</h3>
```
Explanation:
- `{if ?LAST_NAME/}` - if the `last_name` column from the SQL is NOT NULL, then show the last name a comma, and then the first name
- `{else/}` - show just the first name

In APEX Builder, it looks like this:
![Screenshot showing Template Directive for Cards Region Title](https://cdn.hashnode.com/res/hashnode/image/upload/v1656373365073/mtfBCoR_N.png)

### Card Region Sub-Title
We need to display text indicating if the person's status is Enabled, Disabled, or Unknown. For this, we will use a CASE Template Directive.

```HTML
{case ENABLED_FLAG/}
{when Y/}
<span class="u-success-text">Enabled</span>
{when N/}
<span class="u-color-15-text">Disabled</span>
{otherwise/}
<span class="u-danger-text">Unknown</span>
{endcase/}
```
Explanation:
- The `{case/}` directive is comparing the `enabled_flag` from the SQL statement and returning Enabled for Y, Disabled for N; if it is anything else, then it returns Unknown

The code looks like this in APEX Builder:
![Screenshot showing Template Directive for Cards Sub-Title](https://cdn.hashnode.com/res/hashnode/image/upload/v1656451008389/wDVLUcv14.png)

### Card Region Body
We need to display an HTML table with the address in the card body. We only want to show columns for parts of the address with a value.

```HTML
<div class="t-Report t-Report--stretch">
<table class="t-Report-report u-color-21 u-textCenter">
<thead class="t-Report-report u-textCenter">
  <tr>
    {if ?ADDRESS1/}<th class="t-Report-colHead u-bold">Address</th>{endif/}
    {if ?CITY/}<th class="t-Report-colHead u-bold">City</th>{endif/}
    {if ?STATE/}<th class="t-Report-colHead u-bold">State</th>{endif/}
    {if ?ZIP/}<th class="t-Report-colHead u-bold">ZIP</th>{endif/}
  </tr>
</thead>
<tbody>
  <tr>
    {if ?ADDRESS1/}<td class="t-Report-cell">&ADDRESS1.</td>{endif/}
    {if ?CITY/}<td class="t-Report-cell">&CITY.</td>{endif/}
    {if ?STATE/}<td class="t-Report-cell">&STATE.</td>{endif/}
    {if ?ZIP/}<td class="t-Report-cell">&ZIP.</td>{endif/}
  </tr>
</tbody>
</table>
</div>
```
Explanation:
- The `{if ?COLUMN_NAME/}` statements for the table headers and table rows determine if the column is rendered based on whether the column has a value
- The ADDRESS1, CITY, STATE, and ZIP columns are referenced from the Region SQL

This is how it looks in APEX Builder:
![Screenshot showing Template Directive for Cards Region Body](https://cdn.hashnode.com/res/hashnode/image/upload/v1656373345095/FavmeakTi.png)

### Card Region Secondary-Body
We need to display tags indicating the person's expertise. The `tags` column in the SQL contains values delimited by a ':' e.g., `PLSQL:APEX:ORDS`. 

```HTML
{loop ":" TAGS/}
  <span class="a-CardView-badge a-CardView-badgeValue">&APEX$ITEM.</span>
{endloop/}
```
Explanation:
- The `loop` template directive is looping through the values from the `tag` column in the SQL. Each value is delimited by a ':'
- A specific tag value is referenced within the loop using `&APEX$ITEM.`
- The `<span></span>` HTML tags and the UT classes `a-CardView-badge` and `a-CardView-badgeValue` are used for styling

The code looks like this in APEX Builder:
![Screenshot showing Template Directive for Cards Secondary-Body](https://cdn.hashnode.com/res/hashnode/image/upload/v1656449960093/kjpQ1VC14.png)

## 🔗 Read More
- 📖 John Synders Post on [APEX Template Directives](https://hardlikesoftware.com/weblog/2020/11/04/apex-template-directives/#:~:text=Template%20directives%20are%20special%20tokens,supports%20substitutions%20and%20template%20directives.)
- 📖 [APEX Documentation](https://docs.oracle.com/en/database/oracle/apex/22.1/aexjs/apex.util.html#.applyTemplate)
- 🩳 [APEX Shorts](https://blog.cloudnueva.com/series/apex-shorts)
- #️⃣ [APEX Posts](https://blog.cloudnueva.com/tag/orclapex)
