@samveys/view
From packages/view/README.md in the framework repository.
The view contract: one ViewEngine interface, an engine registry and ctx.view. No runtime dependencies.
| Engine | Package |
|---|---|
.tpl.html templates | @samveys/template |
| Vue server rendering | @samveys/vue |
| Inertia root view | @samveys/inertia (renders through the template engine) |
Set up
Install view() first, then an engine plugin.
import { http } from '@samveys/http'
import { template } from '@samveys/template'
import { view } from '@samveys/view'
export const plugins = [http(), view(), template()]view({ engine: 'vue' }) picks the active engine when several are installed. Without it, the first engine registered is used.
Render from a handler
import type { Router } from '@samveys/http'
export function routes(router: Router): void {
router.get('/users', async (ctx) => {
ctx.view.share('appName', 'Samveys')
return ctx.view.render('users.index', { title: 'Users' }, { status: 200 })
})
}ctx.view.render(name, data, init?)returns aResponsewithcontent-type: text/html; charset=utf-8.ctx.view.share(key, value)adds data for this request only. Data given torenderwins over shared data.- Every render is published on the
samveys:view.rendertracing channel. - Rendering without an installed engine, or with an unknown one, is
SVS_E109.
Write an engine
import type { ViewEngine } from '@samveys/view'
export const upper: ViewEngine = {
async render(name, data) {
return `${name}: ${JSON.stringify(data)}`.toUpperCase()
},
}Register it from a plugin with container.make('view.registry').register('upper', upper).
The render third argument carries the request (ctx.http) so an engine can read the CSRF token.
import { definePlugin } from '@samveys/core'
import { upper } from './upper.ts'
export const upperPlugin = definePlugin({
name: 'upper-engine',
requires: { plugins: ['@samveys/view'] },
boot: ({ container }) => container.make('view.registry').register('upper', upper),
})