言語はliblocale化 + 複数言語対応

このコミットが含まれているのは:
守矢諏訪子 2023-07-17 01:02:37 +09:00
コミット 34bcb6c4ce
14個のファイルの変更109行の追加78行の削除

ファイルの表示

@ -1,3 +1,7 @@
# 1.1.0
* 言語はliblocale化
* 複数言語対応
# 1.0.0 # 1.0.0
* PHPからGoに交換しました * PHPからGoに交換しました
* 今度からバージョンを付きます * 今度からバージョンを付きます

2
go.mod
ファイルの表示

@ -1,3 +1,5 @@
module 076/hozonsite module 076/hozonsite
go 1.20 go 1.20
require gitler.moe/suwako/goliblocale v1.0.0

2
go.sum ノーマルファイル
ファイルの表示

@ -0,0 +1,2 @@
gitler.moe/suwako/goliblocale v1.0.0 h1:QiQKNzdgpavwmAaYhAb5pth0I6qS8IJ7q2hYAgpXacU=
gitler.moe/suwako/goliblocale v1.0.0/go.mod h1:pdv9Go5taevY8ClBOA+oLXjGap7G1RmIVKUMF8HSJmU=

39
lang.go
ファイルの表示

@ -1,39 +0,0 @@
package main
import (
"encoding/json"
"fmt"
)
func getlist (lang string) []byte {
var jloc = []byte(`{
"top": "トップ",
"errfuseiurl": "URLは「http://」又は「https://」で始めます。",
"errfusei": "不正なエラー。"
}`)
var eloc = []byte(`{
"top": "Top",
"errfuseiurl": "The URL should start with \"http://\" or \"https://\".",
"errfusei": "Unknown error."
}`)
if lang == "en" { return eloc }
return jloc
}
func getloc (str string, lang string) string {
var payload map[string]interface{}
err := json.Unmarshal(getlist(lang), &payload)
if err != nil {
fmt.Println("loc:", err)
return ""
}
for k, v := range payload {
if str == k {
return v.(string)
}
}
return ""
}

17
locale/en.json ノーマルファイル
ファイルの表示

@ -0,0 +1,17 @@
{
"hozonsite": "Hozon Site",
"desc": "It is the world's first FOSS web archiver.",
"logo": "Logo",
"top": "Top",
"langchange": "Language change",
"totop": "Return to toppage",
"tophe": "To toppage.",
"topwhatsave": "Which page will you archive?",
"hozon": "Archive",
"archwhozonsite": "Archived with Hozon Site.",
"areadyhozon": "Pages that already got archived:",
"willreallyhozon": "This page seems to have been already archived.<br />Do you really want to proceed?",
"yesreallyhozon": "Yes, please archive!!",
"errfuseiurl": "The URL should start with \"http://\" or \"https://\".",
"errfusei": "Unknown error."
}

17
locale/ja.json ノーマルファイル
ファイルの表示

@ -0,0 +1,17 @@
{
"hozonsite": "保存サイト",
"desc": "世界初FOSS系ウエブアーカイバーです。",
"logo": "ロゴ",
"top": "トップ",
"langchange": "言語変更",
"totop": "トップページに戻る",
"tophe": "トップページへ",
"topwhatsave": "どのページを保存しますか?",
"hozon": "保存",
"archwhozonsite": "保存サイトでアーカイブしました。",
"areadyhozon": "既に保存されたページ:",
"willreallyhozon": "このページが既に保存されているみたいです。<br />本当に手続きましょうか?",
"yesreallyhozon": "はい、保存して下さい!!",
"errfuseiurl": "URLは「http://」又は「https://」で始めます。",
"errfusei": "不正なエラー。"
}

ファイルの表示

@ -7,7 +7,7 @@ import (
"strconv" "strconv"
) )
var version = "1.0.0" var version = "1.1.0"
func help () { func help () {
fmt.Println("使い方:"); fmt.Println("使い方:");

40
srv.go
ファイルの表示

@ -9,11 +9,13 @@ import (
"time" "time"
"os" "os"
"encoding/json" "encoding/json"
"gitler.moe/suwako/goliblocale"
) )
type ( type (
Page struct { Page struct {
Tit, Err, Lan, Ver, Ves, Url, Body string Err, Lan, Ver, Ves, Url, Body string
i18n map[string]string
Ext []Exist // 既に存在する場合 Ext []Exist // 既に存在する場合
} }
Stat struct { // APIのみ Stat struct { // APIのみ
@ -24,6 +26,10 @@ type (
} }
) )
func (p Page) T (key string) string {
return p.i18n[key]
}
// 日本語か英語 TODO複数言語対応 // 日本語か英語 TODO複数言語対応
func initloc (r *http.Request) string { func initloc (r *http.Request) string {
cookie, err := r.Cookie("lang") cookie, err := r.Cookie("lang")
@ -52,12 +58,17 @@ func siteHandler (cnf Config) func (http.ResponseWriter, *http.Request) {
data := &Page{Ver: version, Ves: strings.ReplaceAll(version, ".", "")} data := &Page{Ver: version, Ves: strings.ReplaceAll(version, ".", "")}
lang := initloc(r) lang := initloc(r)
data.Lan = lang data.Lan = lang
i18n, err := goliblocale.GetLocale("locale/" + lang)
if err != nil {
fmt.Println("liblocaleエラー%v", err)
return
}
data.i18n = i18n
ftmpl[0] = cnf.webpath + "/view/index.html" ftmpl[0] = cnf.webpath + "/view/index.html"
tmpl := template.Must(template.ParseFiles(ftmpl[0], ftmpl[1], ftmpl[2])) tmpl := template.Must(template.ParseFiles(ftmpl[0], ftmpl[1], ftmpl[2]))
data.Tit = getloc("top", lang)
if r.Method == "POST" { if r.Method == "POST" {
err := r.ParseForm() err := r.ParseForm()
if err != nil { if err != nil {
@ -66,14 +77,9 @@ func siteHandler (cnf Config) func (http.ResponseWriter, *http.Request) {
return return
} }
// クッキー // 言語変更
if r.PostForm.Get("langchange") != "" { if lang := r.PostFormValue("lang"); lang != "" {
cookie, err := r.Cookie("lang") http.SetCookie(w, &http.Cookie{Name: "lang", Value: lang, MaxAge: 31536000, Path: "/"})
if err != nil || cookie.Value == "ja" {
http.SetCookie(w, &http.Cookie {Name: "lang", Value: "en", MaxAge: 31536000, Path: "/"})
} else {
http.SetCookie(w, &http.Cookie {Name: "lang", Value: "ja", MaxAge: 31536000, Path: "/"})
}
http.Redirect(w, r, "/", http.StatusSeeOther) http.Redirect(w, r, "/", http.StatusSeeOther)
return return
} }
@ -84,7 +90,7 @@ func siteHandler (cnf Config) func (http.ResponseWriter, *http.Request) {
url := r.PostForm.Get("hozonsite") url := r.PostForm.Get("hozonsite")
// HTTPかHTTPSじゃない場合 // HTTPかHTTPSじゃない場合
if !checkprefix(url) { if !checkprefix(url) {
data.Err = getloc("errfuseiurl", lang) data.Err = i18n["errfuseiurl"]
ftmpl[0] = cnf.webpath + "/view/404.html" ftmpl[0] = cnf.webpath + "/view/404.html"
} else { } else {
eurl := stripurl(url) eurl := stripurl(url)
@ -114,7 +120,7 @@ func siteHandler (cnf Config) func (http.ResponseWriter, *http.Request) {
} }
data.Ext = existing data.Ext = existing
} else { } else {
data.Err = getloc("errfusei", lang) data.Err = i18n["errfusei"]
ftmpl[0] = cnf.webpath + "/view/404.html" ftmpl[0] = cnf.webpath + "/view/404.html"
} }
} }
@ -142,8 +148,14 @@ func archiveHandler (cnf Config) func (http.ResponseWriter, *http.Request) {
ftmpl := []string{cnf.webpath + "/view/index.html", cnf.webpath + "/view/header.html", cnf.webpath + "/view/footer.html"} ftmpl := []string{cnf.webpath + "/view/index.html", cnf.webpath + "/view/header.html", cnf.webpath + "/view/footer.html"}
data := &Page{Ver: version, Ves: strings.ReplaceAll(version, ".", "")} data := &Page{Ver: version, Ves: strings.ReplaceAll(version, ".", "")}
lang := initloc(r) lang := initloc(r)
data.Lan = lang data.Lan = lang
i18n, err := goliblocale.GetLocale("locale/" + lang)
if err != nil {
fmt.Println("liblocaleエラー%v", err)
return
}
data.i18n = i18n
ftmpl[0] = cnf.webpath + "/view/index.html" ftmpl[0] = cnf.webpath + "/view/index.html"
tmpl := template.Must(template.ParseFiles(ftmpl[0], ftmpl[1], ftmpl[2])) tmpl := template.Must(template.ParseFiles(ftmpl[0], ftmpl[1], ftmpl[2]))
path := strings.TrimPrefix(r.URL.Path, "/archive/") path := strings.TrimPrefix(r.URL.Path, "/archive/")

ファイルの表示

@ -69,10 +69,30 @@ input[type="text"] {
border-color: #ea8181; border-color: #ea8181;
} }
.submit, .footer, h1, .switchlang { select {
background-color: #600e0e;
color: #ea8181;
font-size: 18px;
border-radius: 4px;
max-width: 700px;
border: 1px #ff3b3b groove;
padding: 8px;
width: 200px;
}
select, input.langchange {
height: 35px;
vertical-align: middle;
}
.submit, .footer, h1 {
text-align: center; text-align: center;
} }
input.langchange {
font-size: 24px;
}
.submit, .footer, h1 { .submit, .footer, h1 {
margin-top: 32px; margin-top: 32px;
} }

ファイルの表示

@ -1,4 +1,4 @@
{{template "header" .}} {{template "header" .}}
{{ .Err }}<br /> {{ .Err }}<br />
<a href="/">{{if eq .Lan "ja"}}トップページに戻る{{else}}Return to toppage{{end}}</a> <a href="/">{{.T "totop"}}</a>
{{template "footer" .}} {{template "footer" .}}

ファイルの表示

@ -28,8 +28,8 @@
</head> </head>
<body> <body>
<div class="archhead"> <div class="archhead">
{{if eq .Lan "ja"}}保存サイトでアーカイブしました。{{else}}Archived with Hozon Site.{{end}} <a class="archlink" href="https://technicalsuwako.moe/blog/hozonsite-{{.Ves}}">hozonsite-{{ .Ver }}</a><br /> {{.T "archwhozonsite"}} <a class="archlink" href="https://technicalsuwako.moe/blog/hozonsite-{{.Ves}}">hozonsite-{{ .Ver }}</a><br />
<a class="archlink" href="/">{{if eq .Lan "ja"}}トップページへ{{else}}To toppage{{end}}</a> <a class="archlink" href="/">{{.T "tophe"}}</a>
</div> </div>
<div class="archbody"> <div class="archbody">
{{ .Body }} {{ .Body }}

ファイルの表示

@ -1,10 +1,6 @@
{{template "header" .}} {{template "header" .}}
<h3>{{.Url}}</h3> <h3>{{.Url}}</h3>
{{if eq .Lan "en"}} {{.T "areadyhozon"}}<br />
Pages that already got archived:
{{else}}
既に保存されたページ:
{{end}}<br />
{{range $i, $e := .Ext}} {{range $i, $e := .Ext}}
<a href="{{$e.Url}}"> <a href="{{$e.Url}}">
{{$e.Date}} {{$e.Date}}
@ -12,17 +8,13 @@
<br /> <br />
{{end}} {{end}}
<p> <p>
{{if eq .Lan "en"}} {{.T "willreallyhozon"}}
This page seems to have been already archived.<br />Do you really want to proceed?
{{else}}
このページが既に保存されているみたいです。<br />本当に手続きましょうか?
{{end}}
</p> </p>
<form action="/" method="post"> <form action="/" method="post">
<input type="hidden" name="hozonsite" value="{{.Url}}" /> <input type="hidden" name="hozonsite" value="{{.Url}}" />
<input type="hidden" name="agree" value="1" /> <input type="hidden" name="agree" value="1" />
<div class="submit"> <div class="submit">
<input type="submit" name="submit" value="{{if eq .Lan "en"}}Yes, please archive!!{{else}}はい保存して下さい{{end}}" /> <input type="submit" name="submit" value="{{.T "yesreallyhozon"}}" />
</div> </div>
</form> </form>
{{template "footer" .}} {{template "footer" .}}

ファイルの表示

@ -3,24 +3,28 @@
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja">
<head> <head>
<meta content="text/html; charset=utf-8" http-equiv="content-type" /> <meta content="text/html; charset=utf-8" http-equiv="content-type" />
<meta name="title" content="保存サイト" /> <meta name="title" content="{{.T "hozonsite"}}" />
<meta name="description" content="世界初FOSS系ウエブアーカイバーです。" /> <meta name="description" content="{{.T "desc"}}" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>保存サイト〜{{.Tit}}</title> <title>{{.T "hozonsite"}}〜{{.T "top"}}</title>
<link rel="icon" type="image/x-icon" href="/static/favicon.ico" /> <link rel="icon" type="image/x-icon" href="/static/favicon.ico" />
<link rel="stylesheet" type="text/css" href="/static/style.css" /> <link rel="stylesheet" type="text/css" href="/static/style.css" />
</head> </head>
<body> <body>
<h1> <h1>
<img class="headerimg" src="/static/logo.jpg" alt="{{if eq .Lan "ja"}}ロゴ{{else}}Logo{{end}}" /> <img class="headerimg" src="/static/logo.jpg" alt="{{.T "logo"}}" />
</h1> </h1>
<div class="body"> <div class="body">
<p> <p>
<a href="/">{{if eq .Lan "ja"}}トップ{{else}}Top{{end}}</a> <a href="/">{{.T "top"}}</a>
</p> </p>
<form method="post" action="/"> <form method="post" action="/">
<div class="switchlang"> <div class="central">
<input class="langchange" type="submit" name="langchange" value="{{if eq .Lan "ja"}}Change to English{{else}}日本語に変更する{{end}}" /> <select class="langchange" name="lang">
<option value="ja"{{if eq .Lan "ja"}} selected{{end}}>日本語</option>
<option value="en"{{if eq .Lan "en"}} selected{{end}}>English</option>
</select>
<input class="langchange" type="submit" name="chen" value="{{.T "langchange"}}" />
</div> </div>
</form> </form>
<hr /> <hr />

ファイルの表示

@ -1,9 +1,9 @@
{{template "header" .}} {{template "header" .}}
{{if eq .Lan "ja"}}どのページを保存しますか?{{else}}Which page will you archive?{{end}} {{.T "topwhatsave"}}
<form action="/" method="post"> <form action="/" method="post">
<input type="text" name="hozonsite" value="" /> <input type="text" name="hozonsite" value="" />
<div class="submit"> <div class="submit">
<input type="submit" name="submit" value="{{if eq .Lan "ja"}}保存{{else}}Archive{{end}}" /> <input type="submit" name="submit" value="{{.T "hozon"}}" />
</div> </div>
</form> </form>
{{template "footer" .}} {{template "footer" .}}