Files
Flash5/flash-extensions/flash-ext-view-jte/docs/model-and-globals.md
T
Zakaria El OrcheandClaude Sonnet 5 4feabc45d5 fix(ext-view): clear cross-engine error, propagate globals across JteExtension builder chain
- BaseViewExtension: wrap the ViewRuntimeBridge provider collision with a message
  naming the real constraint (one view engine per FlashApp) instead of the generic
  "duplicate provider" error.
- BaseViewExtension/JteExtension: carry registered globals across JteExtension's
  immutable settings builders (templateRoot/serveStatics/staticPrefix/withStaticCors/
  staticCors). addGlobal() called before any of those used to be silently dropped,
  since each builder method returned a fresh instance with an empty globals list.
- Correct flash-ext-view-jte docs (README, architecture.md, model-and-globals.md):
  globals merge flat with one typed @param per key, not under a global.* namespace
  like Thymeleaf — the docs previously claimed the same reserved namespace for both
  engines, which doesn't match JteRuntime's actual merge behavior.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-09 13:31:21 +00:00

1.3 KiB

Model And Globals

ViewModel is the per-request data container.

POJO-First Pattern

Keep page state in a POJO and pass it as a single key:

return ViewModel.empty()
    .with("page", new HomePage("Flash + jte", "elorc"))
    .with("build", "dev");

Then type it in template:

@import com.example.HomePage
@param HomePage page
@param String build

Globals

Register globals in extension setup:

new JteExtension().addGlobal("appName", req -> "Flash")

Globals are merged flat into the model — same level as local ViewModel keys, not under a global.* namespace. jte templates are statically typed, so each template declares one @param per global it actually uses, named exactly like the global key:

@param String appName

<span>${appName}</span>

A template that doesn't declare appName simply never sees it — no need to declare every global on every page, only the ones a given template actually uses.

A local ViewModel key that collides with a registered global name fails fast with IllegalStateException at render time, so a typo can't silently shadow a global.

Every registered global is still resolved on every render regardless of whether the target template declares it, so keep resolvers cheap (no blocking I/O, no heavy allocation).