Translations & certificates
- Translation system, possibility to define different language using meta.language setting - Only en-EN and fi-FI implemented - Added certificates section, for miscellaneous certs and licences
This commit is contained in:
parent
6c16eb5a7c
commit
a286b61c58
13
main.go
13
main.go
|
@ -17,8 +17,10 @@ import (
|
||||||
var static embed.FS
|
var static embed.FS
|
||||||
var templates map[string]*template.Template
|
var templates map[string]*template.Template
|
||||||
var configFile string
|
var configFile string
|
||||||
|
var strs map[string]map[string]string
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
loadStrings()
|
||||||
cfgFile := flag.String("config", "./data/resume.yaml", "Path to the configuration YAML")
|
cfgFile := flag.String("config", "./data/resume.yaml", "Path to the configuration YAML")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
|
@ -53,7 +55,9 @@ func home(w http.ResponseWriter, r *http.Request) {
|
||||||
"templates/metatag.html",
|
"templates/metatag.html",
|
||||||
"templates/githubCorner.html",
|
"templates/githubCorner.html",
|
||||||
}
|
}
|
||||||
tmpl, err := template.ParseFS(static, templateFiles...)
|
var err error
|
||||||
|
tmpl := template.New("index").Funcs(templateFunctions())
|
||||||
|
tmpl, err = tmpl.ParseFS(static, templateFiles...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error(err.Error())
|
slog.Error(err.Error())
|
||||||
http.Error(w, "Server error", http.StatusInternalServerError)
|
http.Error(w, "Server error", http.StatusInternalServerError)
|
||||||
|
@ -69,7 +73,6 @@ func home(w http.ResponseWriter, r *http.Request) {
|
||||||
data.Theme = urlSlice[len(urlSlice)-1]
|
data.Theme = urlSlice[len(urlSlice)-1]
|
||||||
}
|
}
|
||||||
data.Year = time.Now().Format("2006")
|
data.Year = time.Now().Format("2006")
|
||||||
tmpl.Funcs(templateFunctions())
|
|
||||||
err = tmpl.Execute(w, *data)
|
err = tmpl.Execute(w, *data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error(err.Error())
|
slog.Error(err.Error())
|
||||||
|
@ -82,5 +85,11 @@ func templateFunctions() template.FuncMap {
|
||||||
"html": func(raw string) template.HTML {
|
"html": func(raw string) template.HTML {
|
||||||
return template.HTML(raw)
|
return template.HTML(raw)
|
||||||
},
|
},
|
||||||
|
"translate": func(label, lang string) string {
|
||||||
|
if strs[lang][label] == "" {
|
||||||
|
return label + " (no translation)"
|
||||||
|
}
|
||||||
|
return strs[lang][label]
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
39
resume.go
39
resume.go
|
@ -13,19 +13,20 @@ type Resume struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Profile struct {
|
type Profile struct {
|
||||||
Name string `yaml:"name"`
|
Name string `yaml:"name"`
|
||||||
Title string `yaml:"title"`
|
Title string `yaml:"title"`
|
||||||
City string `yaml:"city"`
|
City string `yaml:"city"`
|
||||||
Phone string `yaml:"phone"`
|
Phone string `yaml:"phone"`
|
||||||
Email string `yaml:"email"`
|
Email string `yaml:"email"`
|
||||||
Socials Socials `yaml:"socials"`
|
Socials Socials `yaml:"socials"`
|
||||||
Photo string `yaml:"photo"`
|
Photo string `yaml:"photo"`
|
||||||
Summary string `yaml:"summary"`
|
Summary string `yaml:"summary"`
|
||||||
Experience []Job `yaml:"experience"`
|
Experience []Job `yaml:"experience"`
|
||||||
Education []Education `yaml:"education"`
|
Education []Education `yaml:"education"`
|
||||||
Skills []Skill `yaml:"skills"`
|
Skills []Skill `yaml:"skills"`
|
||||||
Projects any `yaml:"projects"`
|
Projects any `yaml:"projects"`
|
||||||
Languages []Language `yaml:"languages"`
|
Languages []Language `yaml:"languages"`
|
||||||
|
Certificates []Certificate `yaml:"certificates"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Profile) GetTagWidth(t string) string {
|
func (p *Profile) GetTagWidth(t string) string {
|
||||||
|
@ -47,9 +48,9 @@ func (p *Profile) GetTagWidth(t string) string {
|
||||||
return fmt.Sprintf("%dch", l)
|
return fmt.Sprintf("%dch", l)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (job *Job) html(raw string) template.HTML {
|
//func (job *Job) html(raw string) template.HTML {
|
||||||
return template.HTML(raw)
|
// return template.HTML(raw)
|
||||||
}
|
//}
|
||||||
|
|
||||||
type Job struct {
|
type Job struct {
|
||||||
Company string `yaml:"company"`
|
Company string `yaml:"company"`
|
||||||
|
@ -92,8 +93,6 @@ func (language *Language) VisualLevel(level int) template.HTML {
|
||||||
return _visualLevel(level)
|
return _visualLevel(level)
|
||||||
}
|
}
|
||||||
|
|
||||||
type skills []Skill
|
|
||||||
|
|
||||||
type Social struct {
|
type Social struct {
|
||||||
Media string `yaml:"media"`
|
Media string `yaml:"media"`
|
||||||
UserId string `yaml:"userId"`
|
UserId string `yaml:"userId"`
|
||||||
|
@ -116,3 +115,7 @@ type Language struct {
|
||||||
Name string `yaml:"name"`
|
Name string `yaml:"name"`
|
||||||
Level int `yaml:"level"`
|
Level int `yaml:"level"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Certificate struct {
|
||||||
|
Name string `yaml:"name"`
|
||||||
|
}
|
||||||
|
|
|
@ -11,3 +11,6 @@
|
||||||
|
|
||||||
.subtitle {
|
.subtitle {
|
||||||
color: var(--subtitle-color); }
|
color: var(--subtitle-color); }
|
||||||
|
|
||||||
|
.tag:not(body).is-primary {
|
||||||
|
color: #2f2f2f; }
|
||||||
|
|
|
@ -15,3 +15,7 @@
|
||||||
.subtitle {
|
.subtitle {
|
||||||
color: var(--subtitle-color);
|
color: var(--subtitle-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tag:not(body).is-primary {
|
||||||
|
color: #2f2f2f;
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
func loadStrings() {
|
||||||
|
strs = make(map[string]map[string]string)
|
||||||
|
strs["en-EN"] = make(map[string]string)
|
||||||
|
strs["en-EN"] = map[string]string{
|
||||||
|
"summary": "SUMMARY",
|
||||||
|
"experience": "EXPERIENCE",
|
||||||
|
"education": "EDUCATION",
|
||||||
|
"projects": "PROJECTS",
|
||||||
|
"skills": "SKILLS",
|
||||||
|
"languages": "LANGUAGES",
|
||||||
|
"certificates": "CERTIFICATES, LICENSES ETC",
|
||||||
|
"see_dark": "See Dark Theme",
|
||||||
|
"see_light": "See Light Theme",
|
||||||
|
"all_rights_reserved": "All Rights Reserved.",
|
||||||
|
"powered_by": "Powered by <a href=\"https://github.com/0ranki/go-resume\">go-resume</a>",
|
||||||
|
}
|
||||||
|
|
||||||
|
strs["fi-FI"] = make(map[string]string)
|
||||||
|
strs["fi-FI"] = map[string]string{
|
||||||
|
"summary": "YLEISTÄ",
|
||||||
|
"experience": "TYÖKOKEMUS",
|
||||||
|
"education": "KOULUTUS",
|
||||||
|
"projects": "PROJEKTIT",
|
||||||
|
"skills": "TAIDOT",
|
||||||
|
"languages": "KIELITAITO",
|
||||||
|
"certificates": "LUVAT, TODISTUKSET YM.",
|
||||||
|
"see_dark": "Tumma teema",
|
||||||
|
"see_light": "Vaalea teema",
|
||||||
|
"all_rights_reserved": "Kaikki oikeudet pidätetään.",
|
||||||
|
"powered_by": "Luotu käyttäen sovellusta <a href=\"https://github.com/0ranki/go-resume\">go-resume</a>",
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,3 +1,7 @@
|
||||||
|
{{ define "index" }}
|
||||||
|
|
||||||
|
{{ $lang := .Meta.Language }}
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
|
@ -71,7 +75,7 @@
|
||||||
<div class="column is-three-fifths">
|
<div class="column is-three-fifths">
|
||||||
<div class="summary">
|
<div class="summary">
|
||||||
<div class="title is-size-5 has-text-primary has-text-weight-bold">
|
<div class="title is-size-5 has-text-primary has-text-weight-bold">
|
||||||
SUMMARY
|
{{ translate "summary" $lang }}
|
||||||
</div>
|
</div>
|
||||||
<div class="wrapper">{{ .Profile.Summary }}</div>
|
<div class="wrapper">{{ .Profile.Summary }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -79,7 +83,7 @@
|
||||||
{{ with .Profile.Experience }}
|
{{ with .Profile.Experience }}
|
||||||
<div class="experience">
|
<div class="experience">
|
||||||
<div class="title is-size-5 has-text-primary has-text-weight-bold">
|
<div class="title is-size-5 has-text-primary has-text-weight-bold">
|
||||||
EXPERIENCE
|
{{ translate "experience" $lang }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!--<% content.data.experiences.forEach(function(experience){ %>-->
|
<!--<% content.data.experiences.forEach(function(experience){ %>-->
|
||||||
|
@ -113,7 +117,7 @@
|
||||||
{{ with .Profile.Education }}
|
{{ with .Profile.Education }}
|
||||||
<div class="education">
|
<div class="education">
|
||||||
<div class="title is-size-5 has-text-primary has-text-weight-bold">
|
<div class="title is-size-5 has-text-primary has-text-weight-bold">
|
||||||
EDUCATION
|
{{ translate "education" $lang }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{ range . }}
|
{{ range . }}
|
||||||
|
@ -141,9 +145,10 @@
|
||||||
{{ with .Profile.Projects }}
|
{{ with .Profile.Projects }}
|
||||||
<div class="projects">
|
<div class="projects">
|
||||||
<div class="title is-size-5 has-text-primary has-text-weight-bold">
|
<div class="title is-size-5 has-text-primary has-text-weight-bold">
|
||||||
PROJECTS
|
{{ translate "projects" $lang }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!--TODO: projects-->
|
||||||
<% content.data.projects.forEach(function(proj){ %>
|
<% content.data.projects.forEach(function(proj){ %>
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<div class="is-size-5">
|
<div class="is-size-5">
|
||||||
|
@ -160,7 +165,7 @@
|
||||||
{{ with .Profile.Skills }}
|
{{ with .Profile.Skills }}
|
||||||
<div class="skills">
|
<div class="skills">
|
||||||
<div class="title is-size-5 has-text-primary has-text-weight-bold">
|
<div class="title is-size-5 has-text-primary has-text-weight-bold">
|
||||||
SKILLS
|
{{ translate "skills" $lang }}
|
||||||
</div>
|
</div>
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
{{ range . }}
|
{{ range . }}
|
||||||
|
@ -182,7 +187,7 @@
|
||||||
{{ with .Profile.Languages }}
|
{{ with .Profile.Languages }}
|
||||||
<div class="languages">
|
<div class="languages">
|
||||||
<div class="title is-size-5 has-text-primary has-text-weight-bold">
|
<div class="title is-size-5 has-text-primary has-text-weight-bold">
|
||||||
LANGUAGES
|
{{ translate "languages" $lang }}
|
||||||
</div>
|
</div>
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
{{ range . }}
|
{{ range . }}
|
||||||
|
@ -200,6 +205,25 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
|
{{ with .Profile.Certificates }}
|
||||||
|
<div class="certificates">
|
||||||
|
<div class="title is-size-5 has-text-primary has-text-weight-bold">
|
||||||
|
{{ translate "certificates" $lang }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{ range . }}
|
||||||
|
<div class="item">
|
||||||
|
<div class="is-size-5">
|
||||||
|
<div class="tag is-size-6 is-primary text-dark" style="margin-bottom: 5px;">
|
||||||
|
{{ .Name }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
|
@ -209,14 +233,14 @@
|
||||||
<footer class="footer">
|
<footer class="footer">
|
||||||
<div class="content has-text-centered">
|
<div class="content has-text-centered">
|
||||||
{{ if eq .Theme "light" }}
|
{{ if eq .Theme "light" }}
|
||||||
<a href="/dark">See Dark Theme</a>
|
<a href="/dark">{{ translate "see_dark" $lang }}</a>
|
||||||
{{ else }}
|
{{ else }}
|
||||||
<a href="/light">See Light Theme</a>
|
<a href="/light">{{ translate "see_light" $lang }}</a>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
<br />
|
<br />
|
||||||
Copyright © {{ .Year }} {{ .Profile.Name }}. All rights Reserved.
|
Copyright © {{ .Year }} {{ .Profile.Name }}. {{ translate "all_rights_reserved" $lang }}
|
||||||
<br />
|
<br />
|
||||||
Powered by <a href="https://github.com/0ranki/go-resume">go-resume</a>
|
{{ translate "powered_by" $lang | html }}
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
@ -225,3 +249,4 @@
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
{{ end }}
|
Loading…
Reference in New Issue