diff options
| author | grm <grm@eyesin.space> | 2026-09-14 01:32:25 +0300 |
|---|---|---|
| committer | grm <grm@eyesin.space> | 2026-09-14 01:32:25 +0300 |
| commit | e14a4250efb828262347f5a4bbc4067cd71d885f (patch) | |
| tree | 3fcf6512f3b030b06c818ff4a224677a026d3b1b /internal/web/templates/dashboard | |
| parent | 282d2ab3e0fb3a74f32160a231225773001acd14 (diff) | |
| download | blogspace-e14a4250efb828262347f5a4bbc4067cd71d885f.tar.gz blogspace-e14a4250efb828262347f5a4bbc4067cd71d885f.tar.bz2 blogspace-e14a4250efb828262347f5a4bbc4067cd71d885f.zip | |
Add languages: English and Greek, chosen per blog on the Settings tab
Every blog and its dashboard were hard-wired to English. A blogger can
now pick the language of their blog; it switches the whole dashboard and
the blog's fixed text — post dates, archive months, the RSS link, the
pager, the 404 page — while what the blogger wrote is left alone.
The new internal/i18n package keys translations by the English string,
so an untranslated key renders as English rather than blank, and
TestGreekCatalogComplete scans the templates and handlers to fail when
the Greek catalog misses a key or keeps a stale one. Templates are
compiled once per language with t/tf/date/postdate/month closed over the
language, so they need no data plumbing.
The language lives in settings.language (blog migration 00002), not in
the theme, so "Reset design" does not touch it. Public pages use the
blog's language; management pages use the logged-in user's own blog's,
so a superadmin editing someone else's blog keeps theirs; the login page
follows Accept-Language.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sd8UPWrvyYCLj97JexNw3A
Diffstat (limited to 'internal/web/templates/dashboard')
| -rw-r--r-- | internal/web/templates/dashboard/confirm.html | 14 | ||||
| -rw-r--r-- | internal/web/templates/dashboard/design.html | 178 | ||||
| -rw-r--r-- | internal/web/templates/dashboard/images.html | 14 | ||||
| -rw-r--r-- | internal/web/templates/dashboard/layout.html | 102 | ||||
| -rw-r--r-- | internal/web/templates/dashboard/module_form.html | 28 | ||||
| -rw-r--r-- | internal/web/templates/dashboard/overview.html | 24 | ||||
| -rw-r--r-- | internal/web/templates/dashboard/page_form.html | 18 | ||||
| -rw-r--r-- | internal/web/templates/dashboard/pages.html | 20 | ||||
| -rw-r--r-- | internal/web/templates/dashboard/password.html | 12 | ||||
| -rw-r--r-- | internal/web/templates/dashboard/post_form.html | 20 | ||||
| -rw-r--r-- | internal/web/templates/dashboard/posts.html | 20 | ||||
| -rw-r--r-- | internal/web/templates/dashboard/section_form.html | 40 | ||||
| -rw-r--r-- | internal/web/templates/dashboard/sections.html | 26 | ||||
| -rw-r--r-- | internal/web/templates/dashboard/settings.html | 15 |
14 files changed, 267 insertions, 264 deletions
diff --git a/internal/web/templates/dashboard/confirm.html b/internal/web/templates/dashboard/confirm.html index 8dd0b3a..62bf4a4 100644 --- a/internal/web/templates/dashboard/confirm.html +++ b/internal/web/templates/dashboard/confirm.html @@ -1,16 +1,16 @@ -{{define "title"}}Confirm · Blogspace{{end}} +{{define "title"}}{{t "Confirm"}} · Blogspace{{end}} {{define "content"}} <div class="card narrow"> - <h1>Are you sure?</h1> + <h1>{{t "Are you sure?"}}</h1> {{if .Data.isHome}} - <p>This is the home page; it cannot be deleted. Make another page the home page first.</p> - <p><a class="btn secondary" href="{{.Data.back}}">Back</a></p> + <p>{{t "This is the home page; it cannot be deleted. Make another page the home page first."}}</p> + <p><a class="btn secondary" href="{{.Data.back}}">{{t "Back"}}</a></p> {{else}} - <p>You are about to permanently delete {{.Data.what}}. This cannot be undone.</p> + <p>{{tf "You are about to permanently delete %s. This cannot be undone." .Data.what}}</p> <form method="post" action="{{.Data.action}}"> <input type="hidden" name="_csrf" value="{{.CSRF}}"> - <p class="actionrow"><button type="submit" class="danger">Yes, delete</button> - <a class="btn secondary" href="{{.Data.back}}">Cancel</a></p> + <p class="actionrow"><button type="submit" class="danger">{{t "Yes, delete"}}</button> + <a class="btn secondary" href="{{.Data.back}}">{{t "Cancel"}}</a></p> </form> {{end}} </div> diff --git a/internal/web/templates/dashboard/design.html b/internal/web/templates/dashboard/design.html index 9c2a12f..e961388 100644 --- a/internal/web/templates/dashboard/design.html +++ b/internal/web/templates/dashboard/design.html @@ -1,21 +1,21 @@ -{{define "title"}}Design · {{.Blog.Title}}{{end}} +{{define "title"}}{{t "Design"}} · {{.Blog.Title}}{{end}} {{define "content"}} {{$t := .Data.theme}} <div class="pagehead"> - <h1>Design</h1> - <p class="lead muted">Changes are live as soon as you save; refresh <a href="{{.BlogURL}}" target="_blank">your blog ↗</a> to see them.</p> + <h1>{{t "Design"}}</h1> + <p class="lead muted">{{t "Changes are live as soon as you save; refresh"}} <a href="{{.BlogURL}}" target="_blank">{{t "your blog"}} ↗</a> {{t "to see them."}}</p> </div> -<p class="jumps"><a href="#schemes">Schemes</a><a href="#background">Background</a><a href="#text">Text</a><a href="#header">Header</a><a href="#menu">Menu</a><a href="#posts">Posts</a><a href="#footer">Footer</a><a href="#logo">Logo & icon</a></p> -<p class="muted small">What appears where — header, columns, footer and their modules — is arranged on the <a href="/b/{{.Blog.Subdomain}}/layout">Layout</a> tab.</p> +<p class="jumps"><a href="#schemes">{{t "Schemes"}}</a><a href="#background">{{t "Background"}}</a><a href="#text">{{t "Text"}}</a><a href="#header">{{t "Header"}}</a><a href="#menu">{{t "Menu"}}</a><a href="#posts">{{t "Posts"}}</a><a href="#footer">{{t "Footer"}}</a><a href="#logo">{{t "Logo & icon"}}</a></p> +<p class="muted small">{{t "What appears where — header, columns, footer and their modules — is arranged on the"}} <a href="/b/{{.Blog.Subdomain}}/layout">{{t "Layout"}}</a> {{t "tab."}}</p> <div class="card" id="schemes"> - <h2>Colour schemes</h2> - <p class="muted small">A quick start: applying a scheme sets every colour below and saves immediately. Images, fonts and layout are kept.</p> + <h2>{{t "Colour schemes"}}</h2> + <p class="muted small">{{t "A quick start: applying a scheme sets every colour below and saves immediately. Images, fonts and layout are kept."}}</p> <form method="post" action="/b/{{.Blog.Subdomain}}/design/preset" class="presets"> <input type="hidden" name="_csrf" value="{{.CSRF}}"> - {{range .Data.presets}}<button type="submit" name="preset" value="{{.Key}}" class="preset" title="Apply {{.Name}}"> + {{range .Data.presets}}<button type="submit" name="preset" value="{{.Key}}" class="preset" title="{{tf "Apply %s" (t .Name)}}"> <span class="sw" style="background:{{.HeaderBg}}"></span><span class="sw" style="background:{{.Bg}}"></span><span class="sw" style="background:{{.ContentBg}}"></span><span class="sw" style="background:{{.Link}}"></span> - <span class="pname">{{.Name}}</span> + <span class="pname">{{t .Name}}</span> </button> {{end}} </form> @@ -25,158 +25,158 @@ <input type="hidden" name="_csrf" value="{{.CSRF}}"> <div class="card" id="background"> - <h2>Background</h2> + <h2>{{t "Background"}}</h2> <div class="row"> - <label>Colour<br><input type="color" name="bg_color" value="{{$t.BgColor}}"></label> - <label>Image style<br><select name="bg_mode"> - <option value="cover"{{if eq $t.BgMode "cover"}} selected{{end}}>Stretch to fill</option> - <option value="fixed"{{if eq $t.BgMode "fixed"}} selected{{end}}>Fill, fixed while scrolling</option> - <option value="tile"{{if eq $t.BgMode "tile"}} selected{{end}}>Repeat (tile)</option> + <label>{{t "Colour"}}<br><input type="color" name="bg_color" value="{{$t.BgColor}}"></label> + <label>{{t "Image style"}}<br><select name="bg_mode"> + <option value="cover"{{if eq $t.BgMode "cover"}} selected{{end}}>{{t "Stretch to fill"}}</option> + <option value="fixed"{{if eq $t.BgMode "fixed"}} selected{{end}}>{{t "Fill, fixed while scrolling"}}</option> + <option value="tile"{{if eq $t.BgMode "tile"}} selected{{end}}>{{t "Repeat (tile)"}}</option> </select></label> </div> - {{template "imagepick" (dict "name" "bg_image" "current" $t.BgImage "sub" .Blog.Subdomain "images" .Data.images "label" "Background image")}} + {{template "imagepick" (dict "name" "bg_image" "current" $t.BgImage "sub" .Blog.Subdomain "images" .Data.images "label" (t "Background image"))}} </div> <div class="card" id="text"> - <h2>Text & content area</h2> + <h2>{{t "Text & content area"}}</h2> <div class="row"> - <label>Content background<br><input type="color" name="content_bg" value="{{$t.ContentBg}}"></label> - <label>Text colour<br><input type="color" name="text_color" value="{{$t.TextColor}}"></label> - <label>Link colour<br><input type="color" name="link_color" value="{{$t.LinkColor}}"></label> + <label>{{t "Content background"}}<br><input type="color" name="content_bg" value="{{$t.ContentBg}}"></label> + <label>{{t "Text colour"}}<br><input type="color" name="text_color" value="{{$t.TextColor}}"></label> + <label>{{t "Link colour"}}<br><input type="color" name="link_color" value="{{$t.LinkColor}}"></label> </div> <div class="hoverpick"> <input type="checkbox" name="link_hover_custom" id="link-hover-custom"{{if $t.LinkHover}} checked{{end}}> - <label for="link-hover-custom" class="check">Change colour when the mouse is over a link</label> - <label class="hover-color">Hover colour<br><input type="color" name="link_hover" value="{{if $t.LinkHover}}{{$t.LinkHover}}{{else}}{{$t.LinkColor}}{{end}}"></label> + <label for="link-hover-custom" class="check">{{t "Change colour when the mouse is over a link"}}</label> + <label class="hover-color">{{t "Hover colour"}}<br><input type="color" name="link_hover" value="{{if $t.LinkHover}}{{$t.LinkHover}}{{else}}{{$t.LinkColor}}{{end}}"></label> </div> <div class="row"> - <label>Font<br><select name="font"> + <label>{{t "Font"}}<br><select name="font"> <option value="sans"{{if eq $t.Font "sans"}} selected{{end}}>Sans-serif (Helvetica/Arial)</option> <option value="serif"{{if eq $t.Font "serif"}} selected{{end}}>Serif (Georgia/Times)</option> <option value="mono"{{if eq $t.Font "mono"}} selected{{end}}>Monospace (Courier)</option> </select></label> - <label>Heading font<br><select name="heading_font"> - <option value="same"{{if eq $t.HeadingFont "same"}} selected{{end}}>Same as text</option> + <label>{{t "Heading font"}}<br><select name="heading_font"> + <option value="same"{{if eq $t.HeadingFont "same"}} selected{{end}}>{{t "Same as text"}}</option> <option value="sans"{{if eq $t.HeadingFont "sans"}} selected{{end}}>Sans-serif</option> <option value="serif"{{if eq $t.HeadingFont "serif"}} selected{{end}}>Serif</option> <option value="mono"{{if eq $t.HeadingFont "mono"}} selected{{end}}>Monospace</option> </select></label> - <label>Text size<br><select name="font_size"> - <option value="small"{{if eq $t.FontSize "small"}} selected{{end}}>Small</option> - <option value="normal"{{if eq $t.FontSize "normal"}} selected{{end}}>Normal</option> - <option value="large"{{if eq $t.FontSize "large"}} selected{{end}}>Large</option> + <label>{{t "Text size"}}<br><select name="font_size"> + <option value="small"{{if eq $t.FontSize "small"}} selected{{end}}>{{t "Small"}}</option> + <option value="normal"{{if eq $t.FontSize "normal"}} selected{{end}}>{{t "Normal"}}</option> + <option value="large"{{if eq $t.FontSize "large"}} selected{{end}}>{{t "Large"}}</option> </select></label> - <label>Underline links<br><select name="link_underline"> - <option value="always"{{if eq $t.LinkUnderline "always"}} selected{{end}}>Always</option> - <option value="hover"{{if eq $t.LinkUnderline "hover"}} selected{{end}}>Only on hover</option> - <option value="never"{{if eq $t.LinkUnderline "never"}} selected{{end}}>Never</option> + <label>{{t "Underline links"}}<br><select name="link_underline"> + <option value="always"{{if eq $t.LinkUnderline "always"}} selected{{end}}>{{t "Always"}}</option> + <option value="hover"{{if eq $t.LinkUnderline "hover"}} selected{{end}}>{{t "Only on hover"}}</option> + <option value="never"{{if eq $t.LinkUnderline "never"}} selected{{end}}>{{t "Never"}}</option> </select></label> </div> <div class="row"> - <label>Box style<br><select name="content_style"> - <option value="card"{{if eq $t.ContentStyle "card"}} selected{{end}}>Card (shadow, rounded corners)</option> - <option value="flat"{{if eq $t.ContentStyle "flat"}} selected{{end}}>Flat</option> + <label>{{t "Box style"}}<br><select name="content_style"> + <option value="card"{{if eq $t.ContentStyle "card"}} selected{{end}}>{{t "Card (shadow, rounded corners)"}}</option> + <option value="flat"{{if eq $t.ContentStyle "flat"}} selected{{end}}>{{t "Flat"}}</option> </select></label> - <label>Padding <span class="muted">(inside the box)</span><br><select name="content_padding"> - <option value="compact"{{if eq $t.ContentPadding "compact"}} selected{{end}}>Compact</option> - <option value="normal"{{if eq $t.ContentPadding "normal"}} selected{{end}}>Normal</option> - <option value="roomy"{{if eq $t.ContentPadding "roomy"}} selected{{end}}>Roomy</option> + <label>{{t "Padding"}} <span class="muted">({{t "inside the box"}})</span><br><select name="content_padding"> + <option value="compact"{{if eq $t.ContentPadding "compact"}} selected{{end}}>{{t "Compact"}}</option> + <option value="normal"{{if eq $t.ContentPadding "normal"}} selected{{end}}>{{t "Normal"}}</option> + <option value="roomy"{{if eq $t.ContentPadding "roomy"}} selected{{end}}>{{t "Roomy"}}</option> </select></label> </div> - <p class="muted small">The content spans the whole page; how much of it the posts get is set by the column widths on the <a href="/b/{{.Blog.Subdomain}}/layout#columns">Layout</a> tab.</p> + <p class="muted small">{{t "The content spans the whole page; how much of it the posts get is set by the column widths on the"}} <a href="/b/{{.Blog.Subdomain}}/layout#columns">{{t "Layout"}}</a> {{t "tab."}}</p> </div> <div class="card" id="header"> - <h2>Header</h2> + <h2>{{t "Header"}}</h2> <div class="row"> - <label>Background<br><input type="color" name="header_bg" value="{{$t.HeaderBg}}"></label> - <label>Text colour<br><input type="color" name="header_text" value="{{$t.HeaderText}}"></label> - <label>Alignment<br><select name="header_align"> - <option value="left"{{if eq $t.HeaderAlign "left"}} selected{{end}}>Left</option> - <option value="center"{{if eq $t.HeaderAlign "center"}} selected{{end}}>Centred</option> + <label>{{t "Background"}}<br><input type="color" name="header_bg" value="{{$t.HeaderBg}}"></label> + <label>{{t "Text colour"}}<br><input type="color" name="header_text" value="{{$t.HeaderText}}"></label> + <label>{{t "Alignment"}}<br><select name="header_align"> + <option value="left"{{if eq $t.HeaderAlign "left"}} selected{{end}}>{{t "Left"}}</option> + <option value="center"{{if eq $t.HeaderAlign "center"}} selected{{end}}>{{t "Centred"}}</option> </select></label> - <label>Image height<br><select name="header_image_height"> - <option value="short"{{if eq $t.HeaderImageHeight "short"}} selected{{end}}>Short</option> - <option value="medium"{{if eq $t.HeaderImageHeight "medium"}} selected{{end}}>Medium</option> - <option value="tall"{{if eq $t.HeaderImageHeight "tall"}} selected{{end}}>Tall</option> + <label>{{t "Image height"}}<br><select name="header_image_height"> + <option value="short"{{if eq $t.HeaderImageHeight "short"}} selected{{end}}>{{t "Short"}}</option> + <option value="medium"{{if eq $t.HeaderImageHeight "medium"}} selected{{end}}>{{t "Medium"}}</option> + <option value="tall"{{if eq $t.HeaderImageHeight "tall"}} selected{{end}}>{{t "Tall"}}</option> </select></label> </div> - <p class="muted small">The title, logo and menu are header modules — add, remove and order them on the <a href="/b/{{.Blog.Subdomain}}/layout#header">Layout</a> tab. The banner below is shown across the top of the header whenever one is chosen.</p> - {{template "imagepick" (dict "name" "header_image" "current" $t.HeaderImage "sub" .Blog.Subdomain "images" .Data.images "label" "Header image (banner)")}} + <p class="muted small">{{t "The title, logo and menu are header modules — add, remove and order them on the"}} <a href="/b/{{.Blog.Subdomain}}/layout#header">{{t "Layout"}}</a> {{t "tab."}} {{t "The banner below is shown across the top of the header whenever one is chosen."}}</p> + {{template "imagepick" (dict "name" "header_image" "current" $t.HeaderImage "sub" .Blog.Subdomain "images" .Data.images "label" (t "Header image (banner)"))}} </div> <div class="card" id="menu"> - <h2>Menu</h2> - <p class="muted small">Which links the menu shows, and where it sits, is set on the <a href="/b/{{.Blog.Subdomain}}/layout#menu">Layout</a> tab. Here you choose how it looks.</p> + <h2>{{t "Menu"}}</h2> + <p class="muted small">{{t "Which links the menu shows, and where it sits, is set on the"}} <a href="/b/{{.Blog.Subdomain}}/layout#menu">{{t "Layout"}}</a> {{t "tab."}} {{t "Here you choose how it looks."}}</p> <div class="row"> - <label>Alignment <span class="muted">(menu in the header)</span><br><select name="nav_align"> - <option value="left"{{if eq $t.NavAlign "left"}} selected{{end}}>Left</option> - <option value="center"{{if eq $t.NavAlign "center"}} selected{{end}}>Centred</option> - <option value="right"{{if eq $t.NavAlign "right"}} selected{{end}}>Right</option> + <label>{{t "Alignment"}} <span class="muted">({{t "menu in the header"}})</span><br><select name="nav_align"> + <option value="left"{{if eq $t.NavAlign "left"}} selected{{end}}>{{t "Left"}}</option> + <option value="center"{{if eq $t.NavAlign "center"}} selected{{end}}>{{t "Centred"}}</option> + <option value="right"{{if eq $t.NavAlign "right"}} selected{{end}}>{{t "Right"}}</option> </select></label> - <label>Link style<br><select name="nav_style"> - <option value="normal"{{if eq $t.NavStyle "normal"}} selected{{end}}>Normal</option> - <option value="uppercase"{{if eq $t.NavStyle "uppercase"}} selected{{end}}>Uppercase, spaced</option> + <label>{{t "Link style"}}<br><select name="nav_style"> + <option value="normal"{{if eq $t.NavStyle "normal"}} selected{{end}}>{{t "Normal"}}</option> + <option value="uppercase"{{if eq $t.NavStyle "uppercase"}} selected{{end}}>{{t "Uppercase, spaced"}}</option> </select></label> </div> - <h3>Menu colours</h3> + <h3>{{t "Menu colours"}}</h3> <div class="row"> - <label>Background<br><input type="color" name="nav_bg" value="{{$t.NavBg}}"></label> - <label>Text<br><input type="color" name="nav_text" value="{{$t.NavText}}"></label> + <label>{{t "Background"}}<br><input type="color" name="nav_bg" value="{{$t.NavBg}}"></label> + <label>{{t "Text"}}<br><input type="color" name="nav_text" value="{{$t.NavText}}"></label> </div> <div class="hoverpick"> <input type="checkbox" name="nav_hover_custom" id="nav-hover-custom"{{if $t.NavHover}} checked{{end}}> - <label for="nav-hover-custom" class="check">Change colour when the mouse is over a link</label> - <label class="hover-color">Hover colour<br><input type="color" name="nav_hover" value="{{if $t.NavHover}}{{$t.NavHover}}{{else}}{{$t.NavText}}{{end}}"></label> + <label for="nav-hover-custom" class="check">{{t "Change colour when the mouse is over a link"}}</label> + <label class="hover-color">{{t "Hover colour"}}<br><input type="color" name="nav_hover" value="{{if $t.NavHover}}{{$t.NavHover}}{{else}}{{$t.NavText}}{{end}}"></label> </div> </div> <div class="card" id="posts"> - <h2>Posts & dates</h2> - <label class="check"><input type="checkbox" name="show_dates"{{if $t.ShowDates}} checked{{end}}> Show the date on posts</label> + <h2>{{t "Posts & dates"}}</h2> + <label class="check"><input type="checkbox" name="show_dates"{{if $t.ShowDates}} checked{{end}}> {{t "Show the date on posts"}}</label> <div class="row"> - <label>Date format<br><select name="date_format"> - <option value="long"{{if eq $t.DateFormat "long"}} selected{{end}}>12 September 2026</option> - <option value="short"{{if eq $t.DateFormat "short"}} selected{{end}}>12 Sep 2026</option> - <option value="iso"{{if eq $t.DateFormat "iso"}} selected{{end}}>2026-09-12</option> + <label>{{t "Date format"}}<br><select name="date_format"> + <option value="long"{{if eq $t.DateFormat "long"}} selected{{end}}>{{postdate "long" .Data.today}}</option> + <option value="short"{{if eq $t.DateFormat "short"}} selected{{end}}>{{postdate "short" .Data.today}}</option> + <option value="iso"{{if eq $t.DateFormat "iso"}} selected{{end}}>{{postdate "iso" .Data.today}}</option> </select></label> </div> </div> <div class="card" id="footer"> - <h2>Footer</h2> - <p class="muted small">The footer text, RSS link and other footer modules live on the <a href="/b/{{.Blog.Subdomain}}/layout#footer">Layout</a> tab.</p> + <h2>{{t "Footer"}}</h2> + <p class="muted small">{{t "The footer text, RSS link and other footer modules live on the"}} <a href="/b/{{.Blog.Subdomain}}/layout#footer">{{t "Layout"}}</a> {{t "tab."}}</p> <div class="row"> - <label>Background<br><input type="color" name="footer_bg" value="{{$t.FooterBg}}"></label> - <label>Text colour<br><input type="color" name="footer_color" value="{{$t.FooterColor}}"></label> + <label>{{t "Background"}}<br><input type="color" name="footer_bg" value="{{$t.FooterBg}}"></label> + <label>{{t "Text colour"}}<br><input type="color" name="footer_color" value="{{$t.FooterColor}}"></label> </div> </div> <div class="card" id="logo"> - <h2>Logo & site icon</h2> + <h2>{{t "Logo & site icon"}}</h2> <div class="row"> - <label>Logo size<br><select name="logo_size"> - <option value="small"{{if eq $t.LogoSize "small"}} selected{{end}}>Small (48 px tall)</option> - <option value="medium"{{if eq $t.LogoSize "medium"}} selected{{end}}>Medium (80 px)</option> - <option value="large"{{if eq $t.LogoSize "large"}} selected{{end}}>Large (140 px)</option> + <label>{{t "Logo size"}}<br><select name="logo_size"> + <option value="small"{{if eq $t.LogoSize "small"}} selected{{end}}>{{t "Small (48 px tall)"}}</option> + <option value="medium"{{if eq $t.LogoSize "medium"}} selected{{end}}>{{t "Medium (80 px)"}}</option> + <option value="large"{{if eq $t.LogoSize "large"}} selected{{end}}>{{t "Large (140 px)"}}</option> </select></label> </div> - {{template "imagepick" (dict "name" "logo" "current" $t.Logo "sub" .Blog.Subdomain "images" .Data.images "label" "Logo" "hint" "Shown wherever you place a Logo module (Layout tab); it links to your front page.")}} - {{template "imagepick" (dict "name" "favicon" "current" $t.Favicon "sub" .Blog.Subdomain "images" .Data.images "label" "Favicon" "hint" "The small icon browsers show in the tab. A square PNG or ICO of 32–64 px works best; pick None for the Blogspace icon." "accept" "image/png,image/x-icon,image/gif,image/webp,image/jpeg,.ico")}} + {{template "imagepick" (dict "name" "logo" "current" $t.Logo "sub" .Blog.Subdomain "images" .Data.images "label" (t "Logo") "hint" (t "Shown wherever you place a Logo module (Layout tab); it links to your front page."))}} + {{template "imagepick" (dict "name" "favicon" "current" $t.Favicon "sub" .Blog.Subdomain "images" .Data.images "label" (t "Favicon") "hint" (t "The small icon browsers show in the tab. A square PNG or ICO of 32–64 px works best; pick None for the Blogspace icon.") "accept" "image/png,image/x-icon,image/gif,image/webp,image/jpeg,.ico")}} </div> <div class="savebar"> - <button type="submit">Save design</button> - <a class="btn secondary" href="{{.BlogURL}}" target="_blank">View blog ↗</a> + <button type="submit">{{t "Save design"}}</button> + <a class="btn secondary" href="{{.BlogURL}}" target="_blank">{{t "View blog"}} ↗</a> </div> </form> <details class="help reset"> - <summary>Reset to defaults</summary> - <p>Puts every colour, font and layout option back to how a new blog starts and forgets the chosen images (they stay in your library).</p> + <summary>{{t "Reset to defaults"}}</summary> + <p>{{t "Puts every colour, font and layout option back to how a new blog starts and forgets the chosen images (they stay in your library)."}}</p> <form method="post" action="/b/{{.Blog.Subdomain}}/design/reset"> <input type="hidden" name="_csrf" value="{{.CSRF}}"> - <button type="submit" class="danger">Reset everything</button> + <button type="submit" class="danger">{{t "Reset everything"}}</button> </form> </details> {{end}} diff --git a/internal/web/templates/dashboard/images.html b/internal/web/templates/dashboard/images.html index 2e39531..8b9faa3 100644 --- a/internal/web/templates/dashboard/images.html +++ b/internal/web/templates/dashboard/images.html @@ -1,14 +1,14 @@ -{{define "title"}}Images · {{.Blog.Title}}{{end}} +{{define "title"}}{{t "Images"}} · {{.Blog.Title}}{{end}} {{define "content"}} <div class="pagehead"> - <h1>Images</h1> - <p class="lead muted">Images are stored with your blog. Put one in a post with <em>Insert image</em> in the editor, or copy its line from below.</p> + <h1>{{t "Images"}}</h1> + <p class="lead muted">{{t "Images are stored with your blog. Put one in a post with"}} <em>{{t "Insert image"}}</em> {{t "in the editor, or copy its line from below."}}</p> </div> <div class="card"> <form method="post" action="/b/{{.Blog.Subdomain}}/images/upload" enctype="multipart/form-data"> <input type="hidden" name="_csrf" value="{{.CSRF}}"> - <label>Upload an image <span class="muted">(PNG, JPEG, GIF, WebP or ICO)</span><br><input type="file" name="file" accept="image/*" required></label> - <p class="actionrow"><button type="submit">Upload</button></p> + <label>{{t "Upload an image"}} <span class="muted">({{t "PNG, JPEG, GIF, WebP or ICO"}})</span><br><input type="file" name="file" accept="image/*" required></label> + <p class="actionrow"><button type="submit">{{t "Upload"}}</button></p> </form> </div> <div class="gallery"> @@ -17,8 +17,8 @@ <a href="/b/{{$.Blog.Subdomain}}/media/{{.ID}}" target="_blank"><img src="/b/{{$.Blog.Subdomain}}/media/{{.ID}}" alt="{{.Filename}}"></a> <div class="meta">{{.Filename}} <span class="muted">({{kb .Size}})</span></div> <input class="copy" readonly value="" onclick="this.select()"> - <form method="post" action="/b/{{$.Blog.Subdomain}}/images/{{.ID}}/delete" class="inline"><input type="hidden" name="_csrf" value="{{$.CSRF}}"><button class="mini danger">delete</button></form> + <form method="post" action="/b/{{$.Blog.Subdomain}}/images/{{.ID}}/delete" class="inline"><input type="hidden" name="_csrf" value="{{$.CSRF}}"><button class="mini danger">{{t "delete"}}</button></form> </div> -{{else}}<p class="muted">No images yet.</p>{{end}} +{{else}}<p class="muted">{{t "No images yet."}}</p>{{end}} </div> {{end}} diff --git a/internal/web/templates/dashboard/layout.html b/internal/web/templates/dashboard/layout.html index 229ca0e..48b6778 100644 --- a/internal/web/templates/dashboard/layout.html +++ b/internal/web/templates/dashboard/layout.html @@ -1,86 +1,86 @@ -{{define "title"}}Layout · {{.Blog.Title}}{{end}} +{{define "title"}}{{t "Layout"}} · {{.Blog.Title}}{{end}} {{define "content"}} {{$t := .Data.theme}} {{$u := print "/b/" .Blog.Subdomain "/layout"}} <div class="pagehead"> - <h1>Layout</h1> - <p class="lead muted">Decide what goes where on your blog. Every change here is saved straight away; refresh <a href="{{.BlogURL}}" target="_blank">your blog ↗</a> to see it. Colours and fonts are on the <a href="/b/{{.Blog.Subdomain}}/design">Design</a> tab.</p> + <h1>{{t "Layout"}}</h1> + <p class="lead muted">{{t "Decide what goes where on your blog. Every change here is saved straight away; refresh"}} <a href="{{.BlogURL}}" target="_blank">{{t "your blog"}} ↗</a> {{t "to see it."}} {{t "Colours and fonts are on the"}} <a href="/b/{{.Blog.Subdomain}}/design">{{t "Design"}}</a> {{t "tab."}}</p> </div> -<p class="jumps"><a href="#columns">Columns</a><a href="#header">Header</a><a href="#left">Left column</a><a href="#main">Main content</a><a href="#right">Right column</a><a href="#footer">Footer</a><a href="#menu">Menu</a></p> +<p class="jumps"><a href="#columns">{{t "Columns"}}</a><a href="#header">{{t "Header"}}</a><a href="#left">{{t "Left column"}}</a><a href="#main">{{t "Main content"}}</a><a href="#right">{{t "Right column"}}</a><a href="#footer">{{t "Footer"}}</a><a href="#menu">{{t "Menu"}}</a></p> <div class="card" id="columns"> - <h2>Columns</h2> + <h2>{{t "Columns"}}</h2> <div class="lay"> - <div class="lay-row lay-header{{if not $t.HeaderOn}} off{{end}}">Header{{if not $t.HeaderOn}} (hidden){{end}}</div> + <div class="lay-row lay-header{{if not $t.HeaderOn}} off{{end}}">{{t "Header"}}{{if not $t.HeaderOn}} ({{t "hidden"}}){{end}}</div> <div class="lay-cols"> - <div class="lay-col lay-side{{if not $t.LeftOn}} off{{end}}{{if not (index .Data.areas "left")}} empty{{end}}" style="width:{{$t.LeftWidth}}%">Left {{$t.LeftWidth}}%</div> - <div class="lay-col lay-main" style="width:{{$t.MainWidth}}%">Main content {{$t.MainWidth}}%</div> - <div class="lay-col lay-side{{if not $t.RightOn}} off{{end}}{{if not (index .Data.areas "right")}} empty{{end}}" style="width:{{$t.RightWidth}}%">Right {{$t.RightWidth}}%</div> + <div class="lay-col lay-side{{if not $t.LeftOn}} off{{end}}{{if not (index .Data.areas "left")}} empty{{end}}" style="width:{{$t.LeftWidth}}%">{{t "Left"}} {{$t.LeftWidth}}%</div> + <div class="lay-col lay-main" style="width:{{$t.MainWidth}}%">{{t "Main content"}} {{$t.MainWidth}}%</div> + <div class="lay-col lay-side{{if not $t.RightOn}} off{{end}}{{if not (index .Data.areas "right")}} empty{{end}}" style="width:{{$t.RightWidth}}%">{{t "Right"}} {{$t.RightWidth}}%</div> </div> - <div class="lay-row lay-footer{{if not $t.FooterOn}} off{{end}}">Footer{{if not $t.FooterOn}} (hidden){{end}}</div> + <div class="lay-row lay-footer{{if not $t.FooterOn}} off{{end}}">{{t "Footer"}}{{if not $t.FooterOn}} ({{t "hidden"}}){{end}}</div> </div> <form method="post" action="{{$u}}/widths"> <input type="hidden" name="_csrf" value="{{.CSRF}}"> <div class="row"> - <label>Left column width<br><input type="number" name="left_width" value="{{$t.LeftWidth}}" min="15" max="40" step="5"> %</label> - <label>Right column width<br><input type="number" name="right_width" value="{{$t.RightWidth}}" min="15" max="40" step="5"> %</label> + <label>{{t "Left column width"}}<br><input type="number" name="left_width" value="{{$t.LeftWidth}}" min="15" max="40" step="5"> %</label> + <label>{{t "Right column width"}}<br><input type="number" name="right_width" value="{{$t.RightWidth}}" min="15" max="40" step="5"> %</label> </div> - <p class="muted small">Between 15% and 40% each; the main content takes the rest. A column only appears when it has at least one module; without columns the posts take the whole width. On phones the columns stack: main content first, then the left and right columns, then the footer.</p> - <label class="check"><input type="checkbox" name="keep_columns"{{if $t.KeepColumns}} checked{{end}}> Always keep the columns' space, even when a column is empty or hidden <span class="muted">(the main content then keeps its width and stays centred)</span></label> - <p class="actionrow"><button type="submit">Save columns</button></p> + <p class="muted small">{{t "Between 15% and 40% each; the main content takes the rest. A column only appears when it has at least one module; without columns the posts take the whole width. On phones the columns stack: main content first, then the left and right columns, then the footer."}}</p> + <label class="check"><input type="checkbox" name="keep_columns"{{if $t.KeepColumns}} checked{{end}}> {{t "Always keep the columns' space, even when a column is empty or hidden"}} <span class="muted">({{t "the main content then keeps its width and stays centred"}})</span></label> + <p class="actionrow"><button type="submit">{{t "Save columns"}}</button></p> </form> </div> -{{template "area" (dict "area" "header" "root" . "hint" "The top of every page. Stack the title, a logo and the menu in the order you like. A banner image can be chosen on the Design tab.")}} -{{template "area" (dict "area" "left" "root" . "hint" "A narrow column beside your posts. Good for the menu, an archive or recent posts.")}} +{{template "area" (dict "area" "header" "root" . "hint" (t "The top of every page. Stack the title, a logo and the menu in the order you like. A banner image can be chosen on the Design tab."))}} +{{template "area" (dict "area" "left" "root" . "hint" (t "A narrow column beside your posts. Good for the menu, an archive or recent posts."))}} <div class="card" id="main"> - <div class="cardhead"><h2>Main content</h2></div> - <p class="muted small">Your posts and pages always show here. You can add your own HTML before and after them — an intro box, a newsletter form, a badge…</p> + <div class="cardhead"><h2>{{t "Main content"}}</h2></div> + <p class="muted small">{{t "Your posts and pages always show here. You can add your own HTML before and after them — an intro box, a newsletter form, a badge…"}}</p> <table class="modules"> {{range $area := .Data.areaOrder}}{{$mods := index $.Data.areas $area}} - <tr><th>{{index $.Data.areaNames $area}}</th> + <tr><th>{{t (index $.Data.areaNames $area)}}</th> {{if $mods}}{{$m := index $mods 0}} - <td>{{index $.Data.names $m.Kind}}{{with modsummary $m}} <span class="muted">— {{.}}</span>{{end}}</td> - <td class="nowrap actions"><a href="{{$u}}/modules/{{$m.ID}}/edit">edit</a> <a class="danger" href="{{$u}}/modules/{{$m.ID}}/delete">remove</a></td> + <td>{{t (index $.Data.names $m.Kind)}}{{with modsummary $m}} <span class="muted">— {{.}}</span>{{end}}</td> + <td class="nowrap actions"><a href="{{$u}}/modules/{{$m.ID}}/edit">{{t "edit"}}</a> <a class="danger" href="{{$u}}/modules/{{$m.ID}}/delete">{{t "remove"}}</a></td> {{else}} - <td class="muted">Nothing extra.</td> - <td class="nowrap actions"><form method="post" action="{{$u}}/areas/{{$area}}/add" class="inline"><input type="hidden" name="_csrf" value="{{$.CSRF}}"><input type="hidden" name="kind" value="html"><button class="mini">+ Add custom HTML</button></form></td> + <td class="muted">{{t "Nothing extra."}}</td> + <td class="nowrap actions"><form method="post" action="{{$u}}/areas/{{$area}}/add" class="inline"><input type="hidden" name="_csrf" value="{{$.CSRF}}"><input type="hidden" name="kind" value="html"><button class="mini">+ {{t "Add custom HTML"}}</button></form></td> {{end}} </tr>{{end}} </table> </div> -{{template "area" (dict "area" "right" "root" . "hint" "A narrow column on the other side of your posts. Same choices as the left one.")}} -{{template "area" (dict "area" "footer" "root" . "hint" "The bottom of every page: a copyright line, the RSS link, a list of your pages.")}} +{{template "area" (dict "area" "right" "root" . "hint" (t "A narrow column on the other side of your posts. Same choices as the left one."))}} +{{template "area" (dict "area" "footer" "root" . "hint" (t "The bottom of every page: a copyright line, the RSS link, a list of your pages."))}} <div class="card" id="menu"> - <h2>Menu</h2> - <p class="muted small">The links the Menu module shows, wherever you place it. Pages and outside links can be mixed in any order. Ticking "Show in menu" on a page does the same as adding it here.</p> + <h2>{{t "Menu"}}</h2> + <p class="muted small">{{t "The links the Menu module shows, wherever you place it. Pages and outside links can be mixed in any order. Ticking “Show in menu” on a page does the same as adding it here."}}</p> {{if .Data.menu}}<table class="modules"> {{range .Data.menu}}<tr> <td class="nowrap order"> - <form method="post" action="{{$u}}/menu/{{.ID}}/move" class="inline"><input type="hidden" name="_csrf" value="{{$.CSRF}}"><input type="hidden" name="dir" value="up"><button class="mini" title="Move up">▲</button></form> - <form method="post" action="{{$u}}/menu/{{.ID}}/move" class="inline"><input type="hidden" name="_csrf" value="{{$.CSRF}}"><input type="hidden" name="dir" value="down"><button class="mini" title="Move down">▼</button></form> + <form method="post" action="{{$u}}/menu/{{.ID}}/move" class="inline"><input type="hidden" name="_csrf" value="{{$.CSRF}}"><input type="hidden" name="dir" value="up"><button class="mini" title="{{t "Move up"}}">▲</button></form> + <form method="post" action="{{$u}}/menu/{{.ID}}/move" class="inline"><input type="hidden" name="_csrf" value="{{$.CSRF}}"><input type="hidden" name="dir" value="down"><button class="mini" title="{{t "Move down"}}">▼</button></form> </td> - <td>{{.Text}} {{if .PageID}}<span class="tag">page</span>{{else}}<span class="tag">link</span> <span class="muted small">{{.URL}}</span>{{end}}</td> - <td class="nowrap actions"><form method="post" action="{{$u}}/menu/{{.ID}}/delete" class="inline"><input type="hidden" name="_csrf" value="{{$.CSRF}}"><button class="mini danger">Remove</button></form></td> + <td>{{.Text}} {{if .PageID}}<span class="tag">{{t "page"}}</span>{{else}}<span class="tag">{{t "link"}}</span> <span class="muted small">{{.URL}}</span>{{end}}</td> + <td class="nowrap actions"><form method="post" action="{{$u}}/menu/{{.ID}}/delete" class="inline"><input type="hidden" name="_csrf" value="{{$.CSRF}}"><button class="mini danger">{{t "Remove"}}</button></form></td> </tr>{{end}} - </table>{{else}}<p class="muted">The menu is empty.</p>{{end}} + </table>{{else}}<p class="muted">{{t "The menu is empty."}}</p>{{end}} <div class="cols addrow"> <form method="post" action="{{$u}}/menu/add-page" class="add"> <input type="hidden" name="_csrf" value="{{.CSRF}}"> - <h3>Add a page</h3> - {{if .Data.freePages}}<label>Page<br><select name="page">{{range .Data.freePages}}<option value="{{.ID}}">{{.Title}}</option>{{end}}</select></label> - <button type="submit" class="secondary">Add page</button> - {{else}}<p class="muted small">Every page is already in the menu.</p>{{end}} + <h3>{{t "Add a page"}}</h3> + {{if .Data.freePages}}<label>{{t "Page"}}<br><select name="page">{{range .Data.freePages}}<option value="{{.ID}}">{{.Title}}</option>{{end}}</select></label> + <button type="submit" class="secondary">{{t "Add page"}}</button> + {{else}}<p class="muted small">{{t "Every page is already in the menu."}}</p>{{end}} </form> <form method="post" action="{{$u}}/menu/add-link" class="add"> <input type="hidden" name="_csrf" value="{{.CSRF}}"> - <h3>Add a link</h3> - <label>Text<br><input name="label" maxlength="60" placeholder="My photos"></label> - <label>Address<br><input name="url" maxlength="500" placeholder="https://example.org"></label> - <button type="submit" class="secondary">Add link</button> + <h3>{{t "Add a link"}}</h3> + <label>{{t "Text"}}<br><input name="label" maxlength="60" placeholder="{{t "My photos"}}"></label> + <label>{{t "Address"}}<br><input name="url" maxlength="500" placeholder="https://example.org"></label> + <button type="submit" class="secondary">{{t "Add link"}}</button> </form> </div> </div> @@ -90,24 +90,24 @@ {{define "area"}}{{$r := .root}}{{$area := .area}}{{$u := print "/b/" $r.Blog.Subdomain "/layout"}}{{$on := $r.Data.theme.AreaOn $area}}{{$mods := index $r.Data.areas $area}} <div class="card{{if not $on}} area-off{{end}}" id="{{$area}}"> <div class="cardhead"> - <h2>{{index $r.Data.areaNames $area}}{{if not $on}} <span class="tag off">hidden</span>{{end}}</h2> - <form method="post" action="{{$u}}/areas/{{$area}}/toggle" class="inline switch"><input type="hidden" name="_csrf" value="{{$r.CSRF}}"><button class="mini">{{if $on}}Hide this area{{else}}Show this area{{end}}</button></form> + <h2>{{t (index $r.Data.areaNames $area)}}{{if not $on}} <span class="tag off">{{t "hidden"}}</span>{{end}}</h2> + <form method="post" action="{{$u}}/areas/{{$area}}/toggle" class="inline switch"><input type="hidden" name="_csrf" value="{{$r.CSRF}}"><button class="mini">{{if $on}}{{t "Hide this area"}}{{else}}{{t "Show this area"}}{{end}}</button></form> </div> <p class="muted small">{{.hint}}</p> {{if $mods}}<table class="modules"> {{range $mods}}<tr> <td class="nowrap order"> - <form method="post" action="{{$u}}/modules/{{.ID}}/move" class="inline"><input type="hidden" name="_csrf" value="{{$r.CSRF}}"><input type="hidden" name="dir" value="up"><button class="mini" title="Move up">▲</button></form> - <form method="post" action="{{$u}}/modules/{{.ID}}/move" class="inline"><input type="hidden" name="_csrf" value="{{$r.CSRF}}"><input type="hidden" name="dir" value="down"><button class="mini" title="Move down">▼</button></form> + <form method="post" action="{{$u}}/modules/{{.ID}}/move" class="inline"><input type="hidden" name="_csrf" value="{{$r.CSRF}}"><input type="hidden" name="dir" value="up"><button class="mini" title="{{t "Move up"}}">▲</button></form> + <form method="post" action="{{$u}}/modules/{{.ID}}/move" class="inline"><input type="hidden" name="_csrf" value="{{$r.CSRF}}"><input type="hidden" name="dir" value="down"><button class="mini" title="{{t "Move down"}}">▼</button></form> </td> - <td>{{index $r.Data.names .Kind}}{{with modsummary .}} <span class="muted">— {{.}}</span>{{end}} - {{if and (eq .Kind "logo") (not $r.Data.theme.Logo)}}<span class="tag off">no logo chosen</span> <span class="muted small">pick one on the <a href="/b/{{$r.Blog.Subdomain}}/design#logo">Design</a> tab</span>{{end}}</td> - <td class="nowrap actions">{{if modsettings .Kind}}<a href="{{$u}}/modules/{{.ID}}/edit">edit</a> {{end}}<a class="danger" href="{{$u}}/modules/{{.ID}}/delete">remove</a></td> + <td>{{t (index $r.Data.names .Kind)}}{{with modsummary .}} <span class="muted">— {{.}}</span>{{end}} + {{if and (eq .Kind "logo") (not $r.Data.theme.Logo)}}<span class="tag off">{{t "no logo chosen"}}</span> <span class="muted small">{{t "pick one on the"}} <a href="/b/{{$r.Blog.Subdomain}}/design#logo">{{t "Design"}}</a> {{t "tab."}}</span>{{end}}</td> + <td class="nowrap actions">{{if modsettings .Kind}}<a href="{{$u}}/modules/{{.ID}}/edit">{{t "edit"}}</a> {{end}}<a class="danger" href="{{$u}}/modules/{{.ID}}/delete">{{t "remove"}}</a></td> </tr>{{end}} - </table>{{else}}<p class="muted">Nothing here yet{{if ne $area "header"}} — this area is not shown until you add a module{{end}}.</p>{{end}} + </table>{{else}}<p class="muted">{{if ne $area "header"}}{{t "Nothing here yet — this area is not shown until you add a module."}}{{else}}{{t "Nothing here yet."}}{{end}}</p>{{end}} <form method="post" action="{{$u}}/areas/{{$area}}/add" class="addmod"> <input type="hidden" name="_csrf" value="{{$r.CSRF}}"> - <label>Add a module<br><select name="kind">{{range index $r.Data.kinds $area}}<option value="{{.}}">{{index $r.Data.names .}}</option>{{end}}</select></label> - <button type="submit" class="secondary">Add</button> + <label>{{t "Add a module"}}<br><select name="kind">{{range index $r.Data.kinds $area}}<option value="{{.}}">{{t (index $r.Data.names .)}}</option>{{end}}</select></label> + <button type="submit" class="secondary">{{t "Add"}}</button> </form> </div>{{end}} diff --git a/internal/web/templates/dashboard/module_form.html b/internal/web/templates/dashboard/module_form.html index b63b405..0cd27fa 100644 --- a/internal/web/templates/dashboard/module_form.html +++ b/internal/web/templates/dashboard/module_form.html @@ -2,32 +2,32 @@ {{define "content"}} {{$m := .Data.module}} <div class="card"> - <h1>{{.Data.name}} <span class="muted small">in the {{lower .Data.area}}</span></h1> + <h1>{{.Data.name}} <span class="muted small">{{tf "in the %s" (lower .Data.area)}}</span></h1> <form method="post"> <input type="hidden" name="_csrf" value="{{.CSRF}}"> {{if or (eq $m.Kind "recent") (eq $m.Kind "archive") (eq $m.Kind "sitemap") (and (eq $m.Kind "html") (or (eq $m.Area "left") (eq $m.Area "right") (eq $m.Area "footer")))}} - <label>Heading <span class="muted">(optional)</span><br><input name="title" value="{{$m.Title}}" maxlength="120" placeholder="{{if eq $m.Kind "recent"}}Recent posts{{else if eq $m.Kind "archive"}}Archive{{else if eq $m.Kind "sitemap"}}Pages{{end}}"></label> + <label>{{t "Heading"}} <span class="muted">({{t "optional"}})</span><br><input name="title" value="{{$m.Title}}" maxlength="120" placeholder="{{if eq $m.Kind "recent"}}{{t "Recent posts"}}{{else if eq $m.Kind "archive"}}{{t "Archive"}}{{else if eq $m.Kind "sitemap"}}{{t "Pages"}}{{end}}"></label> {{end}} {{if eq $m.Kind "recent"}} - <div class="row"><label>How many posts<br><select name="count">{{range $n := .Data.counts}}<option value="{{$n}}"{{if eq $n $m.Count}} selected{{end}}>{{$n}}</option>{{end}}</select></label></div> - <p class="muted small">The newest published posts from every page of your blog, newest first.</p> + <div class="row"><label>{{t "How many posts"}}<br><select name="count">{{range $n := .Data.counts}}<option value="{{$n}}"{{if eq $n $m.Count}} selected{{end}}>{{$n}}</option>{{end}}</select></label></div> + <p class="muted small">{{t "The newest published posts from every page of your blog, newest first."}}</p> {{else if eq $m.Kind "archive"}} - <p class="muted small">Every published post grouped by year and month, newest first. Years and months fold open and shut; the latest year starts open.</p> + <p class="muted small">{{t "Every published post grouped by year and month, newest first. Years and months fold open and shut; the latest year starts open."}}</p> {{else if eq $m.Kind "sitemap"}} - <p class="muted small">Links to every page of your blog.</p> + <p class="muted small">{{t "Links to every page of your blog."}}</p> {{else if eq $m.Kind "html"}} <label for="mod-body">HTML</label> - <textarea id="mod-body" name="body" rows="14" class="mono" spellcheck="false" placeholder="<p>Hello!</p>">{{$m.Body}}</textarea> - <p class="muted small">Put into your page exactly as written — embeds, badges and scripts all work. Anything broken here (an unclosed tag, say) can break the page around it, so check your blog after saving. 20 KB at most.</p> + <textarea id="mod-body" name="body" rows="14" class="mono" spellcheck="false" placeholder="<p>{{t "Hello!"}}</p>">{{$m.Body}}</textarea> + <p class="muted small">{{t "Put into your page exactly as written — embeds, badges and scripts all work. Anything broken here (an unclosed tag, say) can break the page around it, so check your blog after saving. 20 KB at most."}}</p> {{else if eq $m.Kind "text"}} - <label for="mod-body">Text</label> - <textarea id="mod-body" name="body" rows="4" placeholder="© 2026 Me">{{$m.Body}}</textarea> - <p class="muted small">Plain text; each line becomes its own paragraph.</p> + <label for="mod-body">{{t "Text"}}</label> + <textarea id="mod-body" name="body" rows="4" placeholder="{{t "© 2026 Me"}}">{{$m.Body}}</textarea> + <p class="muted small">{{t "Plain text; each line becomes its own paragraph."}}</p> {{end}} <p class="actionrow"> - <button type="submit">Save</button> - <a class="btn secondary" href="{{.BlogURL}}" target="_blank">View blog ↗</a> - <a href="/b/{{.Blog.Subdomain}}/layout#{{if or (eq $m.Area "above") (eq $m.Area "below")}}main{{else}}{{$m.Area}}{{end}}">Back to layout</a> + <button type="submit">{{t "Save"}}</button> + <a class="btn secondary" href="{{.BlogURL}}" target="_blank">{{t "View blog"}} ↗</a> + <a href="/b/{{.Blog.Subdomain}}/layout#{{if or (eq $m.Area "above") (eq $m.Area "below")}}main{{else}}{{$m.Area}}{{end}}">{{t "Back to layout"}}</a> </p> </form> </div> diff --git a/internal/web/templates/dashboard/overview.html b/internal/web/templates/dashboard/overview.html index acd539d..e021495 100644 --- a/internal/web/templates/dashboard/overview.html +++ b/internal/web/templates/dashboard/overview.html @@ -1,35 +1,35 @@ {{define "title"}}{{.Blog.Title}} · Blogspace{{end}} {{define "content"}} <h1>{{.Blog.Title}}</h1> -<p class="muted">Your blog is live at <a href="{{.BlogURL}}" target="_blank">{{.BlogURL}}</a>. Every change you save here shows up there as soon as you refresh.</p> +<p class="muted">{{t "Your blog is live at"}} <a href="{{.BlogURL}}" target="_blank">{{.BlogURL}}</a>. {{t "Every change you save here shows up there as soon as you refresh."}}</p> <div class="cols"> <div class="card"> - <h2>Quick actions</h2> - <p><a class="btn" href="/b/{{.Blog.Subdomain}}/posts/new">Write a new post</a></p> - <p><a href="/b/{{.Blog.Subdomain}}/pages/new">Add a page</a> · <a href="/b/{{.Blog.Subdomain}}/announcements/new">Post an announcement</a> · <a href="/b/{{.Blog.Subdomain}}/layout">Arrange the layout</a> · <a href="/b/{{.Blog.Subdomain}}/design">Change the look</a> · <a href="/b/{{.Blog.Subdomain}}/images">Upload images</a></p> + <h2>{{t "Quick actions"}}</h2> + <p><a class="btn" href="/b/{{.Blog.Subdomain}}/posts/new">{{t "Write a new post"}}</a></p> + <p><a href="/b/{{.Blog.Subdomain}}/pages/new">{{t "Add a page"}}</a> · <a href="/b/{{.Blog.Subdomain}}/announcements/new">{{t "Post an announcement"}}</a> · <a href="/b/{{.Blog.Subdomain}}/layout">{{t "Arrange the layout"}}</a> · <a href="/b/{{.Blog.Subdomain}}/design">{{t "Change the look"}}</a> · <a href="/b/{{.Blog.Subdomain}}/images">{{t "Upload images"}}</a></p> </div> <div class="card"> - <h2>Pages</h2> + <h2>{{t "Pages"}}</h2> <ul class="plain"> - {{range .Data.pages}}<li><a href="/b/{{$.Blog.Subdomain}}/posts?page={{.ID}}">{{.Title}}</a> <span class="muted">({{.PostCount}} posts{{if .IsHome}}, home{{end}}{{if not .ShowInNav}}, hidden from menu{{end}})</span></li>{{end}} + {{range .Data.pages}}<li><a href="/b/{{$.Blog.Subdomain}}/posts?page={{.ID}}">{{.Title}}</a> <span class="muted">({{tf "%d posts" .PostCount}}{{if .IsHome}}, {{t "home"}}{{end}}{{if not .ShowInNav}}, {{t "hidden from menu"}}{{end}})</span></li>{{end}} </ul> </div> </div> <div class="card"> - <h2>Latest posts</h2> + <h2>{{t "Latest posts"}}</h2> {{if .Data.posts}} <table> - <tr><th>Title</th><th>Page</th><th>Date</th><th></th></tr> + <tr><th>{{t "Title"}}</th><th>{{t "Page"}}</th><th>{{t "Date"}}</th><th></th></tr> {{range .Data.posts}}<tr> - <td><a href="/b/{{$.Blog.Subdomain}}/posts/{{.ID}}/edit">{{.Title}}</a>{{if not .Published}} <span class="tag">hidden</span>{{end}}</td> + <td><a href="/b/{{$.Blog.Subdomain}}/posts/{{.ID}}/edit">{{.Title}}</a>{{if not .Published}} <span class="tag">{{t "hidden"}}</span>{{end}}</td> <td>{{.PageTitle}}</td> <td>{{date .CreatedAt}}</td> - <td><a href="{{$.BlogURL}}/{{.PageSlug}}/{{.Slug}}" target="_blank">view ↗</a></td> + <td><a href="{{$.BlogURL}}/{{.PageSlug}}/{{.Slug}}" target="_blank">{{t "view"}} ↗</a></td> </tr>{{end}} </table> - <p><a href="/b/{{.Blog.Subdomain}}/posts">All posts</a></p> - {{else}}<p class="muted">No posts yet. <a href="/b/{{.Blog.Subdomain}}/posts/new">Write the first one.</a></p>{{end}} + <p><a href="/b/{{.Blog.Subdomain}}/posts">{{t "All posts"}}</a></p> + {{else}}<p class="muted">{{t "No posts yet."}} <a href="/b/{{.Blog.Subdomain}}/posts/new">{{t "Write the first one."}}</a></p>{{end}} </div> {{end}} diff --git a/internal/web/templates/dashboard/page_form.html b/internal/web/templates/dashboard/page_form.html index 2692449..08c4a43 100644 --- a/internal/web/templates/dashboard/page_form.html +++ b/internal/web/templates/dashboard/page_form.html @@ -1,19 +1,19 @@ -{{define "title"}}{{if .Data.page.ID}}Edit page{{else}}New page{{end}} · {{.Blog.Title}}{{end}} +{{define "title"}}{{if .Data.page.ID}}{{t "Edit page"}}{{else}}{{t "New page"}}{{end}} · {{.Blog.Title}}{{end}} {{define "content"}} <div class="card"> - <h1>{{if .Data.page.ID}}Edit page{{else}}New page{{end}}</h1> + <h1>{{if .Data.page.ID}}{{t "Edit page"}}{{else}}{{t "New page"}}{{end}}</h1> <form method="post" enctype="multipart/form-data"> <input type="hidden" name="_csrf" value="{{.CSRF}}"> - <label>Title<br><input name="title" value="{{.Data.page.Title}}" required maxlength="120"></label> - <label>Address <span class="muted">(leave empty to make one from the title; e.g. <code>about</code> → {{.BlogURL}}/about)</span><br> + <label>{{t "Title"}}<br><input name="title" value="{{.Data.page.Title}}" required maxlength="120"></label> + <label>{{t "Address"}} <span class="muted">({{t "leave empty to make one from the title; e.g."}} <code>about</code> → {{.BlogURL}}/about)</span><br> <input name="slug" value="{{.Data.page.Slug}}" pattern="[a-z0-9]([a-z0-9-]*[a-z0-9])?" maxlength="80"></label> - <label for="ed-intro">Intro text <span class="muted">(Markdown, shown above the posts; optional)</span></label> + <label for="ed-intro">{{t "Intro text"}} <span class="muted">({{t "Markdown, shown above the posts; optional"}})</span></label> {{template "editor" (dict "name" "intro" "value" .Data.page.IntroMD "rows" 8 "tall" false "upload" (print "/b/" .Blog.Subdomain "/images/upload") "csrf" .CSRF)}} - <label class="check"><input type="checkbox" name="show_in_nav"{{if .Data.page.ShowInNav}} checked{{end}}> Show in menu</label> + <label class="check"><input type="checkbox" name="show_in_nav"{{if .Data.page.ShowInNav}} checked{{end}}> {{t "Show in menu"}}</label> <p class="actionrow"> - <button type="submit">Save</button> - {{if .Data.page.ID}}<a class="btn secondary" href="{{.BlogURL}}{{if .Data.page.IsHome}}/{{else}}/{{.Data.page.Slug}}{{end}}" target="_blank">View page ↗</a>{{end}} - <a href="/b/{{.Blog.Subdomain}}/pages">Back to pages</a> + <button type="submit">{{t "Save"}}</button> + {{if .Data.page.ID}}<a class="btn secondary" href="{{.BlogURL}}{{if .Data.page.IsHome}}/{{else}}/{{.Data.page.Slug}}{{end}}" target="_blank">{{t "View page"}} ↗</a>{{end}} + <a href="/b/{{.Blog.Subdomain}}/pages">{{t "Back to pages"}}</a> </p> </form> </div> diff --git a/internal/web/templates/dashboard/pages.html b/internal/web/templates/dashboard/pages.html index eeb09c5..cb40eb4 100644 --- a/internal/web/templates/dashboard/pages.html +++ b/internal/web/templates/dashboard/pages.html @@ -1,25 +1,25 @@ -{{define "title"}}Pages · {{.Blog.Title}}{{end}} +{{define "title"}}{{t "Pages"}} · {{.Blog.Title}}{{end}} {{define "content"}} <div class="pagehead"> - <h1>Pages</h1> - <div class="actions"><a class="btn" href="/b/{{.Blog.Subdomain}}/pages/new">+ New page</a></div> - <p class="lead muted">Each page holds its own list of posts. Which pages are in the menu, and in what order, is set on the <a href="/b/{{.Blog.Subdomain}}/layout#menu">Layout</a> tab.</p> + <h1>{{t "Pages"}}</h1> + <div class="actions"><a class="btn" href="/b/{{.Blog.Subdomain}}/pages/new">+ {{t "New page"}}</a></div> + <p class="lead muted">{{t "Each page holds its own list of posts. Which pages are in the menu, and in what order, is set on the"}} <a href="/b/{{.Blog.Subdomain}}/layout#menu">{{t "Layout"}}</a> {{t "tab."}}</p> </div> <div class="card"> <table> - <tr><th>Order</th><th>Title</th><th>Address</th><th>Posts</th><th></th></tr> + <tr><th>{{t "Order"}}</th><th>{{t "Title"}}</th><th>{{t "Address"}}</th><th>{{t "Posts"}}</th><th></th></tr> {{range .Data.pages}}<tr> <td class="nowrap"> - <form method="post" action="/b/{{$.Blog.Subdomain}}/pages/{{.ID}}/move" class="inline"><input type="hidden" name="_csrf" value="{{$.CSRF}}"><input type="hidden" name="dir" value="up"><button class="mini" title="Move up">▲</button></form> - <form method="post" action="/b/{{$.Blog.Subdomain}}/pages/{{.ID}}/move" class="inline"><input type="hidden" name="_csrf" value="{{$.CSRF}}"><input type="hidden" name="dir" value="down"><button class="mini" title="Move down">▼</button></form> + <form method="post" action="/b/{{$.Blog.Subdomain}}/pages/{{.ID}}/move" class="inline"><input type="hidden" name="_csrf" value="{{$.CSRF}}"><input type="hidden" name="dir" value="up"><button class="mini" title="{{t "Move up"}}">▲</button></form> + <form method="post" action="/b/{{$.Blog.Subdomain}}/pages/{{.ID}}/move" class="inline"><input type="hidden" name="_csrf" value="{{$.CSRF}}"><input type="hidden" name="dir" value="down"><button class="mini" title="{{t "Move down"}}">▼</button></form> </td> <td><a href="/b/{{$.Blog.Subdomain}}/pages/{{.ID}}/edit">{{.Title}}</a> - {{if .IsHome}}<span class="tag">home</span>{{end}}{{if not .ShowInNav}}<span class="tag off">not in menu</span>{{end}}</td> + {{if .IsHome}}<span class="tag">{{t "home"}}</span>{{end}}{{if not .ShowInNav}}<span class="tag off">{{t "not in menu"}}</span>{{end}}</td> <td><a href="{{$.BlogURL}}{{if .IsHome}}/{{else}}/{{.Slug}}{{end}}" target="_blank">{{if .IsHome}}/{{else}}/{{.Slug}}{{end}} ↗</a></td> <td><a href="/b/{{$.Blog.Subdomain}}/posts?page={{.ID}}">{{.PostCount}}</a></td> <td class="nowrap"> - {{if not .IsHome}}<form method="post" action="/b/{{$.Blog.Subdomain}}/pages/{{.ID}}/home" class="inline"><input type="hidden" name="_csrf" value="{{$.CSRF}}"><button class="mini">Make home</button></form> - <a class="danger" href="/b/{{$.Blog.Subdomain}}/pages/{{.ID}}/delete">delete</a>{{end}} + {{if not .IsHome}}<form method="post" action="/b/{{$.Blog.Subdomain}}/pages/{{.ID}}/home" class="inline"><input type="hidden" name="_csrf" value="{{$.CSRF}}"><button class="mini">{{t "Make home"}}</button></form> + <a class="danger" href="/b/{{$.Blog.Subdomain}}/pages/{{.ID}}/delete">{{t "delete"}}</a>{{end}} </td> </tr>{{end}} </table> diff --git a/internal/web/templates/dashboard/password.html b/internal/web/templates/dashboard/password.html index 3e28744..2150a40 100644 --- a/internal/web/templates/dashboard/password.html +++ b/internal/web/templates/dashboard/password.html @@ -1,13 +1,13 @@ -{{define "title"}}Change password · Blogspace{{end}} +{{define "title"}}{{t "Change password"}} · Blogspace{{end}} {{define "content"}} <div class="card narrow"> - <h1>Change password</h1> + <h1>{{t "Change password"}}</h1> <form method="post" action="/account/password"> <input type="hidden" name="_csrf" value="{{.CSRF}}"> - <label>Current password<br><input type="password" name="current" required autocomplete="current-password"></label> - <label>New password<br><input type="password" name="password" required minlength="8" autocomplete="new-password"></label> - <label>Repeat new password<br><input type="password" name="password2" required minlength="8" autocomplete="new-password"></label> - <p class="actionrow"><button type="submit">Change password</button></p> + <label>{{t "Current password"}}<br><input type="password" name="current" required autocomplete="current-password"></label> + <label>{{t "New password"}}<br><input type="password" name="password" required minlength="8" autocomplete="new-password"></label> + <label>{{t "Repeat new password"}}<br><input type="password" name="password2" required minlength="8" autocomplete="new-password"></label> + <p class="actionrow"><button type="submit">{{t "Change password"}}</button></p> </form> </div> {{end}} diff --git a/internal/web/templates/dashboard/post_form.html b/internal/web/templates/dashboard/post_form.html index 8b4a593..af48215 100644 --- a/internal/web/templates/dashboard/post_form.html +++ b/internal/web/templates/dashboard/post_form.html @@ -1,24 +1,24 @@ -{{define "title"}}{{if .Data.post.ID}}Edit post{{else}}New post{{end}} · {{.Blog.Title}}{{end}} +{{define "title"}}{{if .Data.post.ID}}{{t "Edit post"}}{{else}}{{t "New post"}}{{end}} · {{.Blog.Title}}{{end}} {{define "content"}} <div class="card"> - <h1>{{if .Data.post.ID}}Edit post{{else}}New post{{end}}</h1> + <h1>{{if .Data.post.ID}}{{t "Edit post"}}{{else}}{{t "New post"}}{{end}}</h1> <form method="post" enctype="multipart/form-data"> <input type="hidden" name="_csrf" value="{{.CSRF}}"> - <label>Title<br><input name="title" value="{{.Data.post.Title}}" required maxlength="200" autofocus></label> + <label>{{t "Title"}}<br><input name="title" value="{{.Data.post.Title}}" required maxlength="200" autofocus></label> <div class="row"> - <label>Page<br> + <label>{{t "Page"}}<br> <select name="page_id">{{range .Data.pages}}<option value="{{.ID}}"{{if eq .ID $.Data.post.PageID}} selected{{end}}>{{.Title}}</option>{{end}}</select> </label> - <label>Address <span class="muted">(optional, made from the title)</span><br> + <label>{{t "Address"}} <span class="muted">({{t "optional, made from the title"}})</span><br> <input name="slug" value="{{.Data.post.Slug}}" pattern="[a-z0-9]([a-z0-9-]*[a-z0-9])?" maxlength="80"></label> </div> - <label for="ed-body">Content <span class="muted">(Markdown)</span></label> + <label for="ed-body">{{t "Content"}} <span class="muted">(Markdown)</span></label> {{template "editor" (dict "name" "body" "value" .Data.post.BodyMD "rows" 24 "tall" true "upload" (print "/b/" .Blog.Subdomain "/images/upload") "csrf" .CSRF)}} - <label class="check"><input type="checkbox" name="published"{{if .Data.post.Published}} checked{{end}}> Visible on the blog</label> + <label class="check"><input type="checkbox" name="published"{{if .Data.post.Published}} checked{{end}}> {{t "Visible on the blog"}}</label> <p class="actionrow"> - <button type="submit">Save</button> - {{if .Data.post.ID}}<a class="btn secondary" href="{{.BlogURL}}/{{.Data.post.PageSlug}}/{{.Data.post.Slug}}" target="_blank">View post ↗</a>{{end}} - <a href="/b/{{.Blog.Subdomain}}/posts">Back to posts</a> + <button type="submit">{{t "Save"}}</button> + {{if .Data.post.ID}}<a class="btn secondary" href="{{.BlogURL}}/{{.Data.post.PageSlug}}/{{.Data.post.Slug}}" target="_blank">{{t "View post"}} ↗</a>{{end}} + <a href="/b/{{.Blog.Subdomain}}/posts">{{t "Back to posts"}}</a> </p> </form> </div> diff --git a/internal/web/templates/dashboard/posts.html b/internal/web/templates/dashboard/posts.html index c0b7112..3a99a31 100644 --- a/internal/web/templates/dashboard/posts.html +++ b/internal/web/templates/dashboard/posts.html @@ -1,28 +1,28 @@ -{{define "title"}}Posts · {{.Blog.Title}}{{end}} +{{define "title"}}{{t "Posts"}} · {{.Blog.Title}}{{end}} {{define "content"}} <div class="pagehead"> - <h1>Posts</h1> - <div class="actions"><a class="btn" href="/b/{{.Blog.Subdomain}}/posts/new{{if .Data.pageID}}?page={{.Data.pageID}}{{end}}">+ New post</a></div> + <h1>{{t "Posts"}}</h1> + <div class="actions"><a class="btn" href="/b/{{.Blog.Subdomain}}/posts/new{{if .Data.pageID}}?page={{.Data.pageID}}{{end}}">+ {{t "New post"}}</a></div> </div> <form method="get" class="filter"> - <label>Page: + <label>{{t "Page:"}} <select name="page" onchange="this.form.submit()"> - <option value="0">All pages</option> + <option value="0">{{t "All pages"}}</option> {{range .Data.pages}}<option value="{{.ID}}"{{if eq .ID $.Data.pageID}} selected{{end}}>{{.Title}}</option>{{end}} </select></label> - <noscript><button type="submit">Filter</button></noscript> + <noscript><button type="submit">{{t "Filter"}}</button></noscript> </form> <div class="card"> {{if .Data.posts}} <table> - <tr><th>Title</th><th>Page</th><th>Date</th><th></th></tr> + <tr><th>{{t "Title"}}</th><th>{{t "Page"}}</th><th>{{t "Date"}}</th><th></th></tr> {{range .Data.posts}}<tr> - <td><a href="/b/{{$.Blog.Subdomain}}/posts/{{.ID}}/edit">{{.Title}}</a>{{if not .Published}} <span class="tag">hidden</span>{{end}}</td> + <td><a href="/b/{{$.Blog.Subdomain}}/posts/{{.ID}}/edit">{{.Title}}</a>{{if not .Published}} <span class="tag">{{t "hidden"}}</span>{{end}}</td> <td>{{.PageTitle}}</td> <td class="nowrap">{{date .CreatedAt}}</td> - <td class="nowrap"><a href="{{$.BlogURL}}/{{.PageSlug}}/{{.Slug}}" target="_blank">view ↗</a> · <a class="danger" href="/b/{{$.Blog.Subdomain}}/posts/{{.ID}}/delete">delete</a></td> + <td class="nowrap"><a href="{{$.BlogURL}}/{{.PageSlug}}/{{.Slug}}" target="_blank">{{t "view"}} ↗</a> · <a class="danger" href="/b/{{$.Blog.Subdomain}}/posts/{{.ID}}/delete">{{t "delete"}}</a></td> </tr>{{end}} </table> -{{else}}<p class="muted">No posts here yet.</p>{{end}} +{{else}}<p class="muted">{{t "No posts here yet."}}</p>{{end}} </div> {{end}} diff --git a/internal/web/templates/dashboard/section_form.html b/internal/web/templates/dashboard/section_form.html index 7eeaf7c..bc3ba34 100644 --- a/internal/web/templates/dashboard/section_form.html +++ b/internal/web/templates/dashboard/section_form.html @@ -1,35 +1,35 @@ -{{define "title"}}{{if .Data.section.ID}}Edit announcement{{else}}New announcement{{end}} · {{.Blog.Title}}{{end}} +{{define "title"}}{{if .Data.section.ID}}{{t "Edit announcement"}}{{else}}{{t "New announcement"}}{{end}} · {{.Blog.Title}}{{end}} {{define "content"}} {{$s := .Data.section}} <div class="card"> - <h1>{{if $s.ID}}Edit announcement{{else}}New announcement{{end}}</h1> + <h1>{{if $s.ID}}{{t "Edit announcement"}}{{else}}{{t "New announcement"}}{{end}}</h1> <form method="post" enctype="multipart/form-data"> <input type="hidden" name="_csrf" value="{{.CSRF}}"> - <label>Title <span class="muted">(optional)</span><br><input name="title" value="{{$s.Title}}" maxlength="120" autofocus placeholder="Next meeting"></label> + <label>{{t "Title"}} <span class="muted">({{t "optional"}})</span><br><input name="title" value="{{$s.Title}}" maxlength="120" autofocus placeholder="{{t "Next meeting"}}"></label> <div class="row"> - <label>Where<br><select name="column"> - <option value="main"{{if eq $s.Column "main"}} selected{{end}}>Main content (with the posts)</option> - <option value="left"{{if eq $s.Column "left"}} selected{{end}}>Left column</option> - <option value="right"{{if eq $s.Column "right"}} selected{{end}}>Right column</option> + <label>{{t "Where"}}<br><select name="column"> + <option value="main"{{if eq $s.Column "main"}} selected{{end}}>{{t "Main content (with the posts)"}}</option> + <option value="left"{{if eq $s.Column "left"}} selected{{end}}>{{t "Left column"}}</option> + <option value="right"{{if eq $s.Column "right"}} selected{{end}}>{{t "Right column"}}</option> </select></label> - <label>Position<br><select name="position"> - <option value="top"{{if eq $s.Position "top"}} selected{{end}}>At the top</option> - <option value="bottom"{{if eq $s.Position "bottom"}} selected{{end}}>At the bottom</option> + <label>{{t "Position"}}<br><select name="position"> + <option value="top"{{if eq $s.Position "top"}} selected{{end}}>{{t "At the top"}}</option> + <option value="bottom"{{if eq $s.Position "bottom"}} selected{{end}}>{{t "At the bottom"}}</option> </select></label> - <label>Look<br><select name="style"> - <option value="note"{{if eq $s.Style "note"}} selected{{end}}>Highlighted</option> - <option value="warning"{{if eq $s.Style "warning"}} selected{{end}}>Warning</option> - <option value="plain"{{if eq $s.Style "plain"}} selected{{end}}>Plain</option> + <label>{{t "Look"}}<br><select name="style"> + <option value="note"{{if eq $s.Style "note"}} selected{{end}}>{{t "Highlighted"}}</option> + <option value="warning"{{if eq $s.Style "warning"}} selected{{end}}>{{t "Warning"}}</option> + <option value="plain"{{if eq $s.Style "plain"}} selected{{end}}>{{t "Plain"}}</option> </select></label> </div> - <p class="muted small">"Top" of a side column means above its modules, "bottom" below them. If that column is not shown on your blog (see <a href="/b/{{.Blog.Subdomain}}/layout">Layout</a>) the announcement moves to the main content instead.</p> - <label for="ed-body">Text <span class="muted">(Markdown)</span></label> + <p class="muted small">{{t "“Top” of a side column means above its modules, “bottom” below them. If that column is not shown on your blog (see"}} <a href="/b/{{.Blog.Subdomain}}/layout">{{t "Layout"}}</a>) {{t "the announcement moves to the main content instead."}}</p> + <label for="ed-body">{{t "Text"}} <span class="muted">(Markdown)</span></label> {{template "editor" (dict "name" "body" "value" $s.BodyMD "rows" 10 "tall" false "upload" (print "/b/" .Blog.Subdomain "/images/upload") "csrf" .CSRF)}} - <label class="check"><input type="checkbox" name="enabled"{{if $s.Enabled}} checked{{end}}> Shown on the blog</label> + <label class="check"><input type="checkbox" name="enabled"{{if $s.Enabled}} checked{{end}}> {{t "Shown on the blog"}}</label> <p class="actionrow"> - <button type="submit">Save</button> - <a class="btn secondary" href="{{.BlogURL}}" target="_blank">View blog ↗</a> - <a href="/b/{{.Blog.Subdomain}}/announcements">Back to announcements</a> + <button type="submit">{{t "Save"}}</button> + <a class="btn secondary" href="{{.BlogURL}}" target="_blank">{{t "View blog"}} ↗</a> + <a href="/b/{{.Blog.Subdomain}}/announcements">{{t "Back to announcements"}}</a> </p> </form> </div> diff --git a/internal/web/templates/dashboard/sections.html b/internal/web/templates/dashboard/sections.html index 1834229..4d62f29 100644 --- a/internal/web/templates/dashboard/sections.html +++ b/internal/web/templates/dashboard/sections.html @@ -1,29 +1,29 @@ -{{define "title"}}Announcements · {{.Blog.Title}}{{end}} +{{define "title"}}{{t "Announcements"}} · {{.Blog.Title}}{{end}} {{define "content"}} {{$u := print "/b/" .Blog.Subdomain "/announcements"}} <div class="pagehead"> - <h1>Announcements</h1> - <div class="actions"><a class="btn" href="{{$u}}/new">+ New announcement</a></div> - <p class="lead muted">Notices shown on every page and post of your blog — the next meeting, this month's book, a holiday closure. Hide one instead of deleting it if you will need it again.</p> + <h1>{{t "Announcements"}}</h1> + <div class="actions"><a class="btn" href="{{$u}}/new">+ {{t "New announcement"}}</a></div> + <p class="lead muted">{{t "Notices shown on every page and post of your blog — the next meeting, this month's book, a holiday closure. Hide one instead of deleting it if you will need it again."}}</p> </div> <div class="card"> {{if .Data.sections}} <table> - <tr><th>Order</th><th>Announcement</th><th>Where</th><th>Look</th><th></th></tr> + <tr><th>{{t "Order"}}</th><th>{{t "Announcement"}}</th><th>{{t "Where"}}</th><th>{{t "Look"}}</th><th></th></tr> {{range .Data.sections}}<tr{{if not .Enabled}} class="disabled"{{end}}> <td class="nowrap"> - <form method="post" action="{{$u}}/{{.ID}}/move" class="inline"><input type="hidden" name="_csrf" value="{{$.CSRF}}"><input type="hidden" name="dir" value="up"><button class="mini" title="Move up">▲</button></form> - <form method="post" action="{{$u}}/{{.ID}}/move" class="inline"><input type="hidden" name="_csrf" value="{{$.CSRF}}"><input type="hidden" name="dir" value="down"><button class="mini" title="Move down">▼</button></form> + <form method="post" action="{{$u}}/{{.ID}}/move" class="inline"><input type="hidden" name="_csrf" value="{{$.CSRF}}"><input type="hidden" name="dir" value="up"><button class="mini" title="{{t "Move up"}}">▲</button></form> + <form method="post" action="{{$u}}/{{.ID}}/move" class="inline"><input type="hidden" name="_csrf" value="{{$.CSRF}}"><input type="hidden" name="dir" value="down"><button class="mini" title="{{t "Move down"}}">▼</button></form> </td> - <td><a href="{{$u}}/{{.ID}}/edit">{{if .Title}}{{.Title}}{{else}}(untitled){{end}}</a>{{if not .Enabled}}<span class="tag off">hidden</span>{{end}}</td> - <td>{{if eq .Column "main"}}Main content{{else if eq .Column "left"}}Left column{{else}}Right column{{end}}, {{.Position}}</td> - <td>{{if eq .Style "note"}}Highlighted{{else if eq .Style "warning"}}Warning{{else}}Plain{{end}}</td> + <td><a href="{{$u}}/{{.ID}}/edit">{{if .Title}}{{.Title}}{{else}}({{t "untitled"}}){{end}}</a>{{if not .Enabled}}<span class="tag off">{{t "hidden"}}</span>{{end}}</td> + <td>{{if eq .Column "main"}}{{t "Main content"}}{{else if eq .Column "left"}}{{t "Left column"}}{{else}}{{t "Right column"}}{{end}}, {{t .Position}}</td> + <td>{{if eq .Style "note"}}{{t "Highlighted"}}{{else if eq .Style "warning"}}{{t "Warning"}}{{else}}{{t "Plain"}}{{end}}</td> <td class="nowrap"> - <form method="post" action="{{$u}}/{{.ID}}/toggle" class="inline"><input type="hidden" name="_csrf" value="{{$.CSRF}}"><button class="mini">{{if .Enabled}}Hide{{else}}Show{{end}}</button></form> - <a class="danger" href="{{$u}}/{{.ID}}/delete">delete</a> + <form method="post" action="{{$u}}/{{.ID}}/toggle" class="inline"><input type="hidden" name="_csrf" value="{{$.CSRF}}"><button class="mini">{{if .Enabled}}{{t "Hide"}}{{else}}{{t "Show"}}{{end}}</button></form> + <a class="danger" href="{{$u}}/{{.ID}}/delete">{{t "delete"}}</a> </td> </tr>{{end}} </table> -{{else}}<p class="muted">No announcements yet. <a href="{{$u}}/new">Write the first one.</a></p>{{end}} +{{else}}<p class="muted">{{t "No announcements yet."}} <a href="{{$u}}/new">{{t "Write the first one."}}</a></p>{{end}} </div> {{end}} diff --git a/internal/web/templates/dashboard/settings.html b/internal/web/templates/dashboard/settings.html index 53a24c4..9685360 100644 --- a/internal/web/templates/dashboard/settings.html +++ b/internal/web/templates/dashboard/settings.html @@ -1,13 +1,16 @@ -{{define "title"}}Settings · {{.Blog.Title}}{{end}} +{{define "title"}}{{t "Settings"}} · {{.Blog.Title}}{{end}} {{define "content"}} <div class="card narrow"> - <h1>Blog settings</h1> + <h1>{{t "Blog settings"}}</h1> <form method="post" action="/b/{{.Blog.Subdomain}}/settings"> <input type="hidden" name="_csrf" value="{{.CSRF}}"> - <label>Blog title<br><input name="title" value="{{.Blog.Title}}" required maxlength="120"></label> - <label>Tagline <span class="muted">(shown under the title)</span><br><input name="tagline" value="{{.Blog.Tagline}}" maxlength="300"></label> - <p class="muted">Address: <code>{{.BlogURL}}</code>{{if ne .Blog.Subdomain "www"}} — only the administrator can change this{{end}}.</p> - <p class="actionrow"><button type="submit">Save</button></p> + <label>{{t "Blog title"}}<br><input name="title" value="{{.Blog.Title}}" required maxlength="120"></label> + <label>{{t "Tagline"}} <span class="muted">({{t "shown under the title"}})</span><br><input name="tagline" value="{{.Blog.Tagline}}" maxlength="300"></label> + <label>{{t "Language"}} <span class="muted">({{t "of the dashboard, dates and the blog's fixed text"}})</span><br><select name="language"> + {{range .Data.languages}}<option value="{{.Code}}"{{if eq .Code $.Blog.Language}} selected{{end}}>{{.Name}}</option>{{end}} + </select></label> + <p class="muted">{{t "Address:"}} <code>{{.BlogURL}}</code>{{if ne .Blog.Subdomain "www"}} — {{t "only the administrator can change this"}}{{end}}.</p> + <p class="actionrow"><button type="submit">{{t "Save"}}</button></p> </form> </div> {{end}} |
