🤖 Upgrading templates
This release changes how templates call T and the other locale
functions. Each call takes the page's localizer, $L, first, and each
partial gets it as "L" $L. Every app needs the change, whether it
stores money or not. rastrillo migrate-templates makes most of it for
you, and lists the rest.
See what it would do
Run it on your app with no flags. It changes nothing:
rastrillo migrate-templates .
This is its report on an app written before this release:
internal/notes/templates/edit.html calls 0 dicts 4 wrapped 0 preludes 1
internal/notes/templates/genlayout.html calls 0 dicts 0 wrapped 1 preludes 1
internal/notes/templates/new.html calls 0 dicts 4 wrapped 0 preludes 1
internal/notes/templates/signin.html calls 0 dicts 4 wrapped 1 preludes 1
internal/notes/templates/signup.html calls 0 dicts 4 wrapped 1 preludes 1
internal/notes/templates/status.html calls 0 dicts 0 wrapped 1 preludes 1
dry run: 6 templates; 0 locale calls, 16 dict calls, 4 wrapped calls, 6 preludes
review (if this data is a struct, it needs an L field): internal/notes/templates/genlayout.html: template "content" .Content
review (if this data is a struct, it needs an L field): internal/notes/templates/signin.html: template "form-error" .Error
review (if this data is a struct, it needs an L field): internal/notes/templates/signup.html: template "form-error" .Error
review (if this data is a struct, it needs an L field): internal/notes/templates/status.html: template "job-status" .Content
go: internal/notes/genrender.go:39: function map entry "T"; remove it: the localizer's catalog now serves T; give that catalog to ui.Pages as the locale's T
gen holds generated templates in the old syntax; run rastrillo generate
pending: 6 templates need the automatic rewrite; run with -write
Each file line counts the changes it would make to that file. The
indented lines are the list you work through by hand, below.
rastrillo doctor runs the same report under Templates:.
What it changes
With -write it rewrites your templates in place:
- Every call of
T,Tf,Tbdi,number,displayValue,dateWordsormoneygets$Las its first argument. - Every
{{template "name" dict ...}}gets"L" $L. - Any other data passed to a partial is wrapped as
(withL (DATA) $L), and listed for review. - Every template body that now uses
$Lstarts with{{$L := localizer $}}.
Here is part of a sign-in page, before:
{{define "content"}}
{{template "page-header" dict "Title" "Sign in"}}
{{template "form-error" .Error}}
and after:
{{define "content"}}{{$L := localizer $}}
{{template "page-header" dict "L" $L "Title" "Sign in"}}
{{template "form-error" (withL (.Error) $L)}}
It only inserts, at places the template parser reports, and it parses each result again before writing it. A rewrite that does not check out is not written. Running it twice changes nothing the second time.
Work through the list
review: data passed to a partial got wrapped in withL. That adds
L to a map. A struct cannot gain a field, so if the data is a struct,
give it an L field: embed ui.Localized. Otherwise the partial fails
when it renders.
no data: a {{template "name"}} passes no data at all, so the
partial gets no localizer. Pass it ., or a dict with "L" $L.
refused: the file already uses $L for something else, so it was
left alone. The line names each place. Rename your variable and run the
command again.
go: your Go code registers its own T, or another locale
function, in a template function map, or calls ui.WithT or
ui.FuncsWith. The new templates call T $L "key", which a
one-argument T cannot take. Remove it, and render through
ui.Pages, which gives each language's
catalog to its localizer. A go (review) line is a key the check could
not read as a constant: make it one, or check by hand that it can never
be a locale function's name.
gen holds generated templates in the old syntax: run
rastrillo generate. Generated templates are written in the new syntax
already.
Finish
rastrillo migrate-templates -write .
Then work through the list, run rastrillo generate, and run
rastrillo migrate-templates . again. It exits 1 while anything is
left to do, a pending rewrite or a list item, so it works as a CI check.
When it exits 0, so does the Templates: part of rastrillo doctor,
which exits 6 until then.
If you cannot finish in one go, set Compat: true in your
ui.PagesConfig. A call without $L then renders in your default
language instead of failing, and is logged in capitals. Turn it off
when the command reports nothing.
Read this page as markdown — exact, unstyled, and cheap for an agent to fetch.