diff --git a/dict/main.go b/dict/main.go index 8b4328b..8d375d3 100644 --- a/dict/main.go +++ b/dict/main.go @@ -69,10 +69,11 @@ func ParseEntry(entry jmdict.JmdictEntry) Entry { } } -func Search(query string) (exactResults []Entry, otherResults []Entry, truncated bool) { +func Search(query string) queryResult { query = strings.TrimSpace(query) - exactResults = make([]Entry, 0) - otherResults = make([]Entry, 0) + exactResults := make([]Entry, 0) + otherResults := make([]Entry, 0) + truncated := false count := 0 for _, jmdictEntry := range dict.Entries { exactMatch := false @@ -105,25 +106,25 @@ func Search(query string) (exactResults []Entry, otherResults []Entry, truncated break } } - return + return queryResult{ + Query: query, + ExactResults: exactResults, + OtherResults: otherResults, + Truncated: truncated, + Count: len(exactResults) + len(otherResults), + } } -type searchTemplateData struct { +type queryResult struct { + // Fields must be capitalized + // to be accessible in templates + Query string ExactResults []Entry OtherResults []Entry Truncated bool Count int } -func initSearchTemplateData(exactResults []Entry, otherResults []Entry, truncated bool) searchTemplateData { - return searchTemplateData{ - ExactResults: exactResults, - OtherResults: otherResults, - Truncated: truncated, - Count: len(exactResults) + len(otherResults), - } -} - func main() { err := LoadDict() if err != nil { @@ -138,46 +139,49 @@ func main() { func(w http.ResponseWriter, r *http.Request) any { return nil }, []string{http.MethodGet}, )) - redirectToHome := func(w http.ResponseWriter, r *http.Request) { - http.Redirect(w, r, "/", http.StatusPermanentRedirect) + rawSearchHandler := func(w http.ResponseWriter, r *http.Request) { + r.ParseMultipartForm(0) + q := r.FormValue("q") + var redirect string + if q == "" { + redirect = "/" + } else { + redirect = "/search/" + q + } + http.Redirect(w, r, redirect, http.StatusMovedPermanently) } - r.HandleFunc("/search", redirectToHome) - r.HandleFunc("/search/", redirectToHome) + r.HandleFunc("/search", rawSearchHandler) + r.HandleFunc("/search/", rawSearchHandler) r.HandleFunc("/search/{query}", httputils.GenerateHandler( - "index.html", - func(w http.ResponseWriter, r *http.Request) bool { - return true - }, - func(w http.ResponseWriter, r *http.Request) any { - query := mux.Vars(r)["query"] - return struct { - Query string - Results searchTemplateData - }{ - Query: query, - Results: initSearchTemplateData(Search(query)), + // template file + func(w http.ResponseWriter, r *http.Request) string { + if r.Header.Get("HX-Request") == "" { + return "index.html" } + return "search.html" }, - []string{http.MethodGet}, - )) - r.HandleFunc("/api/search", httputils.GenerateHandler( - "search.html", + // handler whether or not to use template func(w http.ResponseWriter, r *http.Request) bool { + // If Accept: applicaiton/json we'll use the template if r.Header.Get("Accept") != "application/json" { return true } + + // Otherwise, let's send JSON + query := mux.Vars(r)["query"] + result := Search(query) + jsonBytes, _ := json.Marshal(append(result.ExactResults, result.OtherResults...)) + w.Header().Set("Content-Type", "application/json; charset=utf-8") - r.ParseMultipartForm(0) - query := r.FormValue("q") - exactResults, otherResults, _ := Search(query) - jsonBytes, _ := json.Marshal(append(exactResults, otherResults...)) fmt.Fprint(w, string(jsonBytes)) + return false }, + // template data func(w http.ResponseWriter, r *http.Request) any { - r.ParseMultipartForm(0) - query := r.FormValue("q") - return initSearchTemplateData(Search(query)) + // Only runs if handler returns true + query := mux.Vars(r)["query"] + return Search(query) }, []string{http.MethodGet}, )) diff --git a/dict/templates/index.html b/dict/templates/index.html index ca01362..446cfc0 100644 --- a/dict/templates/index.html +++ b/dict/templates/index.html @@ -3,7 +3,7 @@ - jidict + {{ with .Query }}{{ . }} search - {{ end }}jidict