homeHandler + page index + template home; fixed page save/update flow,page data formatting

This commit is contained in:
Ruidy Nemausat 2020-03-18 09:22:54 +01:00
parent f77bc38da5
commit 1082d81963
8 changed files with 72 additions and 44 deletions

View file

@ -4,15 +4,24 @@ import (
"log" "log"
"net/http" "net/http"
"github.com/rjNemo/go-wiki/data"
"github.com/rjNemo/go-wiki/models"
"github.com/rjNemo/go-wiki/services" "github.com/rjNemo/go-wiki/services"
"github.com/rjNemo/go-wiki/views" "github.com/rjNemo/go-wiki/views"
) )
// type HomeHandler struct { // HomeHandler responds to requests using Handlers
// } type HomeHandler struct {
Ctx data.Context
}
func homeHandler(w http.ResponseWriter, r *http.Request) { func (hh HomeHandler) home(w http.ResponseWriter, r *http.Request) {
views.Template(w, "home", nil) index, err := hh.Ctx.Pages.GetAll()
if err != nil {
log.Fatal(err)
}
views.Template(w, "home", struct{ Wikis []models.Page }{index})
} }
func contactHandler(w http.ResponseWriter, r *http.Request) { func contactHandler(w http.ResponseWriter, r *http.Request) {

View file

@ -1,6 +1,7 @@
package controllers package controllers
import ( import (
"log"
"net/http" "net/http"
"github.com/rjNemo/go-wiki/data" "github.com/rjNemo/go-wiki/data"
@ -11,7 +12,7 @@ import (
// PageHandler will respond to requests using Handlers // PageHandler will respond to requests using Handlers
type PageHandler struct { type PageHandler struct {
Ctx data.Context Ctx data.Context
} //and add each actual handler as a method }
// func viewHandler(w http.ResponseWriter, r *http.Request, title string) { // func viewHandler(w http.ResponseWriter, r *http.Request, title string) {
func (ph PageHandler) view(w http.ResponseWriter, r *http.Request, title string) { func (ph PageHandler) view(w http.ResponseWriter, r *http.Request, title string) {
@ -35,13 +36,17 @@ func (ph PageHandler) edit(w http.ResponseWriter, r *http.Request, title string)
func (ph PageHandler) save(w http.ResponseWriter, r *http.Request, title string) { func (ph PageHandler) save(w http.ResponseWriter, r *http.Request, title string) {
body := r.FormValue("body") body := r.FormValue("body")
p := models.NewPage(0, title, []byte(body))
// err := p.Save()
if !ph.Ctx.Pages.Exists(title) { if !ph.Ctx.Pages.Exists(title) {
p := models.NewPage(0, title, []byte(body))
ph.Ctx.Pages.Add(*p) ph.Ctx.Pages.Add(*p)
} else { } else {
ph.Ctx.Pages.Update(p.ID(), *p) p, err := ph.Ctx.Pages.Get(title)
if err != nil {
log.Fatal(err)
}
p.SetBody([]byte(body))
ph.Ctx.Pages.Update(p.ID(), p)
} }
// checkError(err, w) // checkError(err, w)

View file

@ -6,13 +6,13 @@ import (
) )
// Router dispatch the request to the corresponding route handlers. // Router dispatch the request to the corresponding route handlers.
func Router(ph PageHandler) { func Router(ph PageHandler, hh HomeHandler) {
// http.HandleFunc("/", loveHandler) // http.HandleFunc("/", loveHandler)
http.HandleFunc("/view/", makeHandler(ph.view)) http.HandleFunc("/view/", makeHandler(ph.view))
http.HandleFunc("/edit/", makeHandler(ph.edit)) http.HandleFunc("/edit/", makeHandler(ph.edit))
http.HandleFunc("/save/", makeHandler(ph.save)) http.HandleFunc("/save/", makeHandler(ph.save))
http.HandleFunc("/contact/", contactHandler) http.HandleFunc("/contact/", contactHandler)
http.HandleFunc("/", homeHandler) http.HandleFunc("/", hh.home)
} }
func makeHandler(fn func(http.ResponseWriter, *http.Request, string)) http.HandlerFunc { func makeHandler(fn func(http.ResponseWriter, *http.Request, string)) http.HandlerFunc {

View file

@ -3,6 +3,7 @@ package data
import ( import (
"database/sql" "database/sql"
"log" "log"
"strings"
"github.com/rjNemo/go-wiki/models" "github.com/rjNemo/go-wiki/models"
) )
@ -18,20 +19,20 @@ func NewPageStore(db *sql.DB) PageStore {
} }
// CreateTable creates the page table in the database if it exits not yet. // CreateTable creates the page table in the database if it exits not yet.
func (us PageStore) CreateTable() { func (ps PageStore) CreateTable() {
if _, err := us.db.Exec(CreateTablePages); err != nil { if _, err := ps.db.Exec(CreateTablePages); err != nil {
log.Fatal(err) log.Fatal(err)
} }
// log.Print("Table successfully created!") // log.Print("Table successfully created!")
} }
// GetAll retrieves all the pages from the database. // GetAll retrieves all the pages from the database.
func (us PageStore) GetAll() ([]models.Page, error) { func (ps PageStore) GetAll() ([]models.Page, error) {
var id int var id int
var title string var title string
var body []byte var body []byte
rows, err := us.db.Query(GetAllPages) rows, err := ps.db.Query(GetAllPages)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -49,12 +50,12 @@ func (us PageStore) GetAll() ([]models.Page, error) {
} }
// Get retrieves the page identified by 'id' from database // Get retrieves the page identified by 'id' from database
func (us PageStore) Get(t string) (models.Page, error) { func (ps PageStore) Get(t string) (models.Page, error) {
var id int var id int
var title string var title string
var body []byte var body []byte
t = strings.Title(t)
row := us.db.QueryRow(GetPage, t) row := ps.db.QueryRow(GetPage, t)
switch err := row.Scan(&id, &title, &body); err { switch err := row.Scan(&id, &title, &body); err {
case sql.ErrNoRows: case sql.ErrNoRows:
log.Println("No entry returned") log.Println("No entry returned")
@ -68,9 +69,9 @@ func (us PageStore) Get(t string) (models.Page, error) {
} }
// Add inserts a page in the database. // Add inserts a page in the database.
func (us PageStore) Add(u models.Page) { func (ps PageStore) Add(u models.Page) {
id := 0 id := 0
err := us.db.QueryRow(InsertPage, u.Title(), u.Body()).Scan(&id) err := ps.db.QueryRow(InsertPage, u.Title(), u.Body()).Scan(&id)
if err != nil { if err != nil {
log.Fatal(err) // too severe log.Fatal(err) // too severe
} }
@ -78,8 +79,8 @@ func (us PageStore) Add(u models.Page) {
} }
// Update edits page identified by 'id' in the database // Update edits page identified by 'id' in the database
func (us PageStore) Update(id int, u models.Page) { func (ps PageStore) Update(id int, u models.Page) {
res, err := us.db.Exec(UpdatePage, id, u.Title(), u.Body()) res, err := ps.db.Exec(UpdatePage, id, u.Title(), string(u.Body()))
if err != nil { if err != nil {
log.Fatal(err) // too severe log.Fatal(err) // too severe
} }
@ -93,8 +94,8 @@ func (us PageStore) Update(id int, u models.Page) {
} }
// Delete removes page identified by 'id' from the database // Delete removes page identified by 'id' from the database
func (us PageStore) Delete(id int) { func (ps PageStore) Delete(id int) {
res, err := us.db.Exec(QueryDelete, id) res, err := ps.db.Exec(QueryDelete, id)
if err != nil { if err != nil {
log.Fatal(err) // too severe log.Fatal(err) // too severe
} }
@ -107,22 +108,21 @@ func (us PageStore) Delete(id int) {
} }
} }
func (ps PageStore) Exists(title string) bool { // Exists returns true if the page named title exists, false otherwise
var e bool func (ps PageStore) Exists(title string) (e bool) {
err := ps.db.QueryRow(ExistsPage, title).Scan(&e) err := ps.db.QueryRow(ExistsPage, strings.Title(title)).Scan(&e)
log.Println("e:", e)
if err != nil { if err != nil {
log.Fatal(err) // too severe log.Fatal(err) // too severe
} }
return e //== title return e
} }
// Find retrieves a page from the database using an expression // Find retrieves a page from the database using an expression
// func (us PageStore) Find(k interface{}, v interface{}) ([]models.Page, error) { // func (ps PageStore) Find(k interface{}, v interface{}) ([]models.Page, error) {
// var id, title int // var id, title int
// var body, lastName, email string // var body, lastName, email string
// rows, err := us.db.Query(QueryFind, k, v) // rows, err := ps.db.Query(QueryFind, k, v)
// if err != nil { // if err != nil {
// return nil, err // return nil, err
// } // }

14
main.go
View file

@ -10,6 +10,7 @@ import (
) )
func main() { func main() {
log.Println("*** Go-wiki v0.1 ©2020 ***")
// connect to db // connect to db
db, err := data.NewDB(settings.ConnStr) db, err := data.NewDB(settings.ConnStr)
if err != nil { if err != nil {
@ -18,20 +19,19 @@ func main() {
// register store and inject them in handlers // register store and inject them in handlers
ctx := data.NewContext(db) ctx := data.NewContext(db)
// Migrate db …
ctx.Pages.CreateTable() ctx.Pages.CreateTable()
// ctx.Users.CreateTable() // ctx.Users.CreateTable()
// create handlers around context
hh := controllers.HomeHandler{Ctx: ctx}
ph := controllers.PageHandler{Ctx: ctx} ph := controllers.PageHandler{Ctx: ctx}
// uh := controllers.UserHandler{Users: UserStore} // uh := controllers.UserHandler{Users: UserStore}
// startServer(, controllers.Router) // startServer
log.Printf("Start Go-wiki server on http://localhost:%s", settings.Port) log.Printf("Start Go-wiki server on http://localhost:%s", settings.Port)
port := ":" + settings.Port port := ":" + settings.Port
controllers.Router(ph) controllers.Router(ph, hh)
log.Fatal(http.ListenAndServe(port, nil)) log.Fatal(http.ListenAndServe(port, nil))
} }
// func startServer(p string, r func()) {
// }
// // appBuilder

View file

@ -2,6 +2,7 @@ package models
import ( import (
"io/ioutil" "io/ioutil"
"strings"
) )
// A Page own a wiki page data and has a title and a body. // A Page own a wiki page data and has a title and a body.
@ -43,14 +44,17 @@ func BlankPage() *Page {
// NewPage constructor returns a pointer to a sample Page. // NewPage constructor returns a pointer to a sample Page.
func NewPage(id int, title string, body []byte) *Page { func NewPage(id int, title string, body []byte) *Page {
return &Page{id: id, title: title, body: body} return &Page{
id: id,
title: strings.Title(title),
body: body}
} }
// Save a page to the 'data/' folder in txt format. // Save a page to the 'data/' folder in txt format.
func (p *Page) Save() error { // func (p *Page) Save() error {
fileName := "data/files/" + p.title + ".txt" // fileName := "data/files/" + p.title + ".txt"
return ioutil.WriteFile(fileName, p.body, 0600) // return ioutil.WriteFile(fileName, p.body, 0600)
} // }
// LoadPage reads a saved page data and returns a pointer to the Page. // LoadPage reads a saved page data and returns a pointer to the Page.
func LoadPage(title string) (*Page, error) { func LoadPage(title string) (*Page, error) {

View file

@ -30,8 +30,7 @@ func NewUser(id, age int, first, last, email string) User {
firstName: strings.Title(first), firstName: strings.Title(first),
lastName: strings.Title(last), lastName: strings.Title(last),
email: strings.ToLower(email), email: strings.ToLower(email),
age: age, age: age}
}
} }
// ID is a getter // ID is a getter

View file

@ -14,5 +14,16 @@
>Documentation</a >Documentation</a
> >
</div> </div>
<div>
<h2>Index</h2>
<p>Some description</p>
<ul>
{{ range $index, $entry := .Wikis }}
<li>
{{ $index }}: <a href="/view/{{ $entry.Title }}">{{ $entry.Title }}</a>
</li>
{{ end }}
</ul>
</div>
</div> </div>
{{end}} {{end}}