commit 3c55ad2713c20828d324cc9d32e1cf0846e16c7e Author: Daniel Cortés Date: Wed Apr 17 12:36:31 2019 -0400 projecto completo creo, me quedo bonito :3 diff --git a/database.go b/database.go new file mode 100644 index 0000000..6e88f32 --- /dev/null +++ b/database.go @@ -0,0 +1,141 @@ +package main + +import ( + "database/sql" + _ "github.com/mattn/go-sqlite3" + "todo/models" +) + +type DatabaseInterface interface { + GetTodos() ([]models.Todo, error) + GetTodo(int) (models.Todo, error) + CreateTodo(models.Todo) error + DoTodo(int) error + UndoTodo(int) error + DeleteTodo(int) error +} + +type DatabaseStore struct { + DB *sql.DB +} + +func MustNewDB() *DatabaseStore { + db, err := sql.Open("sqlite3", "./database.sqlite") + if err != nil { + panic(err) + } + + err = db.Ping() + if err != nil { + panic(err) + } + + return &DatabaseStore{db} +} + +func (store *DatabaseStore) GetTodos() ([]models.Todo, error) { + selectAll := `select id, todo, done from todo` + + rows, err := store.DB.Query(selectAll) + if err != nil { + return []models.Todo{}, err + } + defer rows.Close() + + todos := []models.Todo{} + for rows.Next() { + todo := models.Todo{} + err = rows.Scan(&todo.Id, &todo.Todo, &todo.Done) + if err != nil { + return []models.Todo{}, err + } + todos = append(todos, todo) + } + + return todos, nil +} + +func (store *DatabaseStore) GetTodo(id int) (models.Todo, error) { + selectOne := `select id, todo, done from todo where id = ?` + + var todo models.Todo + err := store.DB.QueryRow(selectOne, id).Scan(&todo.Id, &todo.Todo, &todo.Done) + if err != nil { + return models.Todo{}, err + } + + return todo, nil +} + +func (store *DatabaseStore) CreateTodo(todo models.Todo) error { + createTodo := `insert into todo (todo, done) values (?, ?)` + + statement, err := store.DB.Prepare(createTodo) + if err != nil { + return err + } + defer statement.Close() + + _, err = statement.Exec(todo.Todo, false) + if err != nil { + return err + } + + return nil +} + +func (store *DatabaseStore) ToggleTodo(id int) error { + todo, err := store.GetTodo(id) + if err != nil { + return err + } + + setDone := `update todo set done = ? where id = ?` + + statement, err := store.DB.Prepare(setDone) + if err != nil { + return err + } + defer statement.Close() + + _, err = statement.Exec(!todo.Done, id) + if err != nil { + return err + } + + return nil +} + +func (store *DatabaseStore) UpdateTodo(todo models.Todo) error { + updateTodo := `update todo set todo = ? where id = ?` + + statement, err := store.DB.Prepare(updateTodo) + if err != nil { + return err + } + defer statement.Close() + + _, err = statement.Exec(todo.Todo, todo.Id) + if err != nil { + return err + } + + return nil +} + +func (store *DatabaseStore) DeleteTodo(id int) error { + deleteTodo := `delete from todo where id = ?` + + statement, err := store.DB.Prepare(deleteTodo) + if err != nil { + return err + } + defer statement.Close() + + _, err = statement.Exec(id) + if err != nil { + return err + } + + return nil +} diff --git a/database.sqlite b/database.sqlite new file mode 100644 index 0000000..10be574 Binary files /dev/null and b/database.sqlite differ diff --git a/file_server.go b/file_server.go new file mode 100644 index 0000000..2fe6ca3 --- /dev/null +++ b/file_server.go @@ -0,0 +1,20 @@ +package main + +import ( + "github.com/go-chi/chi" + "net/http" +) + +func fileServer(r chi.Router, path string, root http.FileSystem) { + fs := http.StripPrefix(path, http.FileServer(root)) + + if path != "/" && path[len(path)-1] != '/' { + r.Get(path, http.RedirectHandler(path+"/", 301).ServeHTTP) + path += "/" + } + path += "*" + + r.Get(path, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + fs.ServeHTTP(w, r) + })) +} diff --git a/handler.go b/handler.go new file mode 100644 index 0000000..b5cc70d --- /dev/null +++ b/handler.go @@ -0,0 +1,108 @@ +package main + +import ( + "net/http" + "todo/templates" + "todo/models" + "strconv" + "github.com/go-chi/chi" +) + +var store = MustNewDB() + +func indexHandler(w http.ResponseWriter, r *http.Request) { + todos, err := store.GetTodos() + if err != nil { + templates.WritePage(w, &templates.Error500Page{"Error al intentar obtener todos los TODO", err.Error()}) + return + } + + templates.WritePage(w, &templates.IndexPage{todos}) +} + +func createHandler(w http.ResponseWriter, r *http.Request) { + r.ParseForm() + todo := models.Todo{Id: 0, Todo: r.FormValue("todo"), Done: false} + err := store.CreateTodo(todo) + + if err != nil { + templates.WritePage(w, &templates.Error500Page{"Error al intentar crear un nuevo TODO", err.Error()}) + return + } + http.Redirect(w, r, "/", http.StatusSeeOther) +} + +func toggleHandler(w http.ResponseWriter, r *http.Request) { + id, err := strconv.Atoi(chi.URLParam(r, "id")) + if err != nil { + templates.WritePage(w, &templates.Error500Page{"El id entregado es invalido", err.Error()}) + return + } + + err = store.ToggleTodo(id) + if err != nil { + templates.WritePage(w, &templates.Error500Page{"Error al actualizar el TODO", err.Error()}) + return + } + + http.Redirect(w, r, "/", http.StatusSeeOther) +} + +func deleteHandler(w http.ResponseWriter, r *http.Request) { + id, err := strconv.Atoi(chi.URLParam(r, "id")) + if err != nil { + templates.WritePage(w, &templates.Error500Page{"El id entregado es invalido", err.Error()}) + return + } + + err = store.DeleteTodo(id) + if err != nil { + templates.WritePage(w, &templates.Error500Page{"Error al eliminar el TODO", err.Error()}) + return + } + + http.Redirect(w, r, "/", http.StatusSeeOther) +} + +func editHandler(w http.ResponseWriter, r *http.Request) { + id, err := strconv.Atoi(chi.URLParam(r, "id")) + if err != nil { + templates.WritePage(w, &templates.Error500Page{"El id entregado es invalido", err.Error()}) + return + } + + todos, err := store.GetTodos() + if err != nil { + templates.WritePage(w, &templates.Error500Page{"Error al intentar obtener todos los TODO", err.Error()}) + return + } + editingTodo, err := store.GetTodo(id) + if err != nil { + templates.WritePage(w, &templates.Error500Page{"Error al intentar obtener un TODO", err.Error()}) + return + } + + templates.WritePage(w, &templates.EditPage{todos, editingTodo}) +} + +func updateHandler(w http.ResponseWriter, r *http.Request) { + r.ParseForm() + + id, err := strconv.Atoi(chi.URLParam(r, "id")) + if err != nil { + templates.WritePage(w, &templates.Error500Page{"El id entregado es invalido", err.Error()}) + return + } + + message := r.FormValue("todo") + + todo := models.Todo{Id: id, Todo: message } + err = store.UpdateTodo(todo) + + if err != nil { + templates.WritePage(w, &templates.Error500Page{"Error al intentar actualizar un TODO", err.Error()}) + return + } + + http.Redirect(w, r, "/", http.StatusSeeOther) +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..21d0bac --- /dev/null +++ b/main.go @@ -0,0 +1,36 @@ +package main + +import ( + "github.com/go-chi/chi" + "github.com/go-chi/chi/middleware" + _ "github.com/mattn/go-sqlite3" + "log" + "net/http" + "os" + "path/filepath" +) + + +func main() { + log.Println("Launching TODO App") + log.Println("Generating the routes...") + + workDir, _ := os.Getwd() + filesDir := filepath.Join(workDir, "static") + + router := chi.NewRouter() + router.Use(middleware.Logger) + + router.Get("/", indexHandler) + router.Get("/edit/{id:[0-9]+}", editHandler) + + router.Post("/create", createHandler) + router.Post("/toggle/{id:[0-9]+}", toggleHandler) + router.Post("/update/{id:[0-9]+}", updateHandler) + router.Post("/delete/{id:[0-9]+}", deleteHandler) + + fileServer(router, "/static", http.Dir(filesDir)) + + log.Println("Serving the page on port 1337") + http.ListenAndServe(":1337", router) +} diff --git a/makefile b/makefile new file mode 100644 index 0000000..70a0751 --- /dev/null +++ b/makefile @@ -0,0 +1,6 @@ +templates/%.qtpl.go: templates/%.qtpl + cd templates; qtc +todo: *.go templates/*.go + go build +clean: + rm todo templates/*.qtpl.go diff --git a/models/todo.go b/models/todo.go new file mode 100644 index 0000000..5dbf71e --- /dev/null +++ b/models/todo.go @@ -0,0 +1,7 @@ +package models + +type Todo struct { + Id int + Todo string + Done bool +} diff --git a/static/custom.css b/static/custom.css new file mode 100644 index 0000000..7a072c1 --- /dev/null +++ b/static/custom.css @@ -0,0 +1,33 @@ +input[type=submit].button-green { + color:#FFF; + background-color:#30dd8d; + border-color:#30dd8d; +} + +input[type=submit].button-green:focus, +input[type=submit].button-green:hover { + color:#FFF; + background-color:#2ab775; + border-color:#2ab775; +} + +input[type=submit].button-red { + color:#FFF; + background-color:#f7474a; + border-color:#f7474a; +} + +input[type=submit].button-red:focus, +input[type=submit].button-red:hover { + color:#FFF; + background-color:#d33d3f; + border-color:#d33d3f; +} + +.title { + text-decoration: none; +} + +form { + margin-bottom: 0px; +} diff --git a/templates/500.qtpl b/templates/500.qtpl new file mode 100644 index 0000000..bf20961 --- /dev/null +++ b/templates/500.qtpl @@ -0,0 +1,25 @@ +{% code +type Error500Page struct { + Message string + Error string +} +%} + +{% func (p *Error500Page ) Title() %} +500 +{% endfunc %} + +{% func (p *Error500Page ) Stylesheets() %} + +{% endfunc %} + +{% func (p *Error500Page ) Scripts() %} +{% endfunc %} + +{% func (p *Error500Page ) Body() %} +
+

Error: 500

+

{%s p.Message %}

+

{%s p.Error %}

+
+{% endfunc %} diff --git a/templates/500.qtpl.go b/templates/500.qtpl.go new file mode 100644 index 0000000..ee82355 --- /dev/null +++ b/templates/500.qtpl.go @@ -0,0 +1,175 @@ +// This file is automatically generated by qtc from "500.qtpl". +// See https://github.com/valyala/quicktemplate for details. + +//line 500.qtpl:1 +package templates + +//line 500.qtpl:1 +import ( + qtio422016 "io" + + qt422016 "github.com/valyala/quicktemplate" +) + +//line 500.qtpl:1 +var ( + _ = qtio422016.Copy + _ = qt422016.AcquireByteBuffer +) + +//line 500.qtpl:2 +type Error500Page struct { + Message string + Error string +} + +//line 500.qtpl:8 +func (p *Error500Page) StreamTitle(qw422016 *qt422016.Writer) { + //line 500.qtpl:8 + qw422016.N().S(` +500 +`) +//line 500.qtpl:10 +} + +//line 500.qtpl:10 +func (p *Error500Page) WriteTitle(qq422016 qtio422016.Writer) { + //line 500.qtpl:10 + qw422016 := qt422016.AcquireWriter(qq422016) + //line 500.qtpl:10 + p.StreamTitle(qw422016) + //line 500.qtpl:10 + qt422016.ReleaseWriter(qw422016) +//line 500.qtpl:10 +} + +//line 500.qtpl:10 +func (p *Error500Page) Title() string { + //line 500.qtpl:10 + qb422016 := qt422016.AcquireByteBuffer() + //line 500.qtpl:10 + p.WriteTitle(qb422016) + //line 500.qtpl:10 + qs422016 := string(qb422016.B) + //line 500.qtpl:10 + qt422016.ReleaseByteBuffer(qb422016) + //line 500.qtpl:10 + return qs422016 +//line 500.qtpl:10 +} + +//line 500.qtpl:12 +func (p *Error500Page) StreamStylesheets(qw422016 *qt422016.Writer) { + //line 500.qtpl:12 + qw422016.N().S(` + +`) +//line 500.qtpl:14 +} + +//line 500.qtpl:14 +func (p *Error500Page) WriteStylesheets(qq422016 qtio422016.Writer) { + //line 500.qtpl:14 + qw422016 := qt422016.AcquireWriter(qq422016) + //line 500.qtpl:14 + p.StreamStylesheets(qw422016) + //line 500.qtpl:14 + qt422016.ReleaseWriter(qw422016) +//line 500.qtpl:14 +} + +//line 500.qtpl:14 +func (p *Error500Page) Stylesheets() string { + //line 500.qtpl:14 + qb422016 := qt422016.AcquireByteBuffer() + //line 500.qtpl:14 + p.WriteStylesheets(qb422016) + //line 500.qtpl:14 + qs422016 := string(qb422016.B) + //line 500.qtpl:14 + qt422016.ReleaseByteBuffer(qb422016) + //line 500.qtpl:14 + return qs422016 +//line 500.qtpl:14 +} + +//line 500.qtpl:16 +func (p *Error500Page) StreamScripts(qw422016 *qt422016.Writer) { + //line 500.qtpl:16 + qw422016.N().S(` +`) +//line 500.qtpl:17 +} + +//line 500.qtpl:17 +func (p *Error500Page) WriteScripts(qq422016 qtio422016.Writer) { + //line 500.qtpl:17 + qw422016 := qt422016.AcquireWriter(qq422016) + //line 500.qtpl:17 + p.StreamScripts(qw422016) + //line 500.qtpl:17 + qt422016.ReleaseWriter(qw422016) +//line 500.qtpl:17 +} + +//line 500.qtpl:17 +func (p *Error500Page) Scripts() string { + //line 500.qtpl:17 + qb422016 := qt422016.AcquireByteBuffer() + //line 500.qtpl:17 + p.WriteScripts(qb422016) + //line 500.qtpl:17 + qs422016 := string(qb422016.B) + //line 500.qtpl:17 + qt422016.ReleaseByteBuffer(qb422016) + //line 500.qtpl:17 + return qs422016 +//line 500.qtpl:17 +} + +//line 500.qtpl:19 +func (p *Error500Page) StreamBody(qw422016 *qt422016.Writer) { + //line 500.qtpl:19 + qw422016.N().S(` +
+

Error: 500

+

`) + //line 500.qtpl:22 + qw422016.E().S(p.Message) + //line 500.qtpl:22 + qw422016.N().S(`

+

`) + //line 500.qtpl:23 + qw422016.E().S(p.Error) + //line 500.qtpl:23 + qw422016.N().S(`

+
+`) +//line 500.qtpl:25 +} + +//line 500.qtpl:25 +func (p *Error500Page) WriteBody(qq422016 qtio422016.Writer) { + //line 500.qtpl:25 + qw422016 := qt422016.AcquireWriter(qq422016) + //line 500.qtpl:25 + p.StreamBody(qw422016) + //line 500.qtpl:25 + qt422016.ReleaseWriter(qw422016) +//line 500.qtpl:25 +} + +//line 500.qtpl:25 +func (p *Error500Page) Body() string { + //line 500.qtpl:25 + qb422016 := qt422016.AcquireByteBuffer() + //line 500.qtpl:25 + p.WriteBody(qb422016) + //line 500.qtpl:25 + qs422016 := string(qb422016.B) + //line 500.qtpl:25 + qt422016.ReleaseByteBuffer(qb422016) + //line 500.qtpl:25 + return qs422016 +//line 500.qtpl:25 +} diff --git a/templates/base.qtpl b/templates/base.qtpl new file mode 100644 index 0000000..09cccde --- /dev/null +++ b/templates/base.qtpl @@ -0,0 +1,31 @@ +{% interface PageImpl { + Title() + Stylesheets() + Scripts() + Body() +} +%} + +{% func Page(p PageImpl) %} + + + + + {%= p.Title() %} + {%= p.Stylesheets() %} + {%= p.Scripts() %} + + + +{%= p.Body() %} + + +{% endfunc %} + +{% func GetDoneButton(done bool) %} + {% if done %} + + {% else %} + + {% endif %} +{% endfunc %} diff --git a/templates/base.qtpl.go b/templates/base.qtpl.go new file mode 100644 index 0000000..fe09280 --- /dev/null +++ b/templates/base.qtpl.go @@ -0,0 +1,161 @@ +// This file is automatically generated by qtc from "base.qtpl". +// See https://github.com/valyala/quicktemplate for details. + +//line base.qtpl:1 +package templates + +//line base.qtpl:1 +import ( + qtio422016 "io" + + qt422016 "github.com/valyala/quicktemplate" +) + +//line base.qtpl:1 +var ( + _ = qtio422016.Copy + _ = qt422016.AcquireByteBuffer +) + +//line base.qtpl:1 +type PageImpl interface { + //line base.qtpl:1 + Title() string + //line base.qtpl:1 + StreamTitle(qw422016 *qt422016.Writer) + //line base.qtpl:1 + WriteTitle(qq422016 qtio422016.Writer) + //line base.qtpl:1 + Stylesheets() string + //line base.qtpl:1 + StreamStylesheets(qw422016 *qt422016.Writer) + //line base.qtpl:1 + WriteStylesheets(qq422016 qtio422016.Writer) + //line base.qtpl:1 + Scripts() string + //line base.qtpl:1 + StreamScripts(qw422016 *qt422016.Writer) + //line base.qtpl:1 + WriteScripts(qq422016 qtio422016.Writer) + //line base.qtpl:1 + Body() string + //line base.qtpl:1 + StreamBody(qw422016 *qt422016.Writer) + //line base.qtpl:1 + WriteBody(qq422016 qtio422016.Writer) +//line base.qtpl:1 +} + +//line base.qtpl:9 +func StreamPage(qw422016 *qt422016.Writer, p PageImpl) { + //line base.qtpl:9 + qw422016.N().S(` + + + + + `) + //line base.qtpl:14 + p.StreamTitle(qw422016) + //line base.qtpl:14 + qw422016.N().S(` + `) + //line base.qtpl:15 + p.StreamStylesheets(qw422016) + //line base.qtpl:15 + qw422016.N().S(` + `) + //line base.qtpl:16 + p.StreamScripts(qw422016) + //line base.qtpl:16 + qw422016.N().S(` + + + +`) + //line base.qtpl:20 + p.StreamBody(qw422016) + //line base.qtpl:20 + qw422016.N().S(` + + +`) +//line base.qtpl:23 +} + +//line base.qtpl:23 +func WritePage(qq422016 qtio422016.Writer, p PageImpl) { + //line base.qtpl:23 + qw422016 := qt422016.AcquireWriter(qq422016) + //line base.qtpl:23 + StreamPage(qw422016, p) + //line base.qtpl:23 + qt422016.ReleaseWriter(qw422016) +//line base.qtpl:23 +} + +//line base.qtpl:23 +func Page(p PageImpl) string { + //line base.qtpl:23 + qb422016 := qt422016.AcquireByteBuffer() + //line base.qtpl:23 + WritePage(qb422016, p) + //line base.qtpl:23 + qs422016 := string(qb422016.B) + //line base.qtpl:23 + qt422016.ReleaseByteBuffer(qb422016) + //line base.qtpl:23 + return qs422016 +//line base.qtpl:23 +} + +//line base.qtpl:25 +func StreamGetDoneButton(qw422016 *qt422016.Writer, done bool) { + //line base.qtpl:25 + qw422016.N().S(` + `) + //line base.qtpl:26 + if done { + //line base.qtpl:26 + qw422016.N().S(` + + `) + //line base.qtpl:28 + } else { + //line base.qtpl:28 + qw422016.N().S(` + + `) + //line base.qtpl:30 + } + //line base.qtpl:30 + qw422016.N().S(` +`) +//line base.qtpl:31 +} + +//line base.qtpl:31 +func WriteGetDoneButton(qq422016 qtio422016.Writer, done bool) { + //line base.qtpl:31 + qw422016 := qt422016.AcquireWriter(qq422016) + //line base.qtpl:31 + StreamGetDoneButton(qw422016, done) + //line base.qtpl:31 + qt422016.ReleaseWriter(qw422016) +//line base.qtpl:31 +} + +//line base.qtpl:31 +func GetDoneButton(done bool) string { + //line base.qtpl:31 + qb422016 := qt422016.AcquireByteBuffer() + //line base.qtpl:31 + WriteGetDoneButton(qb422016, done) + //line base.qtpl:31 + qs422016 := string(qb422016.B) + //line base.qtpl:31 + qt422016.ReleaseByteBuffer(qb422016) + //line base.qtpl:31 + return qs422016 +//line base.qtpl:31 +} diff --git a/templates/edit.qtpl b/templates/edit.qtpl new file mode 100644 index 0000000..7a96bca --- /dev/null +++ b/templates/edit.qtpl @@ -0,0 +1,67 @@ +{% import "todo/models" %} + +{% code +type EditPage struct { + Todos []models.Todo + EditingTodo models.Todo +} +%} + +{% func (p *EditPage ) Title() %} +Todo +{% endfunc %} + +{% func (p *EditPage ) Stylesheets() %} + + +{% endfunc %} + +{% func (p *EditPage ) Scripts() %} +{% endfunc %} + +{% func (p *EditPage ) Body() %} +
+

TODO in Golang

+
+
+
+ +
+
+ +
+
+
+ + {% for _, todo := range p.Todos %} +
+
+
+ {%= GetDoneButton(todo.Done) %} +
+
+
+

{%s todo.Todo %}

+
+ {% if todo.Id == p.EditingTodo.Id %} +
+ +
+ {% else %} +
+
+ +
+
+ {% endif %} +
+
+ +
+
+
+ {% endfor %} + +
+{% endfunc %} + diff --git a/templates/edit.qtpl.go b/templates/edit.qtpl.go new file mode 100644 index 0000000..4e77bea --- /dev/null +++ b/templates/edit.qtpl.go @@ -0,0 +1,257 @@ +// This file is automatically generated by qtc from "edit.qtpl". +// See https://github.com/valyala/quicktemplate for details. + +//line edit.qtpl:1 +package templates + +//line edit.qtpl:1 +import "todo/models" + +//line edit.qtpl:3 +import ( + qtio422016 "io" + + qt422016 "github.com/valyala/quicktemplate" +) + +//line edit.qtpl:3 +var ( + _ = qtio422016.Copy + _ = qt422016.AcquireByteBuffer +) + +//line edit.qtpl:4 +type EditPage struct { + Todos []models.Todo + EditingTodo models.Todo +} + +//line edit.qtpl:10 +func (p *EditPage) StreamTitle(qw422016 *qt422016.Writer) { + //line edit.qtpl:10 + qw422016.N().S(` +Todo +`) +//line edit.qtpl:12 +} + +//line edit.qtpl:12 +func (p *EditPage) WriteTitle(qq422016 qtio422016.Writer) { + //line edit.qtpl:12 + qw422016 := qt422016.AcquireWriter(qq422016) + //line edit.qtpl:12 + p.StreamTitle(qw422016) + //line edit.qtpl:12 + qt422016.ReleaseWriter(qw422016) +//line edit.qtpl:12 +} + +//line edit.qtpl:12 +func (p *EditPage) Title() string { + //line edit.qtpl:12 + qb422016 := qt422016.AcquireByteBuffer() + //line edit.qtpl:12 + p.WriteTitle(qb422016) + //line edit.qtpl:12 + qs422016 := string(qb422016.B) + //line edit.qtpl:12 + qt422016.ReleaseByteBuffer(qb422016) + //line edit.qtpl:12 + return qs422016 +//line edit.qtpl:12 +} + +//line edit.qtpl:14 +func (p *EditPage) StreamStylesheets(qw422016 *qt422016.Writer) { + //line edit.qtpl:14 + qw422016.N().S(` + + +`) +//line edit.qtpl:17 +} + +//line edit.qtpl:17 +func (p *EditPage) WriteStylesheets(qq422016 qtio422016.Writer) { + //line edit.qtpl:17 + qw422016 := qt422016.AcquireWriter(qq422016) + //line edit.qtpl:17 + p.StreamStylesheets(qw422016) + //line edit.qtpl:17 + qt422016.ReleaseWriter(qw422016) +//line edit.qtpl:17 +} + +//line edit.qtpl:17 +func (p *EditPage) Stylesheets() string { + //line edit.qtpl:17 + qb422016 := qt422016.AcquireByteBuffer() + //line edit.qtpl:17 + p.WriteStylesheets(qb422016) + //line edit.qtpl:17 + qs422016 := string(qb422016.B) + //line edit.qtpl:17 + qt422016.ReleaseByteBuffer(qb422016) + //line edit.qtpl:17 + return qs422016 +//line edit.qtpl:17 +} + +//line edit.qtpl:19 +func (p *EditPage) StreamScripts(qw422016 *qt422016.Writer) { + //line edit.qtpl:19 + qw422016.N().S(` +`) +//line edit.qtpl:20 +} + +//line edit.qtpl:20 +func (p *EditPage) WriteScripts(qq422016 qtio422016.Writer) { + //line edit.qtpl:20 + qw422016 := qt422016.AcquireWriter(qq422016) + //line edit.qtpl:20 + p.StreamScripts(qw422016) + //line edit.qtpl:20 + qt422016.ReleaseWriter(qw422016) +//line edit.qtpl:20 +} + +//line edit.qtpl:20 +func (p *EditPage) Scripts() string { + //line edit.qtpl:20 + qb422016 := qt422016.AcquireByteBuffer() + //line edit.qtpl:20 + p.WriteScripts(qb422016) + //line edit.qtpl:20 + qs422016 := string(qb422016.B) + //line edit.qtpl:20 + qt422016.ReleaseByteBuffer(qb422016) + //line edit.qtpl:20 + return qs422016 +//line edit.qtpl:20 +} + +//line edit.qtpl:22 +func (p *EditPage) StreamBody(qw422016 *qt422016.Writer) { + //line edit.qtpl:22 + qw422016.N().S(` +
+

TODO in Golang

+
+
+
+ +
+
+ +
+
+
+ + `) + //line edit.qtpl:36 + for _, todo := range p.Todos { + //line edit.qtpl:36 + qw422016.N().S(` +
+
+
+ `) + //line edit.qtpl:40 + StreamGetDoneButton(qw422016, todo.Done) + //line edit.qtpl:40 + qw422016.N().S(` +
+
+
+

`) + //line edit.qtpl:44 + qw422016.E().S(todo.Todo) + //line edit.qtpl:44 + qw422016.N().S(`

+
+ `) + //line edit.qtpl:46 + if todo.Id == p.EditingTodo.Id { + //line edit.qtpl:46 + qw422016.N().S(` +
+ +
+ `) + //line edit.qtpl:50 + } else { + //line edit.qtpl:50 + qw422016.N().S(` +
+
+ +
+
+ `) + //line edit.qtpl:56 + } + //line edit.qtpl:56 + qw422016.N().S(` +
+
+ +
+
+
+ `) + //line edit.qtpl:63 + } + //line edit.qtpl:63 + qw422016.N().S(` + +
+`) +//line edit.qtpl:66 +} + +//line edit.qtpl:66 +func (p *EditPage) WriteBody(qq422016 qtio422016.Writer) { + //line edit.qtpl:66 + qw422016 := qt422016.AcquireWriter(qq422016) + //line edit.qtpl:66 + p.StreamBody(qw422016) + //line edit.qtpl:66 + qt422016.ReleaseWriter(qw422016) +//line edit.qtpl:66 +} + +//line edit.qtpl:66 +func (p *EditPage) Body() string { + //line edit.qtpl:66 + qb422016 := qt422016.AcquireByteBuffer() + //line edit.qtpl:66 + p.WriteBody(qb422016) + //line edit.qtpl:66 + qs422016 := string(qb422016.B) + //line edit.qtpl:66 + qt422016.ReleaseByteBuffer(qb422016) + //line edit.qtpl:66 + return qs422016 +//line edit.qtpl:66 +} diff --git a/templates/index.qtpl b/templates/index.qtpl new file mode 100644 index 0000000..fe13710 --- /dev/null +++ b/templates/index.qtpl @@ -0,0 +1,59 @@ +{% import "todo/models" %} + +{% code +type IndexPage struct { + Todos []models.Todo +} +%} + +{% func (p *IndexPage ) Title() %} +Todo +{% endfunc %} + +{% func (p *IndexPage ) Stylesheets() %} + + +{% endfunc %} + +{% func (p *IndexPage ) Scripts() %} +{% endfunc %} + +{% func (p *IndexPage ) Body() %} +
+

TODO in Golang

+
+
+
+ +
+
+ +
+
+
+ + {% for _, todo := range p.Todos %} +
+
+
+ {%= GetDoneButton(todo.Done) %} +
+
+
+

{%s todo.Todo %}

+
+
+
+ +
+
+
+
+ +
+
+
+ {% endfor %} + +
+{% endfunc %} diff --git a/templates/index.qtpl.go b/templates/index.qtpl.go new file mode 100644 index 0000000..c72ee16 --- /dev/null +++ b/templates/index.qtpl.go @@ -0,0 +1,230 @@ +// This file is automatically generated by qtc from "index.qtpl". +// See https://github.com/valyala/quicktemplate for details. + +//line index.qtpl:1 +package templates + +//line index.qtpl:1 +import "todo/models" + +//line index.qtpl:3 +import ( + qtio422016 "io" + + qt422016 "github.com/valyala/quicktemplate" +) + +//line index.qtpl:3 +var ( + _ = qtio422016.Copy + _ = qt422016.AcquireByteBuffer +) + +//line index.qtpl:4 +type IndexPage struct { + Todos []models.Todo +} + +//line index.qtpl:9 +func (p *IndexPage) StreamTitle(qw422016 *qt422016.Writer) { + //line index.qtpl:9 + qw422016.N().S(` +Todo +`) +//line index.qtpl:11 +} + +//line index.qtpl:11 +func (p *IndexPage) WriteTitle(qq422016 qtio422016.Writer) { + //line index.qtpl:11 + qw422016 := qt422016.AcquireWriter(qq422016) + //line index.qtpl:11 + p.StreamTitle(qw422016) + //line index.qtpl:11 + qt422016.ReleaseWriter(qw422016) +//line index.qtpl:11 +} + +//line index.qtpl:11 +func (p *IndexPage) Title() string { + //line index.qtpl:11 + qb422016 := qt422016.AcquireByteBuffer() + //line index.qtpl:11 + p.WriteTitle(qb422016) + //line index.qtpl:11 + qs422016 := string(qb422016.B) + //line index.qtpl:11 + qt422016.ReleaseByteBuffer(qb422016) + //line index.qtpl:11 + return qs422016 +//line index.qtpl:11 +} + +//line index.qtpl:13 +func (p *IndexPage) StreamStylesheets(qw422016 *qt422016.Writer) { + //line index.qtpl:13 + qw422016.N().S(` + + +`) +//line index.qtpl:16 +} + +//line index.qtpl:16 +func (p *IndexPage) WriteStylesheets(qq422016 qtio422016.Writer) { + //line index.qtpl:16 + qw422016 := qt422016.AcquireWriter(qq422016) + //line index.qtpl:16 + p.StreamStylesheets(qw422016) + //line index.qtpl:16 + qt422016.ReleaseWriter(qw422016) +//line index.qtpl:16 +} + +//line index.qtpl:16 +func (p *IndexPage) Stylesheets() string { + //line index.qtpl:16 + qb422016 := qt422016.AcquireByteBuffer() + //line index.qtpl:16 + p.WriteStylesheets(qb422016) + //line index.qtpl:16 + qs422016 := string(qb422016.B) + //line index.qtpl:16 + qt422016.ReleaseByteBuffer(qb422016) + //line index.qtpl:16 + return qs422016 +//line index.qtpl:16 +} + +//line index.qtpl:18 +func (p *IndexPage) StreamScripts(qw422016 *qt422016.Writer) { + //line index.qtpl:18 + qw422016.N().S(` +`) +//line index.qtpl:19 +} + +//line index.qtpl:19 +func (p *IndexPage) WriteScripts(qq422016 qtio422016.Writer) { + //line index.qtpl:19 + qw422016 := qt422016.AcquireWriter(qq422016) + //line index.qtpl:19 + p.StreamScripts(qw422016) + //line index.qtpl:19 + qt422016.ReleaseWriter(qw422016) +//line index.qtpl:19 +} + +//line index.qtpl:19 +func (p *IndexPage) Scripts() string { + //line index.qtpl:19 + qb422016 := qt422016.AcquireByteBuffer() + //line index.qtpl:19 + p.WriteScripts(qb422016) + //line index.qtpl:19 + qs422016 := string(qb422016.B) + //line index.qtpl:19 + qt422016.ReleaseByteBuffer(qb422016) + //line index.qtpl:19 + return qs422016 +//line index.qtpl:19 +} + +//line index.qtpl:21 +func (p *IndexPage) StreamBody(qw422016 *qt422016.Writer) { + //line index.qtpl:21 + qw422016.N().S(` +
+

TODO in Golang

+
+
+
+ +
+
+ +
+
+
+ + `) + //line index.qtpl:35 + for _, todo := range p.Todos { + //line index.qtpl:35 + qw422016.N().S(` +
+
+
+ `) + //line index.qtpl:39 + StreamGetDoneButton(qw422016, todo.Done) + //line index.qtpl:39 + qw422016.N().S(` +
+
+
+

`) + //line index.qtpl:43 + qw422016.E().S(todo.Todo) + //line index.qtpl:43 + qw422016.N().S(`

+
+
+
+ +
+
+
+
+ +
+
+
+ `) + //line index.qtpl:56 + } + //line index.qtpl:56 + qw422016.N().S(` + +
+`) +//line index.qtpl:59 +} + +//line index.qtpl:59 +func (p *IndexPage) WriteBody(qq422016 qtio422016.Writer) { + //line index.qtpl:59 + qw422016 := qt422016.AcquireWriter(qq422016) + //line index.qtpl:59 + p.StreamBody(qw422016) + //line index.qtpl:59 + qt422016.ReleaseWriter(qw422016) +//line index.qtpl:59 +} + +//line index.qtpl:59 +func (p *IndexPage) Body() string { + //line index.qtpl:59 + qb422016 := qt422016.AcquireByteBuffer() + //line index.qtpl:59 + p.WriteBody(qb422016) + //line index.qtpl:59 + qs422016 := string(qb422016.B) + //line index.qtpl:59 + qt422016.ReleaseByteBuffer(qb422016) + //line index.qtpl:59 + return qs422016 +//line index.qtpl:59 +} diff --git a/todo b/todo new file mode 100755 index 0000000..3ff7e27 Binary files /dev/null and b/todo differ