title: "Step 2 — Variables & Filters" active_step: 2

# Step 2 — Variables & Filters

Template variables with `#hashtag#` syntax and chainable filters.

## Variable syntax

Variables are wrapped in `#` signs. They're replaced with their value at render time. They can come from sessions, URL params, fetched data, or app state.

    #session.visitor_name#      <!-- Session variable -->
    #params.id#                 <!-- URL parameter -->
    #user.email#                <!-- Authenticated user -->
    #post.title#                <!-- Fetched data -->
    #env.APP_NAME#              <!-- Environment variable -->

Naming rules: Variable names use letters, numbers, underscores, and dots. Use `my_var` not `my-var` — hyphens are not allowed.

## Filters

Append a filter with `|filtername`. Chain multiple filters. Arguments go after a colon.

Filter | Example | Output
--- | --- | ---
`uppercase` | `#name|uppercase#` | ALICE
`lowercase` | `#name|lowercase#` | alice
`truncate:N` | `#bio|truncate:50#` | First 50 chars...
`default:"val"` | `#name|default:"stranger"#` | stranger (if empty)

    <!-- Chained filters -->
    #session.bio|truncate:80|uppercase#

## Date & time formatting

The `date` filter formats dates. Use `#now#` to get the current date and time. Pass a preset name or a custom mask.

Live — current date rendered by the server
`#now|date:"full"#` → #now|date:"full"#
`#now|date:"medium"#` → #now|date:"medium"#
`#now|date:"time"#` → #now|date:"time"#
`#now|date:"iso"#` → #now|date:"iso"#

Preset | Example output
--- | ---
`short` | 3/15/25
`medium` | Mar 15, 2025
`long` | March 15, 2025
`full` | Saturday, March 15, 2025
`time` | 2:30 PM
`iso` | 2025-03-15

    <p>Today is #now|date:"full"#</p>
    <p>Posted on #post.created_at|date:"medium"#</p>
    <time>#event.start|date:"h:nn tt"#</time>

## Arithmetic

Use math operators directly inside `#...#` expressions. Works with numbers and variables.

    #price * 0.21#            <!-- Tax calculation -->
    #session.count + 1#       <!-- Increment -->
    #total - discount#        <!-- Subtraction -->
    #items / 2#               <!-- Division -->

### Math filters

Filter | Example | Output
--- | --- | ---
`round:N` | `#price * 0.21|round:2#` | 2.10
`ceil` | `#rating|ceil#` | 4 (from 3.2)
`floor` | `#rating|floor#` | 3 (from 3.8)

## Interactive demo — type your name

Type your name below. The `w-set` attribute writes it to your session. The greeting above updates live — no JavaScript required.

Hello, #session.visitor_name|default:"stranger"#!
Your name

The value persists across page reloads because it's stored in your server-side session.

    <!-- The greeting -->
    Hello, #session.visitor_name|default:"stranger"#!

    <!-- The input that writes to session -->
    <input
      type="text"
      w-set="session.visitor_name = $value"
    >

What you learned

- Variables use `#varname#` syntax
- Filters transform values: `#var|uppercase#`, `#var|truncate:50#`
- `|default:"fallback"` handles missing values
- Filters chain: `#var|truncate:100|uppercase#`
- Date formatting: `#now|date:"full"#`, `#created|date:"medium"#`
- Arithmetic: `#price * 0.21#`, `#count + 1#`
- Math filters: `round:2`, `ceil`, `floor`
- `w-set="session.key = $value"` writes input values to session