W0703: A layout reading the request
A folder's layout stays while the visitor moves between the pages below it: its Load doesn't run again, and its sidebar keeps its scroll, its menus their state. That holds for a layout reading only its path parameters, which can't change under it. One whose methods — or the functions of its package they call — read more of the request, web.Request(ctx), an *http.Request, its URL or query, could show something stale, so it loads and renders again on every navigation, as vuka registers it (web.ReloadLayout). It works; it is only slower, and what it renders doesn't stay.
The usual reason is a menu marking the current page. Mark it in the browser instead, with ui.Link's active: the runtime follows the address on every navigation.
The other is a header showing the page's title or breadcrumbs, read in the layout's Load with ui.PageTitle(ctx) or ui.PageCrumbs(ctx). A Load that runs once would keep the first page's, so the layout reloads too. Read them in the markup instead: it renders again for every page while the layout stays.
Wrong
<script lang="go">
// pages/_layout.vuka.html
type Layout struct {
Children ui.Node
path string
}
func (l *Layout) Load(ctx context.Context) error {
l.path = web.Request(ctx).URL.Path
return nil
}
</script>
<nav>
if strings.HasPrefix(path, "/orders") {
<a href="/orders" class="on">Orders</a>
} else {
<a href="/orders">Orders</a>
}
</nav>
<main>{Children}</main>Right
<script lang="go">
// pages/_layout.vuka.html
type Layout struct {
Children ui.Node
}
</script>
<nav>
<ui.Link href="/orders" active="prefix" activeClass="on">Orders</ui.Link>
</nav>
<main>{Children}</main>Wrong: the title in Load
<script lang="go">
// pages/admin/_layout.vuka.html
type Shell struct {
Children ui.Node
title string
}
func (l *Shell) Load(ctx context.Context) error {
l.title = ui.PageTitle(ctx)
return nil
}
</script>
<h1>{title}</h1>
<main>{Children}</main>Right: the title in the markup
<script lang="go">
// pages/admin/_layout.vuka.html
type Shell struct {
Children ui.Node
}
</script>
<h1>{ui.PageTitle(ctx)}</h1>
<main>{Children}</main>A page gives its breadcrumbs with Crumbs() []ui.Crumb, read the same way with ui.PageCrumbs(ctx); see a header that follows the page.
Wrong: a context processor variable in Load
<script lang="go">
// pages/_layout.vuka.html
type Layout struct {
Children ui.Node
path string
}
func (l *Layout) Load(ctx context.Context) error {
l.path = request.Path
return nil
}
</script>
<small>{path}</small>
<main>{Children}</main>Right: the variable in the markup
<script lang="go">
// pages/_layout.vuka.html
type Layout struct {
Children ui.Node
}
</script>
<small>{request.Path}</small>
<main>{Children}</main>A context processor variable read in the markup is tracked: on a navigation only the spots reading it render again, and the layout stays. Stored in Load, which runs once, it would keep the first page's, so the layout reloads.
A layout that does need the request (a banner keyed by a query parameter) may keep reading it; the warning says what it costs. See layouts that stay.