You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

153 lines
4.8 KiB
Go

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package server
import (
"errors"
"fmt"
"log/slog"
"net/http"
"strconv"
"git.runcible.io/learning/ratchet/internal/model"
)
// TODO function should accept and a pointer to an interface allowing for mocking in tests.
func handleHome(logger *slog.Logger, tc *TemplateCache, snippetService *model.SnippetService) http.Handler {
return http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
// Retrieve Snippets from DB
snippets, err := snippetService.Lastest()
if err != err {
serverError(w, r, err)
return
}
logger.Debug(fmt.Sprintf("%d snippets retrieved", len(snippets)))
// Old way. We want default data so
// data := templateData{
// Snippets: snippets,
// }
data := newTemplateData()
data.Snippets = snippets
renderTemplate(w, r, tc, http.StatusOK, "home.go.tmpl", data)
// // Initialize a slice containing the paths to the two files. It's important
// // to note that the file containing our base template must be the *first*
// // file in the slice.
// files := []string{
// "./ui/html/base.go.tmpl",
// "./ui/html/partials/nav.go.tmpl",
// "./ui/html/pages/home.go.tmpl",
// }
// read template file into template set.
// ts, err := template.ParseFiles(files...)
// ts, err := parseTemplateFiles(files...)
// if err != nil {
// serverError(w, r, err)
// return
// }
// // Write template content to response body
// err = ts.ExecuteTemplate(w, "base", data)
// if err != nil {
// // This is the older more verbose way of doing what RatchetServer.serverError does
// // rs.logger.Error(err.Error())
// // http.Error(w, "Internal Server Error", http.StatusInternalServerError)
// serverError(w, r, err)
// }
})
}
func handleSnippetView(logger *slog.Logger, tc *TemplateCache, snippetService *model.SnippetService) http.Handler {
return http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
id, err := strconv.Atoi(r.PathValue("id"))
if err != nil || id < 1 {
clientError(w, http.StatusNotFound)
return
}
// Set a new cache-control header. If an existing "Cache-Control" header exists
// it will be overwritten.
// w.Header().Set("Cache-Control", "public, max-age=31536000")
snippet, err := snippetService.Get(id)
if err != nil {
logger.Debug(fmt.Sprintf("Failed to retrieve an active record with id: %d", id))
if errors.Is(err, model.ErrNoRecord) {
clientError(w, http.StatusNotFound)
} else {
serverError(w, r, err)
}
return
}
// files := []string{
// "./ui/html/base.go.tmpl",
// "./ui/html/partials/nav.go.tmpl",
// "./ui/html/pages/view.go.tmpl",
// }
// //ts, err := template.ParseFiles(files...)
// ts, err := parseTemplateFiles(files...)
// if err != nil {
// serverError(w, r, err)
// return
// }
// data := templateData{
// Snippet: snippet,
// }
// logger.Debug(fmt.Sprintf("created template: %s", ts.Name()))
// Any data that you pass as the final parameter to ts.ExecuteTemplate()
// is represented within your HTML templates by the . character (referred to as dot).
// In this specific case, the underlying type of dot will be a models.Snippet struct.
// When the underlying type of dot is a struct, you can render (or yield) the value
// of any exported field in your templates by postfixing dot with the field name
// field, we could yield the snippet title by writing {{.Title}} in our templates.
// err = ts.ExecuteTemplate(w, "base", data)
// if err != nil {
// serverError(w, r, err)
// }
// data := templateData{
// Snippet: snippet,
// }
data := newTemplateData()
data.Snippet = snippet
renderTemplate(w, r, tc, http.StatusOK, "view.go.tmpl", data)
})
}
func handleSnippetCreateGet() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Create snippet form.."))
})
}
// snippetCreate handles display of the form used to create snippets
//
// curl -iL -d "" http://localhost:5001/snippet/create
func handleSnippetCreatePost(logger *slog.Logger, tc *TemplateCache, snippetService *model.SnippetService) http.Handler {
return http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
// example of a custom header. Must be done before calling WriteHeader
// or they will fail to take effect.
w.Header().Add("Server", "Dirp")
// Create some variables holding dummy data. We'll remove these later on
// during the build.
title := "O snail"
content := "O snail\nClimb Mount Fuji,\nBut slowly, slowly!\n\n Kobayashi Issa"
expires := 7
id, err := snippetService.Insert(title, content, expires)
if err != nil {
serverError(w, r, err)
}
logger.Info(fmt.Sprintf("Inserted record. id: %d", id))
http.Redirect(w, r, fmt.Sprintf("/snippet/view/%d", id), http.StatusSeeOther)
})
}