aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/site/html.go46
-rw-r--r--cmd/site/i18n.go46
-rw-r--r--cmd/site/locale.go97
-rw-r--r--cmd/site/main.go41
-rw-r--r--go.mod7
-rw-r--r--go.sum10
-rw-r--r--locales/en.json43
-rw-r--r--locales/tp.json43
-rw-r--r--templates/base.html4
-rw-r--r--templates/blogindex.html8
-rw-r--r--templates/blogpost.html10
-rw-r--r--templates/contact.html16
-rw-r--r--templates/error.html2
-rw-r--r--templates/index.html19
-rw-r--r--templates/resume.html4
15 files changed, 327 insertions, 69 deletions
diff --git a/cmd/site/html.go b/cmd/site/html.go
index f42b947..1037baf 100644
--- a/cmd/site/html.go
+++ b/cmd/site/html.go
@@ -19,29 +19,39 @@ func logTemplateTime(name string, from time.Time) {
func (s *Site) renderTemplatePage(templateFname string, data interface{}) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer logTemplateTime(templateFname, time.Now())
- s.tlock.RLock()
- defer s.tlock.RUnlock()
- var t *template.Template
- var err error
-
- if s.templates[templateFname] == nil {
- t, err = template.ParseFiles("templates/base.html", "templates/"+templateFname)
+ getTranslation := func(group, key string, vals ...interface{}) string {
+ var lc locale
+ var ok bool
+ locale, err := GetPreferredLocale(r)
if err != nil {
- w.WriteHeader(http.StatusInternalServerError)
- ln.Error(context.Background(), err, ln.F{"action": "renderTemplatePage", "page": templateFname})
- fmt.Fprintf(w, "error: %v", err)
+ ln.Error(r.Context(), err)
+ lc = s.t.locales["en"]
+ goto overwith
}
- ln.Log(context.Background(), ln.F{"action": "loaded_new_template", "fname": templateFname})
+ lc, ok = s.t.Get(locale.Lang)
+ if !ok {
+ ln.Log(r.Context(), ln.F{"msg": "unknown language requested", "lang": locale.Lang, "header": r.Header.Get("Accept-Language")})
+ lc = s.t.locales["en"]
+ goto overwith
+ }
- s.tlock.RUnlock()
- s.tlock.Lock()
- s.templates[templateFname] = t
- s.tlock.Unlock()
- s.tlock.RLock()
- } else {
- t = s.templates[templateFname]
+ overwith:
+ return lc.Value(group, key, vals...)
+ }
+ funcMap := template.FuncMap{
+ "trans": getTranslation,
+ }
+
+ var t *template.Template = template.New(templateFname).Funcs(funcMap)
+ var err error
+
+ t, err = t.ParseFiles("templates/base.html", "templates/"+templateFname)
+ if err != nil {
+ w.WriteHeader(http.StatusInternalServerError)
+ ln.Error(context.Background(), err, ln.F{"action": "renderTemplatePage", "page": templateFname})
+ fmt.Fprintf(w, "error: %v", err)
}
err = t.Execute(w, data)
diff --git a/cmd/site/i18n.go b/cmd/site/i18n.go
new file mode 100644
index 0000000..6c8fc92
--- /dev/null
+++ b/cmd/site/i18n.go
@@ -0,0 +1,46 @@
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+)
+
+type locale map[string]map[string]string
+
+func (l locale) Value(group, key string, args ...interface{}) string {
+ sg, ok := l[group]
+ if !ok {
+ return "no group " + group
+ }
+
+ result, ok := sg[key]
+ if !ok {
+ return fmt.Sprintf("in group %s, no key %s", group, key)
+ }
+
+ return fmt.Sprintf(result, args...)
+}
+
+type translations struct {
+ locales map[string]locale
+}
+
+func (t *translations) LoadLocale(name string, r io.Reader) error {
+ l := locale{}
+ d := json.NewDecoder(r)
+ err := d.Decode(&l)
+ if err == nil {
+ t.locales[name] = l
+ }
+ return err
+}
+
+func (t *translations) Get(name string) (locale, bool) {
+ l, ok := t.locales[name]
+ if !ok {
+ return nil, false
+ }
+
+ return l, ok
+}
diff --git a/cmd/site/locale.go b/cmd/site/locale.go
new file mode 100644
index 0000000..a65034a
--- /dev/null
+++ b/cmd/site/locale.go
@@ -0,0 +1,97 @@
+package main
+
+import (
+ "errors"
+ "net/http"
+ "strconv"
+ "strings"
+)
+
+// Locale is locale value from the Accept-Language header in request
+type Locale struct {
+ Lang, Country string
+ Qual float64
+}
+
+// Name returns the locale value in 'lang' or 'lang_country' format
+// eg: de_DE, en_US, gb
+func (l *Locale) Name() string {
+ if len(l.Country) > 0 {
+ return l.Lang + "_" + l.Country
+ }
+ return l.Lang
+}
+
+// ParseLocale creates a Locale from a locale string
+func ParseLocale(locale string) Locale {
+ locsplt := strings.Split(locale, "_")
+ resp := Locale{}
+ resp.Lang = locsplt[0]
+ if len(locsplt) > 1 {
+ resp.Country = locsplt[1]
+ }
+ return resp
+}
+
+const (
+ acceptLanguage = "Accept-Language"
+)
+
+func supportedLocales(alstr string) []Locale {
+ locales := make([]Locale, 0)
+ alstr = strings.Replace(alstr, " ", "", -1)
+ if alstr == "" {
+ return locales
+ }
+ al := strings.Split(alstr, ",")
+ for _, lstr := range al {
+ locales = append(locales, Locale{
+ Lang: parseLang(lstr),
+ Country: parseCountry(lstr),
+ Qual: parseQual(lstr),
+ })
+ }
+ return locales
+}
+
+// GetLocales returns supported locales for the given requet
+func GetLocales(r *http.Request) []Locale {
+ return supportedLocales(r.Header.Get(acceptLanguage))
+}
+
+// GetPreferredLocale return preferred locale for the given reuqest
+// returns error if there is no preferred locale
+func GetPreferredLocale(r *http.Request) (*Locale, error) {
+ locales := GetLocales(r)
+ if len(locales) == 0 {
+ return &Locale{}, errors.New("No locale found")
+ }
+ return &locales[0], nil
+}
+
+func parseLang(val string) string {
+ locale := strings.Split(val, ";")[0]
+ lang := strings.Split(locale, "-")[0]
+ return lang
+}
+
+func parseCountry(val string) string {
+ locale := strings.Split(val, ";")[0]
+ spl := strings.Split(locale, "-")
+ if len(spl) > 1 {
+ return spl[1]
+ }
+ return ""
+}
+
+func parseQual(val string) float64 {
+ spl := strings.Split(val, ";")
+ if len(spl) > 1 {
+ qual, err := strconv.ParseFloat(strings.Split(spl[1], "=")[1], 64)
+ if err != nil {
+ return 1
+ }
+ return qual
+ }
+ return 1
+}
diff --git a/cmd/site/main.go b/cmd/site/main.go
index e9b4d21..83cbeb2 100644
--- a/cmd/site/main.go
+++ b/cmd/site/main.go
@@ -9,7 +9,6 @@ import (
"path/filepath"
"sort"
"strings"
- "sync"
"time"
"github.com/Xe/jsonfeed"
@@ -46,10 +45,8 @@ type Site struct {
mux *http.ServeMux
- templates map[string]*template.Template
- tlock sync.RWMutex
-
segment analytics.Client
+ t *translations
}
func (s *Site) ServeHTTP(w http.ResponseWriter, r *http.Request) {
@@ -78,31 +75,49 @@ func Build() (*Site, error) {
Date string
}
+ t := &translations{
+ locales: map[string]locale{},
+ }
+
+ for _, lang := range []string{"en", "tp"} {
+ fin, err := os.Open(filepath.Join("locales", lang+".json"))
+ if err != nil {
+ return nil, err
+ }
+ defer fin.Close()
+
+ err = t.LoadLocale(lang, fin)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ l := t.locales["en"]
+
s := &Site{
rssFeed: &feeds.Feed{
- Title: "Christine Dodrill's Blog",
+ Title: l.Value("blog", "title"),
Link: &feeds.Link{Href: "https://christine.website/blog"},
- Description: "My blog posts and rants about various technology things.",
+ Description: l.Value("blog", "description"),
Author: &feeds.Author{Name: "Christine Dodrill", Email: "me@christine.website"},
Created: bootTime,
- Copyright: "This work is copyright Christine Dodrill. My viewpoints are my own and not the view of any employer past, current or future.",
+ Copyright: l.Value("meta", "rss_copyright"),
},
jsonFeed: &jsonfeed.Feed{
Version: jsonfeed.CurrentVersion,
- Title: "Christine Dodrill's Blog",
+ Title: l.Value("blog", "title"),
HomePageURL: "https://christine.website",
FeedURL: "https://christine.website/blog.json",
- Description: "My blog posts and rants about various technology things.",
- UserComment: "This is a JSON feed of my blogposts. For more information read: https://jsonfeed.org/version/1",
+ Description: l.Value("blog", "description"),
+ UserComment: l.Value("meta", "json_feed"),
Icon: icon,
Favicon: icon,
Author: jsonfeed.Author{
- Name: "Christine Dodrill",
+ Name: l.Value("header", "name"),
Avatar: icon,
},
},
- mux: http.NewServeMux(),
- templates: map[string]*template.Template{},
+ mux: http.NewServeMux(),
}
if wk := os.Getenv("SEGMENT_WRITE_KEY"); wk != "" {
diff --git a/go.mod b/go.mod
index ce5e6d5..39b8f84 100644
--- a/go.mod
+++ b/go.mod
@@ -1,18 +1,17 @@
module github.com/Xe/site
require (
- github.com/GeertJohan/go.rice v0.0.0-20170420135705-c02ca9a983da // indirect
github.com/Xe/gopreload v0.0.0-20170326043426-a00a8beb369c
github.com/Xe/jsonfeed v0.0.0-20170520170432-e21591505612
github.com/Xe/ln v0.0.0-20170921000907-466e05b2ef3e
- github.com/daaku/go.zipexe v0.0.0-20150329023125-a5fe2436ffcb // indirect
+ github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect
+ github.com/davecgh/go-spew v1.1.1 // indirect
github.com/google/gops v0.3.2
github.com/gorilla/feeds v1.0.0
- github.com/jtolds/qod v0.0.0-20170925014538-3abb44dfc7ba // indirect
github.com/kardianos/osext v0.0.0-20170510131534-ae77be60afb1 // indirect
github.com/kr/pretty v0.1.0 // indirect
- github.com/magefile/mage v0.0.0-20171025021237-ab3ca2f6f855 // indirect
github.com/pkg/errors v0.8.0 // indirect
+ github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/russross/blackfriday v0.0.0-20170806171014-cadec560ec52
github.com/segmentio/backo-go v0.0.0-20160424052352-204274ad699c // indirect
github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95 // indirect
diff --git a/go.sum b/go.sum
index dc390b8..15b9853 100644
--- a/go.sum
+++ b/go.sum
@@ -1,17 +1,17 @@
-github.com/GeertJohan/go.rice v0.0.0-20170420135705-c02ca9a983da/go.mod h1:DgrzXonpdQbfN3uYaGz1EG4Sbhyum/MMIn6Cphlh2bw=
github.com/Xe/gopreload v0.0.0-20170326043426-a00a8beb369c h1:lqTJqaoonxgJMvvfl1ukr/3qCEGWC0nQxzPezbJrhHs=
github.com/Xe/gopreload v0.0.0-20170326043426-a00a8beb369c/go.mod h1:0aSWHJguPNHo6zlU7A4Ktua1A/VUr5Jdr1QZ2amOkAQ=
github.com/Xe/jsonfeed v0.0.0-20170520170432-e21591505612 h1:5cPld6YTMozzm3lK9VCnOErgoFbADM2hZc4KDu0YNKs=
github.com/Xe/jsonfeed v0.0.0-20170520170432-e21591505612/go.mod h1:UKXAbYA/G9yE+cPbpfiP7FlT6Kr3N2mbEjQEJ9hT004=
github.com/Xe/ln v0.0.0-20170921000907-466e05b2ef3e h1:uMC/C/zBov+PItx2c6Vax4lt37X+2V5X7NWRcXsxuzE=
github.com/Xe/ln v0.0.0-20170921000907-466e05b2ef3e/go.mod h1:hDOCtu3XM9SVMB0UHBilUvRbZ0JKMI7IDbvBzwclIb0=
-github.com/daaku/go.zipexe v0.0.0-20150329023125-a5fe2436ffcb/go.mod h1:U0vRfAucUOohvdCxt5MWLF+TePIL0xbCkbKIiV8TQCE=
-github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
+github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY=
+github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/gops v0.3.2 h1:n9jMkrye8dh3WQ0IxG5dzLRIhQeZDZoGaj0D7T7x7hQ=
github.com/google/gops v0.3.2/go.mod h1:pMQgrscwEK/aUSW1IFSaBPbJX82FPHWaSoJw1axQfD0=
github.com/gorilla/feeds v1.0.0 h1:EbkEvaYf+PXhYNHS20heBG7Rl2X6Zy8l11ZBWAHkWqE=
github.com/gorilla/feeds v1.0.0/go.mod h1:Nk0jZrvPFZX1OBe5NPiddPw7CfwF6Q9eqzaBbaightA=
-github.com/jtolds/qod v0.0.0-20170925014538-3abb44dfc7ba/go.mod h1:CC0XsLGDIrizqHTsUEJh89QHzv2u2mix/O9xl4+LqSw=
github.com/kardianos/osext v0.0.0-20170510131534-ae77be60afb1 h1:PJPDf8OUfOK1bb/NeTKd4f1QXZItOX389VN3B6qC8ro=
github.com/kardianos/osext v0.0.0-20170510131534-ae77be60afb1/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
@@ -19,10 +19,10 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
-github.com/magefile/mage v0.0.0-20171025021237-ab3ca2f6f855/go.mod h1:IUDi13rsHje59lecXokTfGX0QIzO45uVPlXnJYsXepA=
github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday v0.0.0-20170806171014-cadec560ec52 h1:xZ0R4UuR0EDx7m0OmvsqZaomfqCeYJ/PyLm94WLhnIM=
github.com/russross/blackfriday v0.0.0-20170806171014-cadec560ec52/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/segmentio/backo-go v0.0.0-20160424052352-204274ad699c h1:rsRTAcCR5CeNLkvgBVSjQoDGRRt6kggsE6XYBqCv2KQ=
diff --git a/locales/en.json b/locales/en.json
new file mode 100644
index 0000000..4e64a91
--- /dev/null
+++ b/locales/en.json
@@ -0,0 +1,43 @@
+{
+ "header": {
+ "name": "Christine Dodrill",
+ "blog": "Blog",
+ "contact": "Contact",
+ "resume": "Resume"
+ },
+ "meta": {
+ "copyright": "Copyright %s Christine Dodrill. Any and all opinions listed here are my own, not my employer's.",
+ "rss_copyright": "This work is copyright Christine Dodrill. My viewpoints are my own and not the view of any employer past, current or future.",
+ "json_feed": "This is a JSON feed of my blogposts. For more information, read: https://jsonfeed.org/version/1"
+ },
+ "index": {
+ "contact_me": "Contact Me",
+ "title": "Web and Backend Services Devops Specialist",
+ "skills": "Skills",
+ "highlighted_projects": "Highlighted Projects"
+ },
+ "blog": {
+ "index_title": "Blogposts",
+ "blogroll": "Other Blogs I Find Interesting",
+ "description": "My blog posts and rants about various technology things.",
+ "title": "Christine Dodrill's Blog",
+ "posted_on": "Posted on %s",
+ "read_this": "Read Post",
+ "disclaimer": "Content posted on %s, opinions and preferences of the author may have changed since then."
+ },
+ "contact": {
+ "header": "Contact Information",
+ "email": "Email",
+ "social_media": "Social Media",
+ "other_info": "Other Information",
+ "donations": "To send me donations, my bitcoin address is: ",
+ "irc_comment": "I am on many IRC networks. On Freenode I am using the nick Xe but elsewhere I will use the nick Xena or Cadey."
+ },
+ "error": {
+ "title": "Error",
+ "post_not_found": "no such post found: %s"
+ },
+ "resume": {
+ "plaintext": "Plain-text version of this resume here"
+ }
+}
diff --git a/locales/tp.json b/locales/tp.json
new file mode 100644
index 0000000..e1ef9b9
--- /dev/null
+++ b/locales/tp.json
@@ -0,0 +1,43 @@
+{
+ "header": {
+ "name": "jan Wisi Totiwi",
+ "blog": "lipu sona",
+ "contact": "lipu toki",
+ "resume": "lipu pali mi"
+ },
+ "meta": {
+ "copyright": "lipu ni li pali e jan Wisi Totiwi pi suli %s. sina pali ala e ni. tenpo ale la nasin sona mi li nasin sona ala pi kulupu lawa mi.",
+ "rss_copyright": "lipu ni li pali e jan Wisi Totiwi. sina pali ala e ni. tenpo ale la nasin sona mi li nasin sona ala pi kulupu lawa mi.",
+ "json_feed": "lipu ni li lipu Sason Pe. sina wile sona la sina lukin e lipu: https://jsonfeed.org/version/1"
+ },
+ "index": {
+ "contact_me": "toki e mi",
+ "title": "jan pali e ilo suli",
+ "skills": "kepeken pali e mi",
+ "highlighted_projects": "pali musi e mi"
+ },
+ "blog": {
+ "index_title": "lipu sona",
+ "blogroll": "lipu sona pi jan ante",
+ "description": "lipu ni li jan Wisi Totiwi pi lipu sona. lipu sona ni li ilo pona li ilo sona.",
+ "title": "jan Wisi Totiwi pi lipu sona",
+ "posted_on": "tenpo pi %s",
+ "read_this": "lukin e ni",
+ "disclaimer": "tenpo %s la lipu ni li pali. tenpo ni la jan Wisi Totiwi li ken nasin sona ante."
+ },
+ "contact": {
+ "header": "lipu toki e mi",
+ "email": "ilo toki",
+ "social_media": "kalama ilo toki",
+ "other_info": "lipu ante",
+ "donations": "ken la sina pana mani e mi. sina wile kepeken lipu: ",
+ "irc_comment": "mi kepeken e kulupu mute pi ilo toki. nimi mi li 'Xe' anu 'Xena' anu 'Cadey'."
+ },
+ "error": {
+ "title": "pakala",
+ "post_not_found": "lipu %s li pona ala. ona li lukin ala."
+ },
+ "resume": {
+ "plaintext": "sina wile lipu pona la sina lukin e ni"
+ }
+}
diff --git a/templates/base.html b/templates/base.html
index c00bc1e..8c23220 100644
--- a/templates/base.html
+++ b/templates/base.html
@@ -56,11 +56,11 @@
{{ template "scripts" . }}
<div class="container">
<header>
- <p><a href="/">Christine Dodrill</a> - <a href="/blog">Blog</a> - <a href="/contact">Contact</a> - <a href="/resume">Resume</a></p>
+ <p><a href="/">{{ trans "header" "name" }}</a> - <a href="/blog">{{ trans "header" "blog" }}</a> - <a href="/contact">{{ trans "header" "contact" }}</a> - <a href="/resume">{{ trans "header" "resume" }}</a></p>
</header>
{{ template "content" . }}
<footer>
- <blockquote>Copyright 2018 Christine Dodrill. Any and all opinions listed here are my own and not representative of my employer.</blockquote>
+ <blockquote>{{ trans "meta" "copyright" "2018" }}</blockquote>
</footer>
<script>
if (navigator.serviceWorker.controller) {
diff --git a/templates/blogindex.html b/templates/blogindex.html
index 5527816..3768821 100644
--- a/templates/blogindex.html
+++ b/templates/blogindex.html
@@ -1,5 +1,5 @@
{{ define "title" }}
-<title>Blog - Christine Dodrill</title>
+<title>{{ trans "header" "blog" }} - {{ trans "header" "name" }}</title>
<style>
.blogpost-card {
@@ -9,14 +9,14 @@
{{ end }}
{{ define "content" }}
-<h1>Blogposts</h1>
+<h1>{{ trans "blog" "index_title" }}</h1>
<div class="grid">
{{ range . }}
<div class="card cell -4of12 blogpost-card">
<header class="card-header">{{ .Title }}</header>
<div class="card-content">
- <p>Posted on {{ .Date }} <br> <a href="{{ .Link }}">Read Post</a></p>
+ <p>{{ trans "blog" "posted_on" .Date }} <br> <a href="{{ .Link }}">{{ trans "blog" "read_this" }}</a></p>
</div>
</div>
{{ end }}
@@ -24,7 +24,7 @@
<br />
-<h2>Other Blogs I Find Interesting</h2>
+<h2>{{ trans "blog" "blogroll" }}</h2>
<ul>
<li><a href="https://write.as/excerpts/">Excerpts</a></li>
diff --git a/templates/blogpost.html b/templates/blogpost.html
index 108902c..a8f5340 100644
--- a/templates/blogpost.html
+++ b/templates/blogpost.html
@@ -1,5 +1,5 @@
{{ define "title" }}
-<title>{{ .Title }} - Christine Dodrill</title>
+<title>{{ .Title }} - {{ trans "header" "name" }}</title>
<!-- Twitter -->
<meta name="twitter:card" content="summary" />
@@ -10,11 +10,11 @@
<!-- Facebook -->
<meta property="og:type" content="website" />
<meta property="og:title" content="{{ .Title }}" />
-<meta property="og:site_name" content="Christine Dodrill's Blog" />
+<meta property="og:site_name" content="{{ trans "blog" "title" }}" />
<!-- Description -->
-<meta name="description" content="{{ .Title }} - Christine Dodrill's Blog" />
-<meta name="author" content="Christine Dodrill">
+<meta name="description" content="{{ .Title }} - {{ trans "blog" "title" }}" />
+<meta name="author" content="{{ trans "header" "name" }}">
{{ end }}
{{ define "content" }}
@@ -22,5 +22,5 @@
<hr />
-<i>Content posted on {{ .Date }}, opinions and preferences of the author may have changed since then.</i>
+<i>{{ trans "blog" "disclaimer" .Date }}</i>
{{ end }}
diff --git a/templates/contact.html b/templates/contact.html
index 9f8fdfc..d641b18 100644
--- a/templates/contact.html
+++ b/templates/contact.html
@@ -1,15 +1,13 @@
-{{ define "title" }}<title>Contact - Christine Dodrill</title>{{ end }}
+{{ define "title" }}<title>{{ trans "header" "contact" }} - {{ trans "header" "name" }}</title>{{ end }}
{{ define "content" }}
-<h1>Contact Information</h1>
+<h1>{{ trans "contact" "header" }}</h1>
<div class="grid">
<div class="cell -6of12">
- <h3>Email</h3>
+ <h3>{{ trans "contact" "email" }}</h3>
<p>me@christine.website</p>
- <p>My GPG fingerprint is <code>799F 9134 8118 1111</code>. If you get an email that appears to be from me and the signature does not match that fingerprint, it is not from me. You may download a copy of my public key <a href="/static/gpg.pub">here</a>.</p>
-
- <h3>Social Media</h3>
+ <h3>{{ trans "contact" "social_media" }}</h3>
<ul>
<li><a href="https://github.com/Xe">Github</a></li>
<li><a href="https://twitter.com/theprincessxena">Twitter</a></li>
@@ -20,11 +18,11 @@
</ul>
</div>
<div class="cell -6of12">
- <h3>Other Information</h3>
- <p>To send me donations, my bitcoin address is <code>1Gi2ZF2C9CU9QooH8bQMB2GJ2iL6shVnVe</code>.</p>
+ <h3>{{ trans "contact" "other_info" }}</h3>
+ <p>{{ trans "contact" "donations" }} <code>1Gi2ZF2C9CU9QooH8bQMB2GJ2iL6shVnVe</code>.</p>
<h4>IRC</h4>
- <p>I am on many IRC networks. On Freenode I am using the nick Xe but elsewhere I will use the nick Xena or Cadey.</p>
+ <p>{{ trans "contact" "irc_comment" }}</p>
<h4>Telegram</h4>
<p><a href="https://t.me/miamorecadenza">@miamorecadenza</a></p>
diff --git a/templates/error.html b/templates/error.html
index cb47e83..6e1bf36 100644
--- a/templates/error.html
+++ b/templates/error.html
@@ -1,5 +1,5 @@
{{ define "title" }}
-<title>Error - Christine Dodrill</title>
+<title>{{ trans "error" "title" }} - {{ trans "header" "name" }}</title>
{{ end }}
{{ define "content" }}
diff --git a/templates/index.html b/templates/index.html
index 9043e5f..736a599 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -1,29 +1,36 @@
-{{ define "title" }}<title>Christine Dodrill</title>{{ end }}
+{{ define "title" }}<title>{{ trans "header" "name" }}</title>{{ end }}
{{ define "content" }}
<div class="grid">
<div class="cell -3of12 content">
<img src="/static/img/avatar.png">
<br />
- <a href="/contact" class="justify-content-center">Contact Me</a>
+ <a href="/contact" class="justify-content-center">{{ trans "index" "contact_me" }}</a>
</div>
<div class="cell -9of12 content">
- <h1>Christine Dodrill</h1>
- <h4>Web and Backend Services Devops Specialist</h4>
- <h5>Skills</h5>
+ <h1>{{ trans "header" "name" }}</h1>
+ <h4>{{ trans "index" "title" }}</h4>
+ <h5>{{ trans "index" "skills" }}</h5>
<ul>
<li>Go, Lua, Nim, Haskell, C, Python (3.x) and other languages</li>
<li>Docker (deployment, development & more)</li>
<li>Mashups of data</li>
<li>Package maintainer for Alpine Linux</li>
+ <li>Speaks English, toki pona, and la .lojban.</li>
</ul>
- <h5>Highlighted Projects</h5>
+ <h5>{{ trans "index" "highlighted_projects" }}</h5>
<ul>
<li><a href="https://github.com/Xe/PonyAPI">PonyAPI</a> - My Little Pony: Friendship is Magic Episode information API</li>
<li><a href="https://github.com/PonyvilleFM/aura">Aura</a> - PonyvilleFM live DJ recording bot</li>
<li><a href="https://github.com/Elemental-IRCd/elemental-ircd">Elemental-IRCd</a> - IRC Server Software</li>
<li><a href="https://github.com/Xe/site">This website</a> - The backend and templates for this website</li>
+ <li><a href="https://github.com/Xe/olin">Olin</a> - WebAssembly on the server</li>
+ <li><a href="https://github.com/Xe/aports">aports</a> - Alpine Linux ports</li>
+ <li><a href="https://github.com/Xe/when-then-zen">when-then-zen</a> - Meditation instructions in Gherkin</li>
+ <li><a href="https://github.com/Xe/creators-code">Creator's Code</a> - Minimal code of conduct for communities</li>
+ <li><a href="https://github.com/Xe/printerfacts">printerfacts</a> - Informative facts about printers</li>
+ <li><a href="https://github.com/Xe/x">x</a> - Experiments and toys</li>
</ul>
</div>
</div>
diff --git a/templates/resume.html b/templates/resume.html
index 9789361..4776ce3 100644
--- a/templates/resume.html
+++ b/templates/resume.html
@@ -1,9 +1,9 @@
-{{ define "title" }}<title>Resume - Christine Dodrill</title>{{ end }}
+{{ define "title" }}<title>{{ trans "header" "resume" }} - {{ trans "header" "name" }}</title>{{ end }}
{{ define "content" }}
{{ . }}
<hr />
-<a href="/static/resume/resume.md">Plain-text version of this resume here</a>
+<a href="/static/resume/resume.md">{{ trans "resume" "plaintext" }}</a>
{{ end }}