diff --git a/dict/main.go b/dict/main.go index 77755a9..6c7a0d0 100644 --- a/dict/main.go +++ b/dict/main.go @@ -30,7 +30,12 @@ func LoadDict() error { type Entry struct { Kanji string Reading string - Definitions []string + Definitions []Definition +} + +type Definition struct { + Definition string + PartOfSpeech string } func ParseEntry(entry jmdict.JmdictEntry) Entry { @@ -42,11 +47,18 @@ func ParseEntry(entry jmdict.JmdictEntry) Entry { if len(entry.Readings) > 0 { reading = entry.Readings[0].Reading } - var definitions []string + var definitions []Definition if len(entry.Sense) > 0 && len(entry.Sense[0].Glossary) > 0 { - definitions = make([]string, len(entry.Sense[0].Glossary)) + definitions = make([]Definition, len(entry.Sense[0].Glossary)) for i, glossary := range entry.Sense[0].Glossary { - definitions[i] = glossary.Content + var pos string + if len(entry.Sense[0].PartsOfSpeech) > i+1 { + pos = entry.Sense[0].PartsOfSpeech[i] + } + definitions[i] = Definition{ + Definition: glossary.Content, + PartOfSpeech: pos, + } } } return Entry{ diff --git a/dict/templates/definition.html b/dict/templates/definition.html new file mode 100644 index 0000000..b85c3ed --- /dev/null +++ b/dict/templates/definition.html @@ -0,0 +1,3 @@ +{{ define "definition" }} +{{ if .PartOfSpeech }}<chip>{{ .PartOfSpeech }}</chip> {{ end }}{{ .Definition -}} +{{ end }} \ No newline at end of file diff --git a/dict/templates/search.html b/dict/templates/search.html index b87fb1c..3ee8e32 100644 --- a/dict/templates/search.html +++ b/dict/templates/search.html @@ -9,11 +9,11 @@ {{- end -}} </h3> {{ if le (len .Definitions) 2 -}} - <p>{{- index .Definitions 0 -}}</p> + <p>{{- template "definition" (index .Definitions 0) -}}</p> {{- else -}} <ol> {{- range .Definitions }} - <li>{{- . -}}</li> + <li>{{- template "definition" . -}}</li> {{- end }} </ol> {{- end }} diff --git a/httputils/handler.go b/httputils/handler.go index de941ce..a98c763 100644 --- a/httputils/handler.go +++ b/httputils/handler.go @@ -3,25 +3,68 @@ package httputils import ( "fmt" "net/http" + "os" + "path/filepath" + "strings" "text/template" + "time" ) type Handler = func(http.ResponseWriter, *http.Request) +const templateFolder = "templates" + +var templatePaths, templateModTimes, _ = getTemplates() +var templates *template.Template = template.Must(template.ParseFiles(templatePaths...)) + +func getTemplates() ([]string, map[string]time.Time, error) { + var modTimes map[string]time.Time = make(map[string]time.Time) + err := filepath.Walk(templateFolder, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if !info.IsDir() && strings.HasSuffix(path, ".html") { + modTimes[path] = info.ModTime() + } + return nil + }) + paths := make([]string, len(modTimes)) + i := 0 + for path := range modTimes { + paths[i] = path + i++ + } + return paths, modTimes, err +} + +func reloadTemplateIfModified(path string) { + fileInfo, _ := os.Stat(path) + modTime := fileInfo.ModTime() + if modTime.After(templateModTimes[path]) { + fmt.Printf("Reloading template %s...\n", path) + templates.ParseFiles(path) + templateModTimes[path] = modTime + } +} + +func reloadTemplatesIfModified() { + for _, path := range templatePaths { + reloadTemplateIfModified(path) + } +} + +const reloadTemplates = true + func GenerateHandler( file string, handler func(http.ResponseWriter, *http.Request) bool, data func(http.ResponseWriter, *http.Request) any, methods []string, ) Handler { - var tmpl *template.Template - //if file != "" { - // tmpl = template.Must(template.ParseFiles(fmt.Sprintf("templates/%s", file))) - //} return func(w http.ResponseWriter, r *http.Request) { - // Remove in production, enables live template reloading - if file != "" { - tmpl = template.Must(template.ParseFiles(fmt.Sprintf("templates/%s", file))) + // All templates must be reloaded in case of dependencies + if reloadTemplates { + reloadTemplatesIfModified() } for _, method := range methods { if method == r.Method { @@ -32,9 +75,9 @@ func GenerateHandler( return ok: renderTemplate := handler(w, r) - if renderTemplate && tmpl != nil { + if renderTemplate && file != "" { w.Header().Set("Content-Type", "text/html; charset=utf-8") - tmpl.Execute(w, data(w, r)) + templates.ExecuteTemplate(w, file, data(w, r)) } } }