package seculardb
import (
"fmt"
"html/template"
"io"
"log"
"net/http"
"strconv"
"strings"
)
var pageTmpl = `
Filterable Secular Homeschooler Guide
Name |
Secular Rating |
Grade Level(s) |
Subject(s) |
Description & Notes |
{{range $index, $entry := .Entries}}
{{if .URL}}
{{.Name}} |
{{else}}
{{.Name}} |
{{end}}
{{.Rating}} |
{{join .GradeLevels}} |
{{joinbr .Subjects}} |
{{.Description}} |
{{end}}
`
// WriteHTML writes the given DB to an io.Writer after applying an HTML template
func WriteHTML(w io.Writer, db DB) error {
t := template.Must(template.New("sb").Funcs(
template.FuncMap{
"join": func(v []string) string {
return strings.Join(v, ",")
},
"joinbr": func(v []string) template.HTML {
return template.HTML(strings.Join(v, "
"))
},
}).Parse(pageTmpl))
if err := t.Execute(w, db); err != nil {
return fmt.Errorf("could not generate page: %v", err)
}
return nil
}
// Serve renders the database as an html table
func Serve(w http.ResponseWriter, r *http.Request) {
db, err := Build()
if err != nil {
log.Printf("could not serve page: %v\n", err)
w.WriteHeader(http.StatusInternalServerError)
}
matcher := NewMatcher()
for k, v := range r.URL.Query() {
switch k {
case "rating":
rating, err := strconv.Atoi(v[0])
if err != nil {
log.Printf("error: could not parse rating '%s': %v\n", v[0], err)
w.WriteHeader(http.StatusBadRequest)
return
}
matcher.Rating(rating)
case "grades":
for _, str := range v {
val, err := strconv.Atoi(str)
if err != nil {
log.Printf("error: could not parse grade '%s': %v\n", str, err)
w.WriteHeader(http.StatusBadRequest)
return
}
matcher.Grade(val)
}
case "name":
matcher.Names(v)
case "subject":
matcher.Subjects(v)
}
}
filtered, err := Filter(db, matcher)
if err == nil {
err = WriteHTML(w, filtered)
}
if err != nil {
log.Printf("could not serve page: %v\n", err)
w.WriteHeader(http.StatusInternalServerError)
}
}