> ## Documentation Index
> Fetch the complete documentation index at: https://learn.nextedy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Use Velocity Templates

> Write Velocity template expressions for Nextedy POWERSHEET server-rendered properties to compute dynamic values from work item data and Siemens Polarion ALM platform services.

export const LastReviewed = ({date}) => {
  if (!date) return null;
  const formatted = new Date(`${date}T00:00:00Z`).toLocaleDateString("en-US", {
    year: "numeric",
    month: "long",
    day: "numeric",
    timeZone: "UTC"
  });
  return <p className="mt-10 text-sm text-gray-400 dark:text-zinc-500 not-prose">
      Last reviewed on {formatted}
    </p>;
};

## Prerequisites

* A data model with a server-rendered property (see [Create a Computed Property](/powersheet/guides/server-rendering/create-computed-property))
* Basic understanding of Apache Velocity template syntax

<Steps>
  <Step title="Access Work Item Properties via $item">
    The `$item` variable provides access to the work item model object. Use it to read standard and custom field values:

    ```velocity theme={null}
    $item.title
    $item.status
    $item.author
    $item.created
    $item.updated
    ```

    Example `serverRender` expression that combines fields:

    ```yaml theme={null}
    properties:
      summary:
        serverRender: "$item.id: $item.title ($item.status)"
        readable: true
        updatable: false
    ```
  </Step>

  <Step title="Use Conditional Logic">
    Velocity supports `#if`, `#elseif`, `#else`, and `#end` directives for conditional rendering:

    ```yaml theme={null}
    properties:
      priorityLabel:
        serverRender: "#if($item.priority == 'critical')CRITICAL#elseif($item.priority == 'high')High#else Normal#end"
        readable: true
        updatable: false
    ```

    | Directive               | Purpose                  |
    | ----------------------- | ------------------------ |
    | `#if(condition)`        | Start conditional block  |
    | `#elseif(condition)`    | Alternative condition    |
    | `#else`                 | Default fallback         |
    | `#end`                  | Close block              |
    | `#foreach($x in $list)` | Iterate over collections |
    | `#set($var = value)`    | Assign a variable        |
  </Step>

  <Step title="Access Document Context via $module">
    When a work item belongs to a LiveDoc, the `$module` variable provides document-level properties:

    ```yaml theme={null}
    properties:
      docContext:
        serverRender: "$module.moduleFolder/$module.moduleName"
        readable: true
        updatable: false
    ```

    <Warning title="$module is null for non-document entities">
      If the entity is not associated with a document, `$module` will be null. Always add a null check: `#if($module)$module.moduleName#else N/A#end`
    </Warning>
  </Step>

  <Step title="Use the Low-Level Work Item API via $wi">
    The `$wi` variable exposes the Polarion work item API for operations not available on `$item`:

    ```yaml theme={null}
    properties:
      linkedCount:
        serverRender: "$wi.getLinkedWorkItemsStructsDirect().size()"
        readable: true
        updatable: false
    ```

    <Note title="$wi availability">
      The `$wi` variable is only available for work item entities. For other entity types (documents, chapters), use `$item` or `$module` instead.
    </Note>
  </Step>

  <Step title="Use Platform Services">
    Server-rendered templates have access to several Polarion platform services:

    ```yaml theme={null}
    properties:
      projectName:
        serverRender: "$trackerService.getProjectById($item.projectId).getName()"
        readable: true
        updatable: false
    ```

    Available service variables:

    | Variable             | Service           | Common Uses                       |
    | -------------------- | ----------------- | --------------------------------- |
    | `$trackerService`    | Work item tracker | Query work items, access projects |
    | `$txService`         | Transaction       | Transaction context               |
    | `$repositoryService` | Repository        | Project metadata, users, roles    |
    | `$securityService`   | Security          | Permission checks, user auth      |

    See [Access Polarion Services](/powersheet/guides/server-rendering/access-polarion-services) for detailed examples of each service.
  </Step>

  <Step title="Handle Errors Gracefully">
    When a Velocity template fails, Powersheet returns the error marker `#SERVER_RENDER_ERROR` in the cell. Protect against common failures with defensive coding:

    ```yaml theme={null}
    properties:
      safeTitle:
        serverRender: "#if($item && $item.title)$item.title#else (untitled)#end"
        readable: true
        updatable: false
    ```

    <Warning title="Template error marker">
      If you see `#SERVER_RENDER_ERROR` in a column cell, the template failed due to a parse error, method invocation error, or missing resource. Check the Polarion server logs for the specific exception type.
    </Warning>
  </Step>
</Steps>

## Template Patterns Reference

**String concatenation:**

```velocity theme={null}
$item.id - $item.title
```

**Null-safe access:**

```velocity theme={null}
#if($item.severity)$item.severity#else Unset#end
```

**Collection iteration:**

```velocity theme={null}
#foreach($link in $wi.getLinkedWorkItemsStructsDirect())$link.getLinkedItem().getId() #end
```

**Variable assignment:**

```velocity theme={null}
#set($count = $wi.getLinkedWorkItemsStructsDirect().size())$count linked items
```

<Info title="Verify in application">
  The available methods on `$item`, `$wi`, and platform services depend on your Polarion version. Test templates with simple expressions before building complex logic.
</Info>

## Verify

After configuring a Velocity template expression:

1. Open the powersheet document in Polarion
2. You should now see computed values in the server-rendered column
3. Verify that null-safe checks work by testing with work items that have empty fields
4. If values show `#SERVER_RENDER_ERROR`, consult the [Debug Template Errors](/powersheet/guides/server-rendering/debug-template-errors) guide

## See Also

* [Create a Computed Property](/powersheet/guides/server-rendering/create-computed-property) -- setting up server-rendered properties
* [Access Polarion Services](/powersheet/guides/server-rendering/access-polarion-services) -- using platform services in templates
* [Debug Template Errors](/powersheet/guides/server-rendering/debug-template-errors) -- troubleshooting template failures
* [Configure a Formatter](/powersheet/guides/sheet-configuration/configure-formatter) -- styling computed values

<LastReviewed date="2026-07-02" />
