aboutsummaryrefslogtreecommitdiffstats
path: root/internal/web/templates/dashboard
diff options
context:
space:
mode:
Diffstat (limited to 'internal/web/templates/dashboard')
-rw-r--r--internal/web/templates/dashboard/confirm.html14
-rw-r--r--internal/web/templates/dashboard/design.html178
-rw-r--r--internal/web/templates/dashboard/images.html14
-rw-r--r--internal/web/templates/dashboard/layout.html102
-rw-r--r--internal/web/templates/dashboard/module_form.html28
-rw-r--r--internal/web/templates/dashboard/overview.html24
-rw-r--r--internal/web/templates/dashboard/page_form.html18
-rw-r--r--internal/web/templates/dashboard/pages.html20
-rw-r--r--internal/web/templates/dashboard/password.html12
-rw-r--r--internal/web/templates/dashboard/post_form.html20
-rw-r--r--internal/web/templates/dashboard/posts.html20
-rw-r--r--internal/web/templates/dashboard/section_form.html40
-rw-r--r--internal/web/templates/dashboard/sections.html26
-rw-r--r--internal/web/templates/dashboard/settings.html15
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 &#8599;</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"}} &#8599;</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 &amp; 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 &amp; 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 &amp; 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 &amp; 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 &#8599;</a>
+ <button type="submit">{{t "Save design"}}</button>
+ <a class="btn secondary" href="{{.BlogURL}}" target="_blank">{{t "View blog"}} &#8599;</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="![{{.Filename}}](/media/{{.ID}})" 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 &#8599;</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"}} &#8599;</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">&#9650;</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">&#9660;</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"}}">&#9650;</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"}}">&#9660;</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">&#9650;</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">&#9660;</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"}}">&#9650;</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"}}">&#9660;</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="&lt;p&gt;Hello!&lt;/p&gt;">{{$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="&lt;p&gt;{{t "Hello!"}}&lt;/p&gt;">{{$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 &#8599;</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"}} &#8599;</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> &middot; <a href="/b/{{.Blog.Subdomain}}/announcements/new">Post an announcement</a> &middot; <a href="/b/{{.Blog.Subdomain}}/layout">Arrange the layout</a> &middot; <a href="/b/{{.Blog.Subdomain}}/design">Change the look</a> &middot; <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> &middot; <a href="/b/{{.Blog.Subdomain}}/announcements/new">{{t "Post an announcement"}}</a> &middot; <a href="/b/{{.Blog.Subdomain}}/layout">{{t "Arrange the layout"}}</a> &middot; <a href="/b/{{.Blog.Subdomain}}/design">{{t "Change the look"}}</a> &middot; <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 &#8599;</a></td>
+ <td><a href="{{$.BlogURL}}/{{.PageSlug}}/{{.Slug}}" target="_blank">{{t "view"}} &#8599;</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 &#8599;</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"}} &#8599;</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">&#9650;</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">&#9660;</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"}}">&#9650;</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"}}">&#9660;</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}} &#8599;</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 &#8599;</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"}} &#8599;</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 &#8599;</a> &middot; <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"}} &#8599;</a> &middot; <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 &#8599;</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"}} &#8599;</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">&#9650;</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">&#9660;</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"}}">&#9650;</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"}}">&#9660;</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}}