Skip to content

Conditional Rendering

Press lets you show or hide any element based on whether data is present. This is how you build templates that adapt to different inputs -- optional sections, fallback values, and dynamic layouts.

The show-if Attribute

Add show-if to any element. The element is rendered only when the condition is truthy (present and non-empty):

xml
<frame show-if="data.executive-summary">
  <h2>Executive Summary</h2>
  <p>{{ data.executive-summary }}</p>
</frame>

If data.executive-summary is missing, empty, or null, the entire frame is skipped -- it takes up no space in the layout.

What Counts as Truthy?

ValueRendered?
"some text"Yes
123Yes
trueYes
[ ... ] (non-empty array)Yes
{ ... } (non-empty object)Yes
"" (empty string)No
falseNo
"false"Yes
Missing fieldNo

Using show-if on Different Elements

On Frames

xml
<frame show-if="data.disclaimer" padding="12pt" background-color="#fef3c7">
  <p font-style="italic">{{ data.disclaimer }}</p>
</frame>

On Images

xml
<img show-if="data.company-logo" src="{{ data.company-logo }}" max-height="60pt" />

On Table Rows

xml
<table>
  <tr>
    <td>Subtotal</td>
    <td>{{ data.subtotal }}</td>
  </tr>
  <tr show-if="data.discount">
    <td>Discount</td>
    <td>-{{ data.discount }}</td>
  </tr>
  <tr show-if="data.tax">
    <td>Tax ({{ data.tax-rate }}%)</td>
    <td>{{ data.tax }}</td>
  </tr>
  <tr>
    <td font-style="bold">Total</td>
    <td font-style="bold">{{ data.total }}</td>
  </tr>
</table>

On Text Inline

xml
<p>
  Contact: {{ data.contact.name }}
  <span show-if="data.contact.phone"> | {{ data.contact.phone }}</span>
  <span show-if="data.contact.email"> | {{ data.contact.email }}</span>
</p>

Ternary Expressions

For switching between two values based on a condition, use ternary expressions inside {{ }}:

xml
{{ condition ? valueIfTrue : valueIfFalse }}

Dynamic Sizing

xml
<frame width="{{ data.sidebar ? '65%' : '100%' }}">
  <flow name="body" />
</frame>
<frame show-if="data.sidebar" width="30%">
  <flow name="sidebar" />
</frame>

Conditional Text

xml
<frame font-color="{{ data.overdue ? '#dc2626' : '#16a34a' }}">
  Status: {{ data.overdue ? 'Overdue' : 'Current' }}
</frame>

Conditional Styling

xml
<frame background-color="{{ data.priority ? '#fef2f2' : '#f9fafb' }}"
       border-color="{{ data.priority ? '#fca5a5' : '#e5e7eb' }}"
       border-weight="1pt" padding="12pt">
  <h3>{{ data.title }}</h3>
</frame>

The <show-if> Directive

In addition to the attribute form, Press also supports a <show-if> wrapper element with a condition attribute:

xml
<show-if condition="data.subtitle">
  <frame font-size="14pt" font-color="#6b7280">
    {{ data.subtitle }}
  </frame>
  <hr />
</show-if>

This is useful when you want to conditionally render multiple sibling elements together without wrapping them in an extra frame.

Common Patterns

Conditional Page Types

Use data to select different page layouts:

xml
<repeat group="sections" item="section">
  <page name="{{ section.data.page-type ? section.data.page-type : 'default-page' }}" />
</repeat>

Default Values

xml
<frame>{{ data.currency ? data.currency : '£' }}{{ data.total }}</frame>

Or using asset defaults:

xml
<img src="{{ data.logo ? data.logo : assets.data.defaults.logo }}" />