trellis 0.6.0 copy "trellis: ^0.6.0" to clipboard
trellis: ^0.6.0 copied to clipboard

Template engine for Dart, using natural HTML templates. Fragment-first for hypermedia-driven frameworks like HTMX. Inspired by Thymeleaf.

example/README.md

Trellis Examples #

Quick Start #

import 'package:trellis/trellis.dart';

void main() {
  final engine = Trellis(loader: MapLoader({}));

  final html = engine.render(
    '<h1 tl:text="\${title}">Default</h1>',
    {'title': 'Hello, Trellis!'},
  );
  print(html); // <html><head></head><body><h1>Hello, Trellis!</h1></body></html>

  // Fragment rendering for HTMX partial responses
  const template = '''
  <ul tl:fragment="items">
    <li tl:each="item : \${items}" tl:text="\${item}">placeholder</li>
  </ul>
  ''';
  final fragment = engine.renderFragment(
    template,
    fragment: 'items',
    context: {'items': ['Alpha', 'Beta', 'Gamma']},
  );
  print(fragment); // <ul><li>Alpha</li><li>Beta</li><li>Gamma</li></ul>
}

Examples #

basic/ -- API Demos #

Self-contained examples showing core trellis features with inline templates.

cd example/basic
dart pub get
dart run bin/example.dart        # Template features: text, if, each, switch, fragments
dart run bin/shelf_example.dart  # Shelf integration pattern

todo_app/ -- Full Shelf + HTMX App #

A complete server-side rendered todo application demonstrating trellis with Shelf and HTMX.

Features demonstrated:

  • External .html template files (natural templates)
  • Fragment-first architecture for HTMX partial responses
  • tl:each, tl:if, tl:unless, tl:text, tl:attr, tl:classappend, tl:with, tl:insert
  • renderFile() for full pages, renderFragment() / renderFragments() for HTMX partials
  • Custom filters (date, capitalize)
  • In-memory data store with CRUD operations
cd example/todo_app
dart pub get
dart run bin/server.dart
# Open http://localhost:8080

Project structure

todo_app/
├── bin/server.dart          # Shelf server, Trellis engine setup, route registration
├── lib/
│   ├── handlers.dart        # Route handlers — rendering logic and fragment strategy
│   ├── models.dart          # TodoList and Todo data models with toMap() for templates
│   └── store.dart           # In-memory CRUD store
├── templates/
│   └── app.html             # Single template file — full page + all named fragments
└── static/
    └── styles.css           # Application styles

Key architectural concepts

Single template fileapp.html serves as both the full-page template and the source of all named fragments (sidebar, main-content, todo-list, todo-row). renderFile() renders the whole document; renderFragments() extracts specific sections for HTMX partial responses. See the comment block at the top of app.html for details, including how to split fragments across multiple files instead.

Two render strategies — handlers choose between two fragment combinations depending on what changed. Todo CRUD operations return todo-list + OOB sidebar (counts update, header stays). List navigation/mutation returns main-content + OOB sidebar (full main area replaced including header). See handlers.dart for the rationale.

OOB sidebar — the sidebar carries hx-swap-oob="true", so a single HTMX response can update both the primary target and the sidebar counts simultaneously.

todoCount as integer — Trellis treats empty lists as truthy (unlike Thymeleaf), so tl:if="${todos}" would never hide the empty state. tl:if="${todoCount}" (where 0 is falsy) is the correct pattern for empty-collection guards in Trellis.

2
likes
160
points
482
downloads

Documentation

API reference

Publisher

verified publisherleafnode.se

Weekly Downloads

Template engine for Dart, using natural HTML templates. Fragment-first for hypermedia-driven frameworks like HTMX. Inspired by Thymeleaf.

Repository (GitHub)
View/report issues

Topics

#template #html #htmx #server-side-rendering

License

MIT (license)

Dependencies

args, html, matcher, string_scanner

More

Packages that depend on trellis