// SetPost sets the post with the id in the url in the context and template data. func (m *Middleware) SetPost(next http.Handler) http.Handler { fn := func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) postID, err := strconv.ParseInt(vars["postID"], 10, 64) if err != nil { httperror.HandleError(w, httperror.StatusError{http.StatusBadRequest, err}) return } pm := models.NewPostModel(m.App.DB) topic := context.Topic(r) post, err := pm.FindOne(nil, squirrel.Eq{"posts.id": postID, "posts.topic_id": topic.ID}) if err != nil { httperror.HandleError(w, errors.Wrap(err, "find one error")) return } context.SetPost(r, post) templateData := context.TemplateData(r) templateData["Post"] = post next.ServeHTTP(w, r) } return http.HandlerFunc(fn) }
func getNewPost(a *application.App, w http.ResponseWriter, r *http.Request) error { topic := context.Topic(r) tm := models.NewTagModel(a.DB) tags, err := tm.Find(nil, squirrel.Eq{"tags.topic_id": topic.ID}) if err != nil { return errors.Wrap(err, "find error") } data := context.TemplateData(r) data["Tags"] = tags return libtemplate.Render(w, a.Templates, "new_post.html", data) }
func postNewTag(a *application.App, w http.ResponseWriter, r *http.Request) error { topic := context.Topic(r) name := r.FormValue("name") tm := models.NewTagModel(a.DB) tag := &models.Tag{Name: name, Topic: topic} if err := tm.Add(nil, tag); err != nil { return err } http.Redirect(w, r, tag.Topic.URL(), http.StatusFound) return nil }
func postNewPost(a *application.App, w http.ResponseWriter, r *http.Request) (err error) { title := r.FormValue("title") text := r.FormValue("text") topic := context.Topic(r) user, _ := context.SessionUser(r) // we want the post and tags to be created together so use one tx. If one part fails the rest won't be committed. tx, err := a.DB.Beginx() if err != nil { return errors.Wrap(err, "begin transacion error") } defer func() { if err != nil { tx.Rollback() return } err = tx.Commit() err = errors.Wrap(err, "commit error") }() postModel := models.NewPostModel(a.DB) post := &models.Post{Title: title, Content: text, Topic: topic, Creator: user} if err = postModel.Add(tx, post); err != nil { return errors.Wrap(err, "add post error") } tagIDStr := r.FormValue("tag") if tagIDStr != "" { tagID, err := strconv.ParseInt(tagIDStr, 10, 64) if err != nil { return httperror.StatusError{http.StatusBadRequest, err} } tagModel := models.NewTagModel(a.DB) tag, err := tagModel.FindOne(nil, squirrel.Eq{"tags.id": tagID}) if err != nil { return errors.Wrap(err, "find one error") } if err = tagModel.AddPostTag(tx, post, tag); err != nil { return errors.Wrap(err, "add post tag error") } } http.Redirect(w, r, post.URL(), http.StatusFound) return nil }
// SetTag sets the tag with name in the url in the context and template data. func (m *Middleware) SetTag(next http.Handler) http.Handler { fn := func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) tagName := strings.ToLower(vars["tagName"]) topic := context.Topic(r) tm := models.NewTagModel(m.App.DB) tag, err := tm.FindOne(nil, squirrel.Eq{"tags.name": tagName, "tags.topic_id": topic.ID}) if err != nil { httperror.HandleError(w, errors.Wrap(err, "find one error")) return } context.SetTag(r, tag) templateData := context.TemplateData(r) templateData["Tag"] = tag next.ServeHTTP(w, r) } return http.HandlerFunc(fn) }
func getPosts(a *application.App, w http.ResponseWriter, r *http.Request) error { topic := context.Topic(r) whereEq := squirrel.Eq{"posts.topic_id": topic.ID, "posts.is_pinned": true} pm := models.NewPostModel(a.DB) pinnedPosts, err := pm.Find(nil, whereEq) switch { case err == sql.ErrNoRows: pinnedPosts = make([]*models.Post, 0) case err != nil: return errors.Wrap(err, "find error") } whereEq["posts.is_pinned"] = false unpinnedPosts, err := pm.Find(nil, whereEq) switch { case err == sql.ErrNoRows: unpinnedPosts = make([]*models.Post, 0) case err != nil: return errors.Wrap(err, "find error") } tagModel := models.NewTagModel(a.DB) tags, err := tagModel.Find(nil, squirrel.Eq{"tags.topic_id": topic.ID}) if err != nil { return errors.Wrap(err, "find error") } data := context.TemplateData(r) data["PinnedPosts"] = pinnedPosts data["UnpinnedPosts"] = unpinnedPosts data["Tags"] = tags if err = addUserUpvotedPostIDsToData(r, pm, data); err != nil { return errors.Wrap(err, "add upvoted post ids to data error") } return libtemplate.Render(w, a.Templates, "posts.html", data) }