You are viewing PowerRoster™ v8.2. See what's new in Release Note v8.2

Customising the Resource Explorer

Prev Next

This guide provides comprehensive documentation for creating Handlebars templates for Resource Cards displayed in the Resource Explorer component.

What is the Resource Explorer?

The Resource Explorer is a searchable, filterable interface for browsing and selecting resources within the Velrada Rostering application. Resources are displayed as cards, with the visual presentation of each card determined by a customisable Handlebars template.

What is Handlebars?

Handlebars is a simple templating language that allows you to create HTML markup with dynamic data. Templates use double curly braces {{ }} to insert values and helpers.

Example:

<div>{{name}}</div>

If the resource has name: "John Smith", this renders as:

<div>John Smith</div>

AppSettings for Templates

App Setting - Roster/RosterPCF/ResourceCardTemplate

Default Value -

<div style="display:flex;align-items:center;gap:12px;padding:8px;position:relative;">
        <div style="width:40px;height:40px;border-radius:50%;background-color:{{colorFromIndex index}};display:flex;align-items:center;justify-content:center;flex-shrink:0;">
        <span style="color:white;font-weight:600;font-size:14px;">{{initials name}}</span>
        </div>
        <div style="display:flex;flex-direction:column;overflow:hidden;">
        <div style="display:flex;">
        <div style="font-weight:600;font-size:14px;color:rgb(50,49,48);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">
        {{name}}
        </div>
        {{#if isPreferred}}
            <div>{{{icon "star"}}}</div>
        {{/if}}
        </div>
        {{#if resourcetype}}
            <div style="font-size:12px;color:rgb(96,94,92);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">{{resourcetype}}</div>
        {{/if}}
        </div>
        {{#if isDoubleBooked}}
            <div style="position:absolute;top:-3px;right:-5px;" title="Double Booked">
            {{{icon "warning"}}}
            </div>
        {{/if}}
        </div>

Getting Started

Basic Template Structure

A minimal template looks like this:

<div style='padding:8px;'>
        <div style='font-weight:600;'>{{name}}</div>
        </div>

This displays the resource's name in bold with padding.

Editing Templates

A Resource Card template can be edited by editing the App Setting.

Template Data Context

Every resource card has access to a context object containing resource information. The available fields depend on your system configuration.

Core Fields (Always Available)

Field Name

Type

Description

Example Value

id

string

Unique identifier for the resource

"abc-123-def"

name

string

Display name of the resource

"John Smith"

isDoubleBooked

boolean

Whether resource is booked in conflicting time

true or false

resourceType

string

Type/category of resource

"Registered Nurse"

index

number

Position in the results list (0-based)

0, 1, 2, etc.

isPreferred

boolean

Whether resource is marked as preferred

true or false

isBookedToShift

boolean

Whether booked to the current shift

true or false

isBookedToSegment

boolean

Whether booked to the current segment

true or false

Custom/Dynamic Fields

Users can use the App Setting below to configure custom fields when they use a custom API to fetch or search for resources.

App Setting - Roster/RosterPCF/ResourceExplorerApiResourceFields

Example Values - resourcetype, customField1, etc (use comma separated values if providing multiple values)

Accessing Fields in Templates

Use the field name directly in double curly braces:

<div>{{name}}</div>
        <div>{{vel_email}}</div>
        <div>Skill: {{vel_skillrating}}/5</div>

Available Handlebars Helpers

Helpers are special functions you can use within templates to transform or conditionally display data.

Built-in Handlebars Helpers

{{#if condition}}...{{/if}}

Conditionally display content based on truthiness.

{{#if isPreferred}}
            <div style='color:green;'>★ Preferred Resource</div>
        {{/if}}

{{#unless condition}}...{{/unless}}

Opposite of if - displays content when condition is false.

{{#unless isDoubleBod
oked}}
            <div style='color:green;'>Available</div>
        {{/unless}}

{{#each array}}...{{/each}}

Loop through arrays.

{{#each skills}}
            <span>{{this}}</span>
        {{/each}}

{{#with object}}...{{/with}}

Change the context to a nested object.

{{#with location}}
            <div>{{city}}, {{state}}</div>
        {{/with}}

Custom Helpers

{{#ifEquals arg1 arg2}}...{{/ifEquals}}

Purpose: Compare two values for equality

Parameters:

  • arg1 - First value

  • arg2 - Second value

Example:

{{#ifEquals resourceType 'Registered Nurse'}}
            <div style='color:blue;'>
            {{else}}
                <div>Other Role</div>
        {{/ifEquals}}

Use Cases:

  • Show different badges based on status

  • Conditional formatting by resource type

  • Display role-specific icons

{{formatNumber value}}

Purpose: Format numbers with locale-specific thousand separators

Parameters:

  • value - Number to format

Example:

<div>Total Hours: {{formatNumber 1234.56}}</div>
        <!-- Renders: Total Hours: 1,234.56 -->

Use Cases:

  • Display salary/pay rates

  • Show hours worked

  • Format any numeric values

{{uppercase text}}

Purpose: Convert text to uppercase

Parameters:

  • text - String to convert

Example:

<div>{{uppercase name}}</div>
        <!-- "john smith" becomes "JOHN SMITH" -->

Use Cases:

  • Standardise name formatting

  • Emphasise important text

  • Display codes/IDs in uppercase

{{lowercase text}}

Purpose: Convert text to lowercase

Parameters:

  • text - String to convert

Example:

<div>Email: {{lowercase vel_email}}</div>
        <!-- "John.Smith@Example.COM" becomes "john.smith@example.com" -->

Use Cases:

  • Normalise email addresses

  • Format usernames

{{truncate text length}}

Purpose: Truncate text with ellipsis if it exceeds a specified length

Parameters:

  • text - String to truncate

  • length - Maximum character count

Example:

<div>{{truncate description 50}}</div>
        <!-- "This is a very long description that exceeds the limit"
        becomes "This is a very long description that exceeds th..." -->

Use Cases:

  • Prevent card text overflow

  • Display summaries

  • Limit long field values

{{initials name}}

Purpose: Extract initials from a full name

Parameters:

  • name - Full name string

Rules:

  • Single word: Returns first 2 characters uppercase

  • Multiple words: Returns first letter of first word + first letter of last word, uppercase

Examples:

{{initials 'John Smith'}}

        {{initials 'Mary Jane Watson'}}

        {{initials 'Madonna'}}
    

Use Cases:

  • Display initials in avatar circles

  • Compact name representations

  • Visual identification

Full Example:

<div style='display:flex;align-items:center;gap:8px;'>
        <div
        style='
        width: 32px;
        height: 32px;
        border-radius: 50%;
        background-color: {{colorFromIndex index}};
        color: white;
        display: flex;
        align-items: center;
        justify-content: center;
        font-weight: 600;
        font-size: 12px;
        '
        >
        {{initials name}}
        </div>
        <div>{{name}}</div>
        </div>

{{colorFromIndex index}}

Purpose: Generate a consistent color based on an index number

Parameters:

  • index - Numeric index (typically 0-23 for best distribution)

Returns: HSL color string (e.g., hsl(180, 65%, 45%))

Color Palette:

  • Uses 24 evenly distributed hues on the color wheel

  • 65% saturation, 45% lightness

  • Consistent colors for the same index

Example:

<div style='background-color:{{colorFromIndex index}};'>
        {{name}}
        </div>

Use Cases:

  • Color-code resources by position in list

  • Create visually distinct avatar backgrounds

  • Group visual identification

Color Examples:

  • index: 0 → hsl(0, 65%, 45%) (red)

  • index: 4 → hsl(60, 65%, 45%) (yellow)

  • index: 8 → hsl(120, 65%, 45%) (green)

  • index: 16 → hsl(240, 65%, 45%) (blue)

{{icon iconName}}

Purpose: Insert an inline SVG icon

Parameters:

  • iconName - Name of the icon (see Icon Library section)

Returns: Safe HTML string containing SVG markup

Example:

<div>
        {{icon 'calendar'}}
        Scheduled
        </div>

Use Cases:

  • Add visual indicators (warnings, status icons)

  • Display symbols next to text

  • Enhance visual communication

Common Icons:

  • {{icon "warning"}} - Alert symbol

  • {{icon "person"}} - Person silhouette

  • {{icon "calendar"}} - Calendar icon

  • {{icon "star"}} - Star (favorites)

  • {{icon "clock"}} - Time/clock

See full list in Icon Library section.


Icon Library

The system includes 40+ pre-built SVG icons you can use via the {{icon "name"}} helper.

Status & Alerts

Icon Name

Visual

Use Case

warning

⚠️ Yellow triangle

Warnings, conflicts

error

✖️ Red circle X

Errors, unavailable

info

ℹ️ Blue circle

Information, notes

success

✅ Green checkmark

Success, confirmed

breach

🚫 Red circle crossed out

Compliance breach

Example:

{{#if isDoubleBooked}}
            <div style='color:#A42626;'>
            {{icon 'warning'}}
            Double Booked
            </div>
        {{/if}}

Favorites & Ratings

Icon Name

Visual

Use Case

star

Filled star

Preferred/favorite

star-outline

☆ Empty star

Not preferred

Example:

<div>
        {{name}}
        {{#if isPreferred}}{{{icon 'star'}}}{{/if}}
        </div>

Actions

Icon Name

Visual

Use Case

edit

✏️  Pencil

Edit indicator

delete

🗑️  Trash Can

Delete/remove

copy

🗒️  Copy

Duplicate

paste

📄  Paste

Paste operation

save

💾  Floppy Disk

Save action

add

 Plus Sign

Add/create

remove

 Minus sign

Remove/subtract

refresh

🔄  Circular arrow

Refresh/reload

Navigation

Icon Name

Visual

Use Case

chevron-right

▶️  Right arrow

Next/forward

chevron-left

◀️  Left arrow

Previous/back

chevron-down

🔽  Down arrow

Expand/show more

chevron-up

🔼  Up arrow

Collapse/show less

Rostering Specific

Icon Name

Visual

Use Case

calendar

🗓️  Calendar

Dates, schedules

clock

🕛 Clock face

Time, duration

person

👤  Person silhouette

Individual resource

person-group

👥  Multiple people

Teams, groups

location

📍  Map pin

Location, territory

day-shift

☀️  Sun

Day shifts

night-shift

🌙  Moon

Night shifts

swap

🔄  Bidirectional arrows

Swap/exchange

lock

🔒  Locked padlock

Locked, unavailable

unlock

🔓  Unlocked padlock

Unlocked, available

Example:

<div style='font-size:12px;color:#605E5C;'>
        {{icon 'location'}}
        {{vel_territory}}
        </div>
        <div style='font-size:12px;color:#605E5C;'>
        {{icon 'clock'}}
        {{vel_shifthours}}
        hours
        </div>

Settings & Utility

Icon Name

Visual

Use Case

settings

⚙️  Gear

Configuration, settings

filter

🔍  Funnel

Filter options

search

🔎  Magnifying glass

Search

Complete Icon List

Status: warning, error, info, success, breach
        Favorites: star, star-outline
        Actions: edit, delete, copy, paste, save, add, remove, refresh
        Navigation: chevron-right, chevron-left, chevron-down, chevron-up
        Rostering: calendar, clock, person, person-group, location,
        day-shift, night-shift, swap, lock, unlock
        Settings: settings, filter, search
    

Template Examples

Example 1: Basic Card with Name and Type

<div style='padding:8px;display:flex;flex-direction:column;gap:4px;'>
        <div style='font-weight:600;font-size:14px;color:rgb(50,49,48);'>
        {{name}}
        </div>
        {{#if resourceType}}
            <div style='font-size:12px;color:rgb(96,94,92);'>
            {{resourceType}}
            </div>
        {{/if}}
        </div>

Renders:

John Smith
        Registered Nurse

Example 2: Card with Avatar Initials

<div style='display:flex;align-items:center;gap:8px;padding:8px;'>
        <div
        style='
        width: 36px;
        height: 36px;
        border-radius: 50%;
        background-color: {{colorFromIndex index}};
        color: white;
        display: flex;
        align-items: center;
        justify-content: center;
        font-weight: 600;
        font-size: 14px;
        '
        >
        {{initials name}}
        </div>
        <div style='flex:1;'>
        <div style='font-weight:600;'>{{name}}</div>
        <div style='font-size:12px;color:#605E5C;'>{{resourceType}}</div>
        </div>
        </div>

Renders:

[JS] John Smith
        Registered Nurse

(Where [JS] is a colored circle with initials)

Example 3: Card with Status Indicators

<div style='padding:8px;'>
        <div style='font-weight:600;display:flex;align-items:center;gap:4px;'>
        {{name}}
        {{#if isPreferred}}{{{icon 'star'}}}{{/if}}
        </div>

        {{#if resourceType}}
            <div style='font-size:12px;color:#605E5C;margin-top:4px;'>
            {{icon 'person'}}
            {{resourceType}}
            </div>
        {{/if}}

        {{#if isDoubleBooked}}
            <div
            style='font-size:11px;color:#A42626;font-weight:500;margin-top:4px;'
            >
            {{icon 'warning'}}
            Double Booked
            </div>
        {{/if}}
        </div>

Renders:

John Smith ★

👤 Registered Nurse

⚠ Double Booked

Example 4: Detailed Card with Custom Fields

<div style='padding:10px;border-left:3px solid {{colorFromIndex index}};'>
        <!-- Header -->
        <div
        style='display:flex;align-items:center;gap:6px;margin-bottom:8px;'
        >
        <div
        style='
        width: 32px;
        height: 32px;
        border-radius: 50%;
        background-color: {{colorFromIndex index}};
        color: white;
        display: flex;
        align-items: center;
        justify-content: center;
        font-weight: 600;
        font-size: 12px;
        '
        >
        {{initials name}}
        </div>
        <div style='flex:1;'>
        <div style='font-weight:600;font-size:14px;'>
        {{name}}
        {{#if isPreferred}}{{{icon 'star'}}}{{/if}}
        </div>
        </div>
        </div>

        <!-- Details -->
        <div
        style='display:flex;flex-direction:column;gap:4px;font-size:12px;color:#605E5C;'
        >
        {{#if resourceType}}
            <div>{{{icon 'person'}}} {{resourceType}}</div>
        {{/if}}

        {{#if vel_territory}}
            <div>{{{icon 'location'}}} {{vel_territory}}</div>
        {{/if}}

        {{#if vel_email}}
            <div>✉ {{lowercase vel_email}}</div>
        {{/if}}

        {{#if vel_skillrating}}
            <div>★ Skill: {{vel_skillrating}}/5</div>
        {{/if}}
        </div>

        <!-- Status -->
        {{#if isDoubleBooked}}
            <div
            style='
            margin-top: 8px;
            padding: 4px 8px;
            background-color: #FDE7E9;
            color: #A42626;
            border-radius: 4px;
            font-size: 11px;
            font-weight: 500;
            '
            >
            {{icon 'warning'}}
            Double Booked
            </div>
        {{/if}}
        </div>

Renders: A detailed card with avatar, multiple fields, and status indicator.

Example 5: Compact Horizontal Layout

<div
        style='display: flex; align-items: center; justify-content: space-between;
        padding: 6px 10px;'
        >
        <div style='display:flex;align-items:center;gap:8px;'>
        <div
        style='
        width: 28px;
        height: 28px;
        border-radius: 50%;
        background-color: {{colorFromIndex index}};
        color: white;
        display: flex;
        align-items: center;
        justify-content: center;
        font-weight: 600;
        font-size: 11px;
        '
        >
        {{initials name}}
        </div>
        <div>
        <div style='font-weight:600;font-size:13px;'>{{name}}</div>
        <div style='font-size:11px;color:#605E5C;'>{{truncate
        resourceType
        20
      }}</div>
        </div>
        </div>

        <div style='display:flex;gap:4px;'>
        {{#if isPreferred}}{{icon 'star'}}{{/if}}
        {{#if isDoubleBooked}}{{icon 'warning'}}{{/if}}
        </div>
        </div>

Example 6: Role-Based Styling

<div style='padding:10px;'>hand

        {{#ifEquals resourceType 'Registered Nurse'}}
            <div style='background-color:#E3F2FD;padding:8px;border-radius:4px;'>
            <div style='font-weight:600;color:#1976D2;'>
            {{icon 'person'}}
            {{name}}
            </div>
            <div style='font-size:12px;color:#1565C0;'>RN - Registered Nurse</div>
            </div>
            {{else}}
                {{#ifEquals resourceType 'Licensed Practical Nurse'}}
                    <div style='background-color:#F3E5F5;padding:8px;border-radius:4px;'>
                    <div style='font-weight:600;color:#7B1FA2;'>
                    {{icon 'person'}}
                    {{name}}
                    </div>
                    <div style='font-size:12px;color:#6A1B9A;'>LPN - Licensed Practical Nurse</div>
                    </div>
                    {{else}}
                        <div style='padding:8px;'>
                        <div style='font-weight:600;'>{{name}}</div>
                        <div style='font-size:12px;color:#605E5C;'>{{resourceType}}</div>
                        </div>
                {{/ifEquals}}
        {{/ifEquals}}
        </div>

This template applies different background colors and styling based on the resource type.

Styling Guidelines

Recommended Inline Styles

Templates support inline CSS styles only (no external CSS classes). Use the style attribute.

Typography

<!-- Primary text -->
        <div style='font-weight:600;font-size:14px;color:rgb(50,49,48);'>
        {{name}}
        </div>

        <!-- Secondary text -->
        <div style='font-size:12px;color:rgb(96,94,92);'>
        {{resourceType}}
        </div>

        <!-- Small text -->
        <div style='font-size:11px;color:rgb(96,94,92);'>
        Additional info
        </div>

Colors

Use Fluent UI color palette for consistency:

Use Case

Color

RGB Value

Primary text

Near-black

rgb(50,49,48)

Secondary text

Gray

rgb(96,94,92)

Error/Warning

Red

rgb(164,38,44)

Success

Green

rgb(16,124,16)

Info/Link

Blue

rgb(0,120,212)

Background (error)

Light red

#FDE7E9

Background (info)

Light blue

#E3F2FD

Border

Light gray

rgb(237,235,233)

Layout

<!-- Flexbox container -->
        <div style='display:flex;flex-direction:column;gap:4px;'>
        <!-- Content -->
        </div>

        <!-- Horizontal flex -->
        <div style='display:flex;align-items:center;gap:8px;'>
        <!-- Content -->
        </div>

        <!-- Padding -->
        <div style='padding:8px;'>
        <!-- Content -->
        </div>

        <!-- Margins -->
        <div style='margin-top:4px;margin-bottom:8px;'>
        <!-- Content -->
        </div>

Borders & Radius

<!-- Rounded corners -->
        <div style='border-radius:4px;'>
        <!-- Content -->
        </div>

        <!-- Circle (for avatars) -->
        <div style='border-radius:50%;'>
        <!-- Content -->
        </div>

        <!-- Border -->
        <div style='border:1px solid rgb(237,235,233);'>
        <!-- Content -->
        </div>

        <!-- Left accent border -->
        <div style='border-left:3px solid {{colorFromIndex index}};'>
        <!-- Content -->
        </div>

Accessibility Considerations

  1. Color Contrast: Ensure sufficient contrast between text and background

    • Minimum 4.5:1 ratio for normal text

    • Minimum 3:1 for large text (18pt+)

  2. Icon Meanings: Don't rely solely on color to convey meaning

    • Use icons with color

    • Include text labels

  3. Font Size: Keep text readable

    • Minimum 11px for small text

    • 12-14px for body text

    • 16px+ for headers


Best Practices

Keep Cards Compact

Resource cards should fit comfortably in a vertical list. Aim for heights between 60-120px.

 Too Large:

<div style='padding:30px;font-size:18px;'>
        <!-- Too much padding andnd large font -->
        </div>

 Good Size:

<div style='padding:8px;font-size:14px;'>
        <!-- Compact and readable -->
        </div>

Use Conditional Rendering

Only show fields when they have values.

Don't:

<div>Email: {{vel_email}}</div>
        <!-- Shows "Email: " even if empty -->

Do:

{{#if vel_email}}
            <div>Email: {{vel_email}}</div>
        {{/if}}

Handle Missing Data Gracefully

Always provide fallbacks for optional fields.

<div>
        {{#if resourceType}}
            {{resourceType}}
        {{else}}
            <span style='color:#A0A0A0;'>No Type Specified</span>
        {{/if}}
        </div>

Maintain Visual Hierarchy

Use font weight, size, and color to establish importance.

<!-- Primary info (largest, boldest) -->
        <div style='font-weight:600;font-size:14px;color:rgb(50,49,48);'>
        {{name}}
        </div>

        <!-- Secondary info (medium) -->
        <div style='font-size:12px;color:rgb(96,94,92);'>
        {{resourceType}}
        </div>

        <!-- Tertiary info (smallest) -->
        <div style='font-size:11px;color:rgb(96,94,92);'>
        {{vel_employeeid}}
        </div>

Consistent Spacing

Use consistent gap values throughout your template.

Recommended spacing scale:

  • gap: 4px - Tight spacing (within a section)

  • gap: 8px - Medium spacing (between sections)

  • gap: 12px - Loose spacing (major separators)

<div style='display:flex;flex-direction:column;gap:4px;'>
        <!-- Items close together -->
        </div>

Optimise for Scanning

Users often scan lists quickly. Put the most important information first and make it visually distinct.

Good hierarchy:

  1. Name (largest, bold)

  2. Role/Type (medium, secondary color)

  3. Status indicators (icons, colored badges)

  4. Additional details (smallest, tertiary color)

Test with Real Data

Test your templates in a development environment with realistic data that matches your production environment. Test edge cases:

  • Very long names

  • Missing fields

  • Multiple status flags active

  • Resources with all custom fields populated

Tip: Use browser developer tools to inspect the rendered HTML and verify your template output.

Performance Considerations

  • Avoid complex nested loops - Each card renders many times

  • Use helpers efficiently - Helpers like colorFromIndex are optimised

  • Keep HTML minimal - More DOM nodes = slower rendering


Troubleshooting

Problem: Template shows blank cards

Possible Causes:

  1. Syntax error in Handlebars

  2. Missing closing tags ({{/if}}, {{/each}})

  3. Field name typo

Solution:

  • Check browser console for Handlebars compilation errors

  • Verify all {{#if}} blocks have matching {{/if}} closings

  • Verify field names match your data exactly (case-sensitive)

Problem: Icons not appearing

Possible Causes:

  1. Icon name typo

  2. Using quotes incorrectly

Solution:

<!-- ✖ Wrong -->
        {{icon 'warning'}}

        <!-- ✅ Correct -->
        {{icon "warning"}}

Problem: Data not showing

Possible Causes:

  1. Field not included in resourceExplorerApiResourceFields app setting

  2. Field name mismatch

  3. Data not available for that resource

Solution:

  • Check browser console to see the actual resource data being passed to the template

  • Verify resourceExplorerApiResourceFields app setting includes your custom field

  • Use {{#if fieldName}} to handle missing data

Problem: Styling not working

Possible Causes:

  1. Invalid CSS syntax

  2. Using external CSS classes (not supported)

  3. Missing semicolons in style attribute

Solution:

<!-- ✖ Wrong - missing semicolon -->
        <div style="color:red font-size:14px">

        <!-- ✅ Correct -->
        <div style="color:red;font-size:14px;">

Problem: Cards different heights

Cause: Conditional content creates variable-height cards

Solution: Use fixed height or min-height if consistency is important

<div style='min-height:80px;padding:8px;'>
        <!-- Content -->
        </div>


Advanced Techniques

Creating Status Badges

{{#if isDoubleBooked}}
            <div
            style='
            display: inline-block;
            padding: 2px 8px;
            background-color: #FDE7E9;
            color: #A42626;
            border-radius: 12px;
            font-size: 11px;
            font-weight: 500;
            '
            >
            {{icon 'warning'}}
            Double Booked
            </div>
        {{/if}}

Multi-Column Layouts

<div style='display:grid;grid-template-columns:1fr 1fr;gap:8px;padding:8px;'>
        <div>
        <div style='font-size:11px;color:#605E5C;'>Name</div>
        <div style='font-weight:600;'>{{name}}</div>
        </div>
        <div>
        <div style='font-size:11px;color:#605E5C;'>Type</div>
        <div style='font-weight:600;'>{{resourceType}}</div>
        </div>
        <div>
        <div style='font-size:11px;color:#605E5C;'>Territory</div>
        <div style='font-weight:600;'>{{vel_territory}}</div>
        </div>
        <div>
        <div style='font-size:11px;color:#605E5C;'>Rating</div>
        <div style='font-weight:600;'>{{vel_skillrating}}/5</div>
        </div>
        </div>

Custom Skill Rating Display

{{#if vel_skillrating}}
            <div style='display:flex;align-items:center;gap:4px;'>
            <span style='font-size:11px;color:#605E5C;'>Skill:</span>
            {{#ifEquals vel_skillrating 5}}
                <span style='color:#107C10;'>★ ★ ★ ★ ★</span>
        {{else}}
            {{#ifEquals vel_skillrating 4}}
                <span style='color:#107C10;'>★ ★ ★ ★ ☆</span>
        {{else}}
            {{#ifEquals vel_skillrating 3}}
                <span style='color:#FDB900;'>★ ★ ★ ☆ ☆</span>
        {{else}}
            <span style='color:#FDB900;'>{{vel_skillrating}}/5</span>
            {{/ifEquals}}
            {{/ifEquals}}
            {{/ifEquals}}
            </div>
        {{/if}}

Dynamic Background Colors

<div
        style='
        padding: 10px;
        background: linear-gradient(
        to right,
        {{colorFromIndex index}}15,
        {{colorFromIndex index}}05
        );
        border-left: 3px solid {{colorFromIndex index}};
        '>

        <div style='font-weight:600;'>{{name}}</div>
        <div style='font-size:12px;color:#605E5C;'>{{resourceType}}</div>
        </div>

Note: The 15 and 05 are hex opacity values (15% and 5% opacity).

Combining Multiple Conditions

{{#if isPreferred}}
            {{#unless isDoubleBooked}}
                <div
                style='
                background-color: #E8F5E9;
                color: #2E7D32;
                padding: 4px 8px;
                border-radius: 4px;
                font-size: 11px;
                font-weight: 500;
                '
                >
                {{icon 'star'}}
                {{icon 'success'}}
                Available & Preferred
                </div>
            {{/unless}}
            {/if}}

Responsive Text Sizing

<div style='padding:8px;'>
        <!-- Name takes available space, truncates if too long -->
        <div
        style='
        font-weight: 600;
        font-size: 14px;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        max-width: 200px;
        '
        >
        {{name}}
        </div>

        <!-- Or use truncate helper -->
        <div style='font-weight:600;font-size:14px;'>
        {{truncate name 25}}
        </div>
        </div>

Field Labels with Icons

<div style='display:flex;flex-direction:column;gap:6px;font-size:12px;'>
        <div style='display:flex;align-items:center;gap:6px;'>
        {{icon 'person'}}
        <span style='color:#605E5C;'>{{resourceType}}</span>
        </div>

        {{#if vel_territory}}
            <div style='display:flex;align-items:center;gap:6px;'>
            {{icon 'location'}}
            <span style='color:#605E5C;'>{{vel_territory}}</span>
            </div>
        {{/if}}

        {{#if vel_email}}
            <div style='display:flex;align-items:center;gap:6px;'>
            <span style='font-size:14px;'>✉</span>
            <span style='color:#0078D4;'>{{lowercase vel_email}}</span>
            </div>
        {{/if}}
        </div>

Nested Conditions for Complex Logic

<div style='padding:8px;'>
        <div style='font-weight:600;font-size:14px;'>{{name}}</div>

        <!-- Status badge with priority logic -->
        {{#if isDoubleBooked}}
            <!-- High priority: show double booked -->
            <div style='color:#A42626;font-size:11px;margin-top:4px;'>
            {{icon 'warning'}}
            Unavailable - Double Booked
            </div>
        {{else}}
            {{#if isPreferred}}
                <!-- Medium priority: show preferred if not double booked -->
                <div style='color:#107C10;font-size:11px;margin-top:4px;'>
                {{icon 'star'}}
                Preferred Resource
                </div>
            {{else}}
                <!-- Low priority: show available -->
                <div style='color:#605E5C;font-size:11px;margin-top:4px;'>
                Available
                </div>
            {{/if}}
        {{/if}}
        </div>

Summary Checklist

When creating a new template, ensure you:

  • Use valid Handlebars syntax

  • Include conditional checks for optional fields ({{#if field}})

  • Keep card height reasonable (60-120px)

  • Use inline styles only (no external CSS classes)

  • Test in a development environment before deploying to production

  • Verify field names match your Dataverse configuration

  • Include visual indicators for important states (preferred, double booked)

  • Use helpers to transform data (uppercase, truncate, formatNumber)

  • Maintain consistent spacing and typography

  • Ensure good color contrast for accessibility

  • Handle edge cases (long names, missing data)

  • Save template to vel_appsetting with key Roster/RosterPCF/ResourceCardTemplate

Additional Resources

Getting Help

If you encounter issues:

  1. Check browser console - Look for Handlebars compilation errors and JavaScript errors

  2. Review sample data - Use browser dev tools to inspect resource data

  3. Test incrementally - Build complex templates step by step, testing after each change

  4. Refer to examples - Copy/modify examples from this guide

  5. Use a development environment - Always test templates before deploying to production