Timill Platform Documentation

Widget Source Files

Downloadable Go template sources for the scripted widget examples.

This directory contains example Go templates for creating custom Scripted Widgets.

Overview#

Scripted Widgets allow you to create custom HTML widgets using Go’s html/template syntax. Templates have access to a powerful API for querying items, transforming data, and rendering HTML with automatic escaping for security.

Examples#

1. Simple Item List (01_simple_item_list.html)#

Displays a list of open items with their status badges.

Features:

  • Query items by status
  • Display item count
  • Show truncated descriptions
  • Status color coding
  • Empty state handling

Use Case: Quick overview of open tasks or issues


2. Status Dashboard (02_status_dashboard.html)#

Groups items by status and displays counts in a grid layout.

Features:

  • Group items by any field
  • Visual status cards
  • Total item count
  • Responsive grid layout

Use Case: High-level status overview for project management


3. Recent Activity (03_recent_activity.html)#

Shows recently updated items with relative timestamps.

Features:

  • Sort items by update time
  • Display relative time (“2 hours ago”)
  • Limit to top 10 items
  • Activity timeline view

Use Case: Track recent changes and updates


Available Template Functions#

Query Functions#

{{$items := queryItems "status:open"}}        // Query items with filter
{{$item := getItem "item-id"}}                // Get single item by ID
{{$count := countItems "assignee:me"}}        // Count items matching query

Data Transformation#

{{$grouped := groupBy $items "status"}}       // Group items by field
{{$filtered := filterItems $items "status" "open"}}  // Filter by field value
{{$sorted := sortItems $items "created" false}}      // Sort (false = descending)

Context Access#

{{$user := getCurrentUser}}                   // Get current user
{{$group := getCurrentGroup}}                 // Get current group

Formatting Functions#

{{formatDate .Created.Get}}                   // Format: 2024-01-15
{{formatDateTime .Updated.Get}}               // Format: 2024-01-15 14:30:00
{{truncateText .Description.Get 100}}         // Truncate to 100 chars
{{timeAgo .Updated.Get}}                      // Relative: "2 hours ago"

String Functions#

{{upper "hello"}}                             // HELLO
{{lower "HELLO"}}                             // hello
{{title "hello world"}}                       // Hello World

Utility Functions#

{{len $items}}                                // Get length
{{add 5 3}}                                   // 8
{{sub 10 3}}                                  // 7
{{mul 4 5}}                                   // 20
{{div 10 2}}                                  // 5

Styling Functions#

{{getStatusColor "In Progress"}}              // Returns Tailwind CSS classes

HTML Safety#

{{safeHTML "<strong>Bold</strong>"}}          // Render as HTML
{{safeAttr "data-value"}}                     // Safe attribute
{{safeURL "https://example.com"}}             // Safe URL

Template Structure#

Basic Template#

<div class="space-y-3">
  {{$items := queryItems "status:open"}}
  
  {{if $items}}
    <!-- Render items -->
    {{range $items}}
      <div>{{.Title.Get}}</div>
    {{end}}
  {{else}}
    <!-- Empty state -->
    <p>No items found</p>
  {{end}}
</div>

Accessing Item Fields#

{{.Title.Get}}                    // Item title
{{.Description.Get}}              // Item description
{{.Status.Get}}                   // Item status
{{.Type}}                         // Item type
{{.Group}}                        // Group ID
{{.Assignee.Get}}                 // Assignee ID
{{.Created.Get}}                  // Created timestamp
{{.Updated.Get}}                  // Updated timestamp

Conditional Rendering#

{{if .Status.Get}}
  <span>{{.Status.Get}}</span>
{{end}}

{{if gt (len $items) 10}}
  <p>More than 10 items</p>
{{end}}

Loops and Iteration#

{{range $items}}
  <div>{{.Title.Get}}</div>
{{end}}

{{range $index, $item := $items}}
  <div>{{$index}}: {{$item.Title.Get}}</div>
{{end}}

{{range $key, $value := $grouped}}
  <div>{{$key}}: {{len $value}} items</div>
{{end}}

Styling Guidelines#

All examples use Tailwind CSS classes for styling. The platform automatically handles:

  • Dark mode (using dark: prefix)
  • Responsive design
  • Consistent spacing and colors

Common Patterns#

Card Container:

<div class="bg-white dark:bg-gray-800 rounded-lg p-4 border border-gray-200 dark:border-gray-700">
  <!-- Content -->
</div>

Status Badge:

<span class="px-2 py-1 text-xs font-medium rounded {{getStatusColor .Status.Get}}">
  {{.Status.Get}}
</span>

Empty State:

<div class="text-center py-8">
  <svg class="mx-auto h-12 w-12 text-gray-400"><!-- Icon --></svg>
  <p class="mt-2 text-sm text-gray-500 dark:text-gray-400">No items</p>
</div>

Security#

All templates use Go’s html/template which provides automatic escaping:

  • HTML content is escaped by default
  • Use safeHTML only for trusted content
  • XSS protection is built-in
  • RBAC is enforced on all queries

Best Practices#

  1. Always handle empty states - Check if data exists before rendering
  2. Use semantic HTML - Proper heading hierarchy, lists, etc.
  3. Provide visual feedback - Loading states, empty states, error states
  4. Keep it responsive - Use Tailwind’s responsive classes
  5. Limit data - Don’t query thousands of items at once
  6. Cache when possible - Use auto-refresh sparingly
  7. Test dark mode - Ensure readability in both themes

Performance Tips#

  • Limit query results (use filters effectively)
  • Avoid nested loops when possible
  • Use countItems instead of len (queryItems ...) for counts only
  • Consider pagination for large datasets
  • Set reasonable refresh intervals (if using auto-refresh)

Troubleshooting#

Template Error:

  • Check syntax (closing tags, proper Go template syntax)
  • Verify function names are correct
  • Ensure all variables are defined before use

No Data Displayed:

  • Verify query syntax
  • Check RBAC permissions
  • Ensure group is selected in widget settings

Styling Issues:

  • Verify Tailwind class names
  • Check dark mode classes
  • Test in both light and dark themes

Additional Resources#