1
0

Первый шаг к переводу сайта на русский.

This commit is contained in:
Alexander Andreev 2024-09-14 18:36:08 +04:00
parent 50ba6bb74b
commit ad02399301
Signed by: Arav
GPG Key ID: 25969B23DCB5CA34
8 changed files with 37 additions and 24 deletions

View File

@ -2,11 +2,13 @@ package web
import "net/http" import "net/http"
import "github.com/invopop/ctxi18n/i18n"
import "git.arav.su/Arav/dwelling-home/pkg/servicestat" import "git.arav.su/Arav/dwelling-home/pkg/servicestat"
import "git.arav.su/Arav/dwelling-home/pkg/util" import "git.arav.su/Arav/dwelling-home/pkg/util"
templ About(services *servicestat.ServiceList, r *http.Request) { templ About(services *servicestat.ServiceList, r *http.Request) {
@base("About", "About me and my home servers.", "about, me, servcies", "/about", r, aboutHead()) { @base(i18n.T(ctx, "base.section.about"), "About me and my home servers.", "about, me, servcies", "/about", r, aboutHead()) {
<section id="about-me"> <section id="about-me">
<h2>Me</h2> <h2>Me</h2>
<p><b class="highlighted">Who am I?</b> My name is <span class="highlighted">A</span>lexande<span class="highlighted">r</span> <span class="highlighted">A</span>ndree<span class="highlighted">v</span>. I'm a russian guy of age 31 who likes tinkering with computers.</p> <p><b class="highlighted">Who am I?</b> My name is <span class="highlighted">A</span>lexande<span class="highlighted">r</span> <span class="highlighted">A</span>ndree<span class="highlighted">v</span>. I'm a russian guy of age 31 who likes tinkering with computers.</p>

View File

@ -4,14 +4,15 @@ import "time"
import "net/http" import "net/http"
import "git.arav.su/Arav/dwelling-home/pkg/util" import "git.arav.su/Arav/dwelling-home/pkg/util"
import "github.com/invopop/ctxi18n/i18n"
templ Article(title, description, body, urlName string, date time.Time, r *http.Request) { templ Article(title, description, body, urlName string, date time.Time, r *http.Request) {
@base(title + " - Stuff", description, "", "/stuff/article/"+urlName, r, articleHead()) { @base(title + " - " + i18n.T(ctx, "base.section.stuff"), description, "", "/stuff/article/"+urlName, r, articleHead()) {
<article> <article>
<header> <header>
<h2>{ title }</h2> <h2>{ title }</h2>
<div class="menu"> <div class="menu">
<a href="/stuff#articles">Go back to articles list</a> <a href="/stuff#articles">{ i18n.T(ctx, "article.go-back") }</a>
{{ dctz := util.ToClientTimezone(date, r) }} {{ dctz := util.ToClientTimezone(date, r) }}
<time datetime={ dctz.Format("2006-01-02") }>{ dctz.Format("02 January 2006") }</time> <time datetime={ dctz.Format("2006-01-02") }>{ dctz.Format("02 January 2006") }</time>
</div> </div>

View File

@ -3,6 +3,8 @@ package web
import "strings" import "strings"
import "net/http" import "net/http"
import "github.com/invopop/ctxi18n/i18n"
import "git.arav.su/Arav/dwelling-home/internal/version" import "git.arav.su/Arav/dwelling-home/internal/version"
import "git.arav.su/Arav/dwelling-home/pkg/util" import "git.arav.su/Arav/dwelling-home/pkg/util"
@ -37,12 +39,12 @@ templ base(title, description, keywords, canonical string, r *http.Request, head
<text y="7" textLength="360" lengthAdjust="spacingAndGlyphs">Arav's dwelling</text> <text y="7" textLength="360" lengthAdjust="spacingAndGlyphs">Arav's dwelling</text>
<text y="25" textLength="360" lengthAdjust="spacingAndGlyphs">Welcome to my sacred place, wanderer</text> <text y="25" textLength="360" lengthAdjust="spacingAndGlyphs">Welcome to my sacred place, wanderer</text>
</svg> </svg>
{{ mainNavSections := []string{"Stuff", "Mindflow", "About", "Guestbook"} }} {{ mainNavSections := []string{i18n.T(ctx, "base.section.stuff"), i18n.T(ctx, "base.section.mindflow"), i18n.T(ctx, "base.section.about"), i18n.T(ctx, "base.section.guestbook")} }}
{{ mainNavLinks := []templ.SafeURL{"/stuff", "/mindflow", "/about", "/guestbook"} }} {{ mainNavLinks := []templ.SafeURL{"/stuff", "/mindflow", "/about", "/guestbook"} }}
<nav> <nav>
<ul> <ul>
if title != "" { if title != "" {
<li><a href="/">Home</a></li> <li><a href="/">{ i18n.T(ctx, "base.section.home") }</a></li>
} }
for i, s := range mainNavSections { for i, s := range mainNavSections {
if strings.HasSuffix(title, s) { if strings.HasSuffix(title, s) {
@ -53,8 +55,8 @@ templ base(title, description, keywords, canonical string, r *http.Request, head
</ul> </ul>
if title != "" { if title != "" {
<h1> <h1>
if strings.HasSuffix(title, "- Stuff") { if strings.HasSuffix(title, "- " + i18n.T(ctx, "base.section.stuff")) {
Stuff { i18n.T(ctx, "base.section.stuff") }
} else { } else {
{ title } { title }
} }
@ -66,9 +68,9 @@ templ base(title, description, keywords, canonical string, r *http.Request, head
{ children... } { children... }
</main> </main>
<footer> <footer>
<a href="/rss.xml" title="Stay up to date on what's going on.">RSS feed</a> <a href="/rss.xml" title={ i18n.T(ctx, "base.rss-feed-title") }>{ i18n.T(ctx, "base.rss-feed") }</a>
<br/> <br/>
{ version.GetVersion() } &copy; 2017&mdash;2024 Alexander &quot;Arav&quot; Andreev &lt;<a href="mailto:me@arav.su">me@arav.su</a>&gt; <a href="/privacy">Privacy statements</a> { version.GetVersion() } &copy; 2017&mdash;2024 { i18n.T(ctx, "base.copy-author") } &lt;<a href="mailto:me@arav.su">me@arav.su</a>&gt; <a href="/privacy">{ i18n.T(ctx, "base.privacy-statements-link") }</a>
</footer> </footer>
</body> </body>
</html> </html>

View File

@ -6,29 +6,31 @@ import "strings"
import "time" import "time"
import "net/http" import "net/http"
import "github.com/invopop/ctxi18n/i18n"
import "git.arav.su/Arav/justguestbook" import "git.arav.su/Arav/justguestbook"
import "git.arav.su/Arav/dwelling-home/pkg/util" import "git.arav.su/Arav/dwelling-home/pkg/util"
templ Guestbook(captchaID, owner string, entries []*justguestbook.Entry, pageCount, pageCur int64, r *http.Request) { templ Guestbook(captchaID, owner string, entries []*justguestbook.Entry, pageCount, pageCur int64, r *http.Request) {
@base("Guestbook", "This is my guestbook. Welcome.", "guestbook, personal", "/guestbook", r, guestbookHead()) { @base(i18n.T(ctx, "base.section.guestbook"), i18n.T(ctx, "guestbook.description"), "guestbook, personal", "/guestbook", r, guestbookHead()) {
<form id="new-post" action="/api/guestbook" method="POST"> <form id="new-post" action="/api/guestbook" method="POST">
<input type="text" name="name" maxlength="80" placeholder="Name (Anonymous if left blank)"/> <input type="text" name="name" maxlength="80" placeholder={ i18n.T(ctx, "guestbook.form.name") }/>
<input type="text" name="website" maxlength="255" placeholder="Website (optional)"/> <input type="text" name="website" maxlength="255" placeholder={ i18n.T(ctx, "guestbook.form.website") }/>
<textarea name="message" maxlength="4096" placeholder="Your message" required></textarea> <textarea name="message" maxlength="4096" placeholder={ i18n.T(ctx, "guestbook.form.message") } required></textarea>
<span class="checkboxes"> <span class="checkboxes">
<input type="checkbox" name="hide_website" id="hide-website" checked/> <input type="checkbox" name="hide_website" id="hide-website" checked/>
<label for="hide-website">Hide website <small>(only I can see if set)</small></label> <label for="hide-website">{ i18n.T(ctx, "guestbook.form.hide-website-1") } <small>{ i18n.T(ctx, "guestbook.form.hide-website-2") }</small></label>
<br/> <br/>
<small>Use &gt; to make a quote.</small> <small>@templ.Raw(i18n.T(ctx, "guestbook.form.quote-usage"))</small>
</span> </span>
<span class="captcha"> <span class="captcha">
<input type="hidden" name="captcha_id" value={ captchaID }/> <input type="hidden" name="captcha_id" value={ captchaID }/>
<img src={ string(templ.URL(fmt.Sprintf("/api/captcha/%s/image", captchaID))) } alt="CAPTCHA" width="160" height="40"/> <img src={ string(templ.URL(fmt.Sprintf("/api/captcha/%s/image", captchaID))) } alt="CAPTCHA" width="160" height="40"/>
<input type="text" name="captcha_answer" maxlength="6" placeholder="CAPTCHA" required/> <input type="text" name="captcha_answer" maxlength="6" placeholder="CAPTCHA" required/>
<small>Valid for <b>10</b> minutes.</small> <small>@templ.Raw(i18n.T(ctx, "guestbook.form.captcha-validity"))</small>
</span> </span>
<input type="submit" value="Send a post"/> <input type="submit" value={ i18n.T(ctx, "guestbook.form.send-post") }/>
</form> </form>
<section id="posts"> <section id="posts">
for _, entry := range entries { for _, entry := range entries {
@ -39,7 +41,7 @@ templ Guestbook(captchaID, owner string, entries []*justguestbook.Entry, pageCou
if !entry.HideWebsite { if !entry.HideWebsite {
{{ website = entry.Website }} {{ website = entry.Website }}
} }
{ strconv.FormatInt(entry.ID, 10) } by <span class="highlighted">{ entry.Name }</span> <em>{ website }</em> on <time datetime={ entry.Created.Format(time.RFC3339) }>{ created_tz }</time> { strconv.FormatInt(entry.ID, 10) } { i18n.T(ctx, "guestbook.post.by") } <span class="highlighted">{ entry.Name }</span> <em>{ website }</em> { i18n.T(ctx, "guestbook.post.on") } <time datetime={ entry.Created.Format(time.RFC3339) }>{ created_tz }</time>
</header> </header>
for _, line := range strings.Split(entry.Message, "\n") { for _, line := range strings.Split(entry.Message, "\n") {
<p <p
@ -51,7 +53,7 @@ templ Guestbook(captchaID, owner string, entries []*justguestbook.Entry, pageCou
<div class="reply"> <div class="reply">
<header> <header>
{{ reply_created_tz := util.ToClientTimezone(entry.Reply.Created, r).Format("Monday _2 January 2006 15:04:05 -07:00") }} {{ reply_created_tz := util.ToClientTimezone(entry.Reply.Created, r).Format("Monday _2 January 2006 15:04:05 -07:00") }}
Reply by <span class="highlighted">{ owner }</span> in <time datetime={ entry.Reply.Created.Format(time.RFC3339) }>{ reply_created_tz }</time> { i18n.T(ctx, "guestbook.post.reply") } <span class="highlighted">{ owner }</span> { i18n.T(ctx, "guestbook.post.on") } <time datetime={ entry.Reply.Created.Format(time.RFC3339) }>{ reply_created_tz }</time>
</header> </header>
for _, line := range strings.Split(entry.Reply.Message, "\n") { for _, line := range strings.Split(entry.Reply.Message, "\n") {
<p <p
@ -64,7 +66,7 @@ templ Guestbook(captchaID, owner string, entries []*justguestbook.Entry, pageCou
</article> </article>
} }
if len(entries) == 0 { if len(entries) == 0 {
<p class="center">No posts.</p> <p class="center">{ i18n.T(ctx, "guestbook.post.no-posts") }</p>
} }
</section> </section>
if pageCount > 1 { if pageCount > 1 {

View File

@ -31,7 +31,7 @@ templ Index(r *http.Request) {
<section> <section>
<p>Привет, Анон. Я Александр, хожу по интернету под ником Arav и его всякими вариациями. С 2017 года завел у себя домашний сервер в виде третьей малины, а чуть позже добавил ещё один в виде старого ноута, некоторые сервисы могут быть полезны и тебе, они по ссылкам выше. Но если кратко: файловая шара, радио, файловый хостинг с ограниченным временем хранения, ну и git сервер мой, можешь порыться в нем. ;)</p> <p>Привет, Анон. Я Александр, хожу по интернету под ником Arav и его всякими вариациями. С 2017 года завел у себя домашний сервер в виде третьей малины, а чуть позже добавил ещё один в виде старого ноута, некоторые сервисы могут быть полезны и тебе, они по ссылкам выше. Но если кратко: файловая шара, радио, файловый хостинг с ограниченным временем хранения, ну и git сервер мой, можешь порыться в нем. ;)</p>
<p>Изначально завел небольшой сайт на neocities, но быстро стало нехватать всякого (например, шаблонов, чтобы везде одно и то же не менять), потому переехал полностью на свой сервер, а там оставил только ссылки.</p> <p>Изначально завел небольшой сайт на neocities, но быстро стало нехватать всякого (например, шаблонов, чтобы везде одно и то же не менять), потому переехал полностью на свой сервер, а там оставил только ссылки.</p>
<p>Да, я веду сайт изначально на английском чисто для большего охвата аудитории и практики, ибо как ни крути, а английский не скоро перестанет быть доминирующим языком международного общения, да и тупо лень вести на двух языках сайт, да и технически так и не решил пока как локализовать. Однако, один посетитель справедливо пожурил меня, что хотя бы на главной русский должен быть. :)</p> <p>Да, я веду сайт изначально на английском чисто для большего охвата аудитории и практики, ибо как ни крути, а английский не скоро перестанет быть доминирующим языком международного общения, да и было тупо лень на двух языках вести сайт. :)</p>
</section> </section>
} }
} }

View File

@ -4,11 +4,13 @@ import "net/http"
import "strings" import "strings"
import "time" import "time"
import "github.com/invopop/ctxi18n/i18n"
import "git.arav.su/Arav/dwelling-home/pkg/mindflow" import "git.arav.su/Arav/dwelling-home/pkg/mindflow"
import "git.arav.su/Arav/dwelling-home/pkg/util" import "git.arav.su/Arav/dwelling-home/pkg/util"
templ Mindflow(posts []mindflow.Post, categories []mindflow.Category, r *http.Request) { templ Mindflow(posts []mindflow.Post, categories []mindflow.Category, r *http.Request) {
@base("Mindflow", "Updates on my infrastructure, my very important opinions and thoughts.", "updates, thoughts, opinions, blog, diary", "/mindflow", r, mindflowHead()) { @base(i18n.T(ctx, "base.section.mindflow"), "Updates on my infrastructure, my very important opinions and thoughts.", "updates, thoughts, opinions, blog, diary", "/mindflow", r, mindflowHead()) {
<p class="center">Here I post updates on websites and infrastructure, my very important opinions and thoughts no one asked for. If you'd like to subscribe to this bullshittery then <a href="/rss.xml">RSS feed</a> at your service. :)</p> <p class="center">Here I post updates on websites and infrastructure, my very important opinions and thoughts no one asked for. If you'd like to subscribe to this bullshittery then <a href="/rss.xml">RSS feed</a> at your service. :)</p>
<section> <section>
<menu id="filter" class="hidden"> <menu id="filter" class="hidden">

View File

@ -2,10 +2,12 @@ package web
import "net/http" import "net/http"
import "github.com/invopop/ctxi18n/i18n"
import "git.arav.su/Arav/dwelling-home/pkg/util" import "git.arav.su/Arav/dwelling-home/pkg/util"
templ Privacy(r *http.Request) { templ Privacy(r *http.Request) {
@base("Privacy", "Privacy statements for all of my services.", "privacy statements", "/privacy", r, nil) { @base(i18n.T(ctx, "base.section.privacy"), "Privacy statements for all of my services.", "privacy statements", "/privacy", r, nil) {
<section id="privacy"> <section id="privacy">
<h2>Privacy statements</h2> <h2>Privacy statements</h2>
<h3>General data</h3> <h3>General data</h3>

View File

@ -2,12 +2,14 @@ package web
import "net/http" import "net/http"
import "github.com/invopop/ctxi18n/i18n"
import "git.arav.su/Arav/dwelling-home/pkg/util" import "git.arav.su/Arav/dwelling-home/pkg/util"
templ Stuff(r *http.Request) { templ Stuff(r *http.Request) {
{{ gitSite := util.GetServiceByHost(r.Host, util.ServiceGit) }} {{ gitSite := util.GetServiceByHost(r.Host, util.ServiceGit) }}
@base("Stuff", "Here I share my programs, scripts, articles, may be other stuff.", "articles, programs, personal projects, own music", "/stuff", r, nil) { @base(i18n.T(ctx, "base.section.stuff"), "Here I share my programs, scripts, articles, may be other stuff.", "articles, programs, personal projects, own music", "/stuff", r, nil) {
<p class="center">Here lies everything I've made that I'm willing to share.</p> <p class="center">Here lies everything I've made that I'm willing to share.</p>
<section id="articles"> <section id="articles">
<h2>Articles</h2> <h2>Articles</h2>