// URL: /package/new // 新建第三方包 func newPackageHandler(handler *Handler) { user, _ := currentUser(handler) var categories []PackageCategory c := handler.DB.C(PACKAGE_CATEGORIES) c.Find(nil).All(&categories) var choices []wtforms.Choice for _, category := range categories { choices = append(choices, wtforms.Choice{Value: category.Id_.Hex(), Label: category.Name}) } form := wtforms.NewForm( wtforms.NewHiddenField("html", ""), wtforms.NewTextField("name", "名称", "", wtforms.Required{}), wtforms.NewSelectField("category_id", "分类", choices, ""), wtforms.NewTextField("url", "网址", "", wtforms.Required{}, wtforms.URL{}), wtforms.NewTextArea("editormd-markdown-doc", "内容", ""), wtforms.NewTextArea("editormd-html-code", "HTML", ""), ) if handler.Request.Method == "POST" && form.Validate(handler.Request) { c = handler.DB.C(CONTENTS) id := bson.NewObjectId() categoryId := bson.ObjectIdHex(form.Value("category_id")) html := form.Value("editormd-html-code") c.Insert(&Package{ Content: Content{ Id_: id, Type: TypePackage, Title: form.Value("name"), Markdown: form.Value("editormd-markdown-doc"), Html: template.HTML(html), CreatedBy: user.Id_, CreatedAt: time.Now(), }, Id_: id, CategoryId: categoryId, Url: form.Value("url"), }) c = handler.DB.C(PACKAGE_CATEGORIES) // 增加数量 c.Update(bson.M{"_id": categoryId}, bson.M{"$inc": bson.M{"packagecount": 1}}) http.Redirect(handler.ResponseWriter, handler.Request, "/p/"+id.Hex(), http.StatusFound) return } handler.renderTemplate("package/form.html", BASE, map[string]interface{}{ "form": form, "title": "提交第三方包", "action": "/package/new", "active": "package", }) }
// URL /profile // 用户设置页面,显示用户设置,用户头像,密码修改 func profileHandler(w http.ResponseWriter, r *http.Request) { user, ok := currentUser(r) if !ok { http.Redirect(w, r, "/signin?next=/profile", http.StatusFound) return } profileForm := wtforms.NewForm( wtforms.NewTextField("email", "电子邮件", user.Email, wtforms.Email{}), wtforms.NewTextField("website", "个人网站", user.Website), wtforms.NewTextField("location", "所在地", user.Location), wtforms.NewTextField("tagline", "签名", user.Tagline), wtforms.NewTextArea("bio", "个人简介", user.Bio), ) if r.Method == "POST" { if profileForm.Validate(r) { c := db.C("users") c.Update(bson.M{"_id": user.Id_}, bson.M{"$set": bson.M{"website": profileForm.Value("website"), "location": profileForm.Value("location"), "tagline": profileForm.Value("tagline"), "bio": profileForm.Value("bio"), }}) http.Redirect(w, r, "/profile", http.StatusFound) return } } renderTemplate(w, r, "account/profile.html", map[string]interface{}{"user": user, "profileForm": profileForm}) }
// URL: /admin/ad/new // 添加广告 func adminNewAdHandler(handler *Handler) { defer dps.Persist() choices := []wtforms.Choice{ wtforms.Choice{"top0", "最顶部"}, wtforms.Choice{"top", "顶部"}, wtforms.Choice{"frontpage", "首页"}, wtforms.Choice{"content", "主题内"}, wtforms.Choice{"2cols", "2列宽度"}, wtforms.Choice{"3cols", "3列宽度"}, wtforms.Choice{"4cols", "4列宽度"}, } form := wtforms.NewForm( wtforms.NewSelectField("position", "位置", choices, "", wtforms.Required{}), wtforms.NewTextField("name", "名称", "", wtforms.Required{}), wtforms.NewTextField("index", "序号", "", wtforms.Required{}), wtforms.NewTextArea("code", "代码", "", wtforms.Required{}), ) if handler.Request.Method == "POST" { if !form.Validate(handler.Request) { handler.renderTemplate("ad/form.html", ADMIN, map[string]interface{}{ "form": form, "isNew": true, }) return } c := handler.DB.C(ADS) index, err := strconv.Atoi(form.Value("index")) if err != nil { form.AddError("index", "请输入正确的数字") handler.renderTemplate("ad/form.html", ADMIN, map[string]interface{}{ "form": form, "isNew": true, }) return } err = c.Insert(&AD{ Id_: bson.NewObjectId(), Position: form.Value("position"), Name: form.Value("name"), Code: form.Value("code"), Index: index, }) if err != nil { panic(err) } http.Redirect(handler.ResponseWriter, handler.Request, "/admin/ads", http.StatusFound) return } handler.renderTemplate("ad/form.html", ADMIN, map[string]interface{}{ "form": form, "isNew": true, }) }
// URL /profile // 用户设置页面,显示用户设置,用户头像,密码修改 func profileHandler(w http.ResponseWriter, r *http.Request) { user, _ := currentUser(r) profileForm := wtforms.NewForm( wtforms.NewTextField("email", "电子邮件", user.Email, wtforms.Email{}), wtforms.NewTextField("website", "个人网站", user.Website), wtforms.NewTextField("location", "所在地", user.Location), wtforms.NewTextField("tagline", "签名", user.Tagline), wtforms.NewTextArea("bio", "个人简介", user.Bio), wtforms.NewTextField("github_username", "GitHub用户名", user.GitHubUsername), wtforms.NewTextField("weibo", "新浪微博", user.Weibo), ) if r.Method == "POST" { if profileForm.Validate(r) { c := DB.C(USERS) c.Update(bson.M{"_id": user.Id_}, bson.M{"$set": bson.M{ "website": profileForm.Value("website"), "location": profileForm.Value("location"), "tagline": profileForm.Value("tagline"), "bio": profileForm.Value("bio"), "githubusername": profileForm.Value("github_username"), "weibo": profileForm.Value("weibo"), }}) http.Redirect(w, r, "/profile", http.StatusFound) return } } renderTemplate(w, r, "account/profile.html", BASE, map[string]interface{}{ "user": user, "profileForm": profileForm, "defaultAvatars": defaultAvatars, }) }
// URL: /admin/node/new // 新建节点 func adminNewNodeHandler(w http.ResponseWriter, r *http.Request) { user, ok := currentUser(r) if !ok { http.Redirect(w, r, "/signin?next=/node/new", http.StatusFound) return } if !user.IsSuperuser { message(w, r, "没有权限", "你没有新建节点的权限", "error") return } form := wtforms.NewForm( wtforms.NewTextField("id", "ID", "", &wtforms.Required{}), wtforms.NewTextField("name", "名称", "", &wtforms.Required{}), wtforms.NewTextArea("description", "描述", "", &wtforms.Required{}), ) if r.Method == "POST" { if form.Validate(r) { c := db.C("nodes") node := Node{} err := c.Find(bson.M{"id": form.Value("id")}).One(&node) if err == nil { form.AddError("id", "该ID已经存在") renderTemplate(w, r, "node/new.html", map[string]interface{}{"form": form, "adminNav": ADMIN_NAV}) return } err = c.Find(bson.M{"name": form.Value("name")}).One(&node) if err == nil { form.AddError("name", "该名称已经存在") renderTemplate(w, r, "node/new.html", map[string]interface{}{"form": form, "adminNav": ADMIN_NAV}) return } Id_ := bson.NewObjectId() err = c.Insert(&Node{ Id_: Id_, Id: form.Value("id"), Name: form.Value("name"), Description: form.Value("description")}) if err != nil { panic(err) } http.Redirect(w, r, "/admin/node/new", http.StatusFound) } } renderTemplate(w, r, "node/new.html", map[string]interface{}{"form": form, "adminNav": ADMIN_NAV}) }
// URL: /package/new // 新建第三方包 func newPackageHandler(w http.ResponseWriter, r *http.Request) { user, _ := currentUser(r) var categories []PackageCategory c := DB.C("packagecategories") c.Find(nil).All(&categories) var choices []wtforms.Choice for _, category := range categories { choices = append(choices, wtforms.Choice{Value: category.Id_.Hex(), Label: category.Name}) } form := wtforms.NewForm( wtforms.NewHiddenField("html", ""), wtforms.NewTextField("name", "名称", "", wtforms.Required{}), wtforms.NewSelectField("category_id", "分类", choices, ""), wtforms.NewTextField("url", "网址", "", wtforms.Required{}, wtforms.URL{}), wtforms.NewTextArea("description", "描述", "", wtforms.Required{}), ) if r.Method == "POST" && form.Validate(r) { c = DB.C("contents") id := bson.NewObjectId() categoryId := bson.ObjectIdHex(form.Value("category_id")) html := form.Value("html") html = strings.Replace(html, "<pre>", `<pre class="prettyprint linenums">`, -1) c.Insert(&Package{ Content: Content{ Id_: id, Type: TypePackage, Title: form.Value("name"), Markdown: form.Value("description"), Html: template.HTML(html), CreatedBy: user.Id_, CreatedAt: time.Now(), }, Id_: id, CategoryId: categoryId, Url: form.Value("url"), }) c = DB.C("packagecategories") // 增加数量 c.Update(bson.M{"_id": categoryId}, bson.M{"$inc": bson.M{"packagecount": 1}}) http.Redirect(w, r, "/p/"+id.Hex(), http.StatusFound) return } renderTemplate(w, r, "package/form.html", map[string]interface{}{ "form": form, "title": "提交第三方包", "action": "/package/new", "active": "package", }) }
// URL: /admin/book/{id}/edit // 编辑图书 func editBookHandler(handler *Handler) { defer deferclient.Persist() bookId := mux.Vars(handler.Request)["id"] c := handler.DB.C(BOOKS) var book Book c.Find(bson.M{"_id": bson.ObjectIdHex(bookId)}).One(&book) form := wtforms.NewForm( wtforms.NewTextField("title", "书名", book.Title, wtforms.Required{}), wtforms.NewTextField("cover", "封面", book.Cover, wtforms.Required{}), wtforms.NewTextField("author", "作者", book.Author, wtforms.Required{}), wtforms.NewTextField("translator", "译者", book.Translator), wtforms.NewTextArea("introduction", "简介", book.Introduction), wtforms.NewTextField("pages", "页数", strconv.Itoa(book.Pages), wtforms.Required{}), wtforms.NewTextField("language", "语言", book.Language, wtforms.Required{}), wtforms.NewTextField("publisher", "出版社", book.Publisher), wtforms.NewTextField("publication_date", "出版年月日", book.PublicationDate), wtforms.NewTextField("isbn", "ISBN", book.ISBN), ) if handler.Request.Method == "POST" { if form.Validate(handler.Request) { pages, _ := strconv.Atoi(form.Value("pages")) err := c.Update(bson.M{"_id": book.Id_}, bson.M{"$set": bson.M{ "title": form.Value("title"), "cover": form.Value("cover"), "author": form.Value("author"), "translator": form.Value("translator"), "introduction": form.Value("introduction"), "pages": pages, "language": form.Value("language"), "publisher": form.Value("publisher"), "publication_date": form.Value("publication_date"), "isbn": form.Value("isbn"), }}) if err != nil { panic(err) } http.Redirect(handler.ResponseWriter, handler.Request, "/admin/books", http.StatusFound) return } } handler.renderTemplate("book/form.html", ADMIN, map[string]interface{}{ "book": book, "form": form, "isNew": false, }) }
// URL /user_center/edit_info // 修改用户资料 func editUserInfoHandler(handler *Handler) { user, _ := currentUser(handler) profileForm := wtforms.NewForm( wtforms.NewTextField("email", "电子邮件", user.Email, wtforms.Email{}), wtforms.NewTextField("website", "个人网站", user.Website), wtforms.NewTextField("location", "所在地", user.Location), wtforms.NewTextField("tagline", "签名", user.Tagline), wtforms.NewTextArea("bio", "个人简介", user.Bio), wtforms.NewTextField("github_username", "GitHub用户名", user.GitHubUsername), wtforms.NewTextField("weibo", "新浪微博", user.Weibo), ) if handler.Request.Method == "POST" { if profileForm.Validate(handler.Request) { c := handler.DB.C(USERS) // 检查邮箱 result := new(User) err := c.Find(bson.M{"email": profileForm.Value("email")}).One(result) if err == nil && result.Id_ != user.Id_ { profileForm.AddError("email", "电子邮件地址已经被使用") handler.renderTemplate("user_center/info_form.html", BASE, map[string]interface{}{ "user": user, "profileForm": profileForm, "active": "edit_info", }) return } c.Update(bson.M{"_id": user.Id_}, bson.M{"$set": bson.M{ "email": profileForm.Value("email"), "website": profileForm.Value("website"), "location": profileForm.Value("location"), "tagline": profileForm.Value("tagline"), "bio": profileForm.Value("bio"), "githubusername": profileForm.Value("github_username"), "weibo": profileForm.Value("weibo"), }}) handler.redirect("/user_center/edit_info", http.StatusFound) return } } handler.renderTemplate("user_center/info_form.html", BASE, map[string]interface{}{ "user": user, "profileForm": profileForm, "active": "edit_info", }) }
// URL: /admin/node/new // 新建节点 func adminNewNodeHandler(handler *Handler) { defer deferclient.Persist() form := wtforms.NewForm( wtforms.NewTextField("id", "ID", "", &wtforms.Required{}), wtforms.NewTextField("name", "名称", "", &wtforms.Required{}), wtforms.NewTextArea("description", "描述", "", &wtforms.Required{}), ) if handler.Request.Method == "POST" { if form.Validate(handler.Request) { c := handler.DB.C(NODES) node := Node{} err := c.Find(bson.M{"id": form.Value("id")}).One(&node) if err == nil { form.AddError("id", "该ID已经存在") handler.renderTemplate("node/new.html", ADMIN, map[string]interface{}{"form": form}) return } err = c.Find(bson.M{"name": form.Value("name")}).One(&node) if err == nil { form.AddError("name", "该名称已经存在") handler.renderTemplate("node/new.html", ADMIN, map[string]interface{}{"form": form}) return } Id_ := bson.NewObjectId() err = c.Insert(&Node{ Id_: Id_, Id: form.Value("id"), Name: form.Value("name"), Description: form.Value("description")}) if err != nil { panic(err) } http.Redirect(handler.ResponseWriter, handler.Request, "/admin/node/new", http.StatusFound) } } handler.renderTemplate("node/new.html", ADMIN, map[string]interface{}{"form": form}) }
// URL: /admin/ad/{id}/edit // 编辑广告 func adminEditAdHandler(w http.ResponseWriter, r *http.Request) { id := mux.Vars(r)["id"] c := DB.C("ads") var ad AD c.Find(bson.M{"_id": bson.ObjectIdHex(id)}).One(&ad) choices := []wtforms.Choice{ wtforms.Choice{"frongpage", "首页"}, wtforms.Choice{"3cols", "3列宽度"}, wtforms.Choice{"4cols", "4列宽度"}, } form := wtforms.NewForm( wtforms.NewSelectField("position", "位置", choices, ad.Position, wtforms.Required{}), wtforms.NewTextField("name", "名称", ad.Name, wtforms.Required{}), wtforms.NewTextArea("code", "代码", ad.Code, wtforms.Required{}), ) if r.Method == "POST" { if !form.Validate(r) { renderTemplate(w, r, "admin/ad_form.html", map[string]interface{}{ "adminNav": ADMIN_NAV, "form": form, "isNew": false, }) return } err := c.Update(bson.M{"_id": ad.Id_}, bson.M{"$set": bson.M{ "position": form.Value("position"), "name": form.Value("name"), "code": form.Value("code"), }}) if err != nil { panic(err) } http.Redirect(w, r, "/admin/ads", http.StatusFound) return } renderTemplate(w, r, "admin/ad_form.html", map[string]interface{}{ "adminNav": ADMIN_NAV, "form": form, "isNew": false, }) }
func newBookHandler(handler *Handler) { defer deferclient.Persist() form := wtforms.NewForm( wtforms.NewTextField("title", "书名", "", wtforms.Required{}), wtforms.NewTextField("cover", "封面", "", wtforms.Required{}), wtforms.NewTextField("author", "作者", "", wtforms.Required{}), wtforms.NewTextField("translator", "译者", ""), wtforms.NewTextArea("introduction", "简介", ""), wtforms.NewTextField("pages", "页数", "", wtforms.Required{}), wtforms.NewTextField("language", "语言", "", wtforms.Required{}), wtforms.NewTextField("publisher", "出版社", ""), wtforms.NewTextField("publication_date", "出版年月日", ""), wtforms.NewTextField("isbn", "ISBN", ""), ) if handler.Request.Method == "POST" { if form.Validate(handler.Request) { pages, _ := strconv.Atoi(form.Value("pages")) c := handler.DB.C(BOOKS) err := c.Insert(&Book{ Id_: bson.NewObjectId(), Title: form.Value("title"), Cover: form.Value("cover"), Author: form.Value("author"), Translator: form.Value("translator"), Pages: pages, Language: form.Value("language"), Publisher: form.Value("publisher"), PublicationDate: form.Value("publication_date"), Introduction: form.Value("introduction"), ISBN: form.Value("isbn"), }) if err != nil { panic(err) } http.Redirect(handler.ResponseWriter, handler.Request, "/admin/books", http.StatusFound) return } } handler.renderTemplate("book/form.html", ADMIN, map[string]interface{}{ "form": form, "isNew": true, }) }
// URL: /admin/ad/new // 添加广告 func adminNewAdHandler(w http.ResponseWriter, r *http.Request) { choices := []wtforms.Choice{ wtforms.Choice{"frongpage", "首页"}, wtforms.Choice{"2cols", "2列宽度"}, wtforms.Choice{"3cols", "3列宽度"}, wtforms.Choice{"4cols", "4列宽度"}, } form := wtforms.NewForm( wtforms.NewSelectField("position", "位置", choices, "", wtforms.Required{}), wtforms.NewTextField("name", "名称", "", wtforms.Required{}), wtforms.NewTextArea("code", "代码", "", wtforms.Required{}), ) if r.Method == "POST" { if !form.Validate(r) { renderTemplate(w, r, "admin/ad_form.html", map[string]interface{}{ "adminNav": ADMIN_NAV, "form": form, "isNew": true, }) return } c := DB.C("ads") err := c.Insert(&AD{ Id_: bson.NewObjectId(), Position: form.Value("position"), Name: form.Value("name"), Code: form.Value("code"), }) if err != nil { panic(err) } http.Redirect(w, r, "/admin/ads", http.StatusFound) return } renderTemplate(w, r, "admin/ad_form.html", map[string]interface{}{ "adminNav": ADMIN_NAV, "form": form, "isNew": true, }) }
// URL: /topic/new // 新建主题 func newTopicHandler(w http.ResponseWriter, r *http.Request) { nodeId := mux.Vars(r)["node"] var nodes []Node c := DB.C("nodes") c.Find(nil).All(&nodes) var choices = []wtforms.Choice{wtforms.Choice{}} // 第一个选项为空 for _, node := range nodes { choices = append(choices, wtforms.Choice{Value: node.Id_.Hex(), Label: node.Name}) } form := wtforms.NewForm( wtforms.NewHiddenField("html", ""), wtforms.NewSelectField("node", "节点", choices, nodeId, &wtforms.Required{}), wtforms.NewTextArea("title", "标题", "", &wtforms.Required{}), wtforms.NewTextArea("content", "内容", ""), ) var content string var html template.HTML if r.Method == "POST" { if form.Validate(r) { session, _ := store.Get(r, "user") username, _ := session.Values["username"] username = username.(string) user := User{} c = DB.C("users") c.Find(bson.M{"username": username}).One(&user) c = DB.C("contents") id_ := bson.NewObjectId() now := time.Now() html2 := form.Value("html") html2 = strings.Replace(html2, "<pre>", `<pre class="prettyprint linenums">`, -1) nodeId := bson.ObjectIdHex(form.Value("node")) err := c.Insert(&Topic{ Content: Content{ Id_: id_, Type: TypeTopic, Title: form.Value("title"), Markdown: form.Value("content"), Html: template.HTML(html2), CreatedBy: user.Id_, CreatedAt: now, }, Id_: id_, NodeId: nodeId, LatestRepliedAt: now, }) if err != nil { fmt.Println("newTopicHandler:", err.Error()) return } // 增加Node.TopicCount c = DB.C("nodes") c.Update(bson.M{"_id": nodeId}, bson.M{"$inc": bson.M{"topiccount": 1}}) c = DB.C("status") var status Status c.Find(nil).One(&status) c.Update(bson.M{"_id": status.Id_}, bson.M{"$inc": bson.M{"topiccount": 1}}) http.Redirect(w, r, "/t/"+id_.Hex(), http.StatusFound) return } content = form.Value("content") html = template.HTML(form.Value("html")) form.SetValue("html", "") } renderTemplate(w, r, "topic/form.html", map[string]interface{}{ "form": form, "title": "新建", "html": html, "content": content, "action": "/topic/new", "active": "topic", }) }
// URL: /a/{articleId}/edit // 编辑主题 func editArticleHandler(w http.ResponseWriter, r *http.Request) { user, _ := currentUser(r) articleId := mux.Vars(r)["articleId"] c := DB.C("contents") var article Article err := c.Find(bson.M{"_id": bson.ObjectIdHex(articleId)}).One(&article) if err != nil { message(w, r, "没有该文章", "没有该文章,不能编辑", "error") return } if !article.CanEdit(user.Username) { message(w, r, "没用该权限", "对不起,你没有权限编辑该文章", "error") return } var categorys []ArticleCategory c = DB.C("articlecategories") c.Find(nil).All(&categorys) var choices []wtforms.Choice for _, category := range categorys { choices = append(choices, wtforms.Choice{Value: category.Id_.Hex(), Label: category.Name}) } form := wtforms.NewForm( wtforms.NewHiddenField("html", ""), wtforms.NewTextField("title", "标题", article.Title, wtforms.Required{}), wtforms.NewTextArea("content", "内容", article.Markdown, wtforms.Required{}), wtforms.NewTextField("original_source", "原始出处", article.OriginalSource, wtforms.Required{}), wtforms.NewTextField("original_url", "原始链接", article.OriginalUrl, wtforms.URL{}), wtforms.NewSelectField("category", "分类", choices, article.CategoryId.Hex()), ) content := article.Markdown html := article.Html if r.Method == "POST" { if form.Validate(r) { html := form.Value("html") html = strings.Replace(html, "<pre>", `<pre class="prettyprint linenums">`, -1) categoryId := bson.ObjectIdHex(form.Value("category")) c = DB.C("contents") err = c.Update(bson.M{"_id": article.Id_}, bson.M{"$set": bson.M{ "categoryid": categoryId, "originalsource": form.Value("original_source"), "originalurl": form.Value("original_url"), "content.title": form.Value("title"), "content.markdown": form.Value("content"), "content.html": template.HTML(html), "content.updatedby": user.Id_.Hex(), "content.updatedat": time.Now(), }}) if err != nil { fmt.Println("update error:", err.Error()) return } http.Redirect(w, r, "/a/"+article.Id_.Hex(), http.StatusFound) return } content = form.Value("content") html = template.HTML(form.Value("html")) } renderTemplate(w, r, "article/form.html", map[string]interface{}{ "form": form, "title": "编辑", "action": "/a/" + articleId + "/edit", "html": html, "content": content, "active": "article", }) }
// URL: /t/{topicId}/edit // 编辑主题 func editTopicHandler(w http.ResponseWriter, r *http.Request) { user, _ := currentUser(r) topicId := mux.Vars(r)["topicId"] c := DB.C("contents") var topic Topic err := c.Find(bson.M{"_id": bson.ObjectIdHex(topicId), "content.type": TypeTopic}).One(&topic) if err != nil { message(w, r, "没有该主题", "没有该主题,不能编辑", "error") return } if !topic.CanEdit(user.Username) { message(w, r, "没有该权限", "对不起,你没有权限编辑该主题", "error") return } var nodes []Node c = DB.C("nodes") c.Find(nil).All(&nodes) var choices = []wtforms.Choice{wtforms.Choice{}} // 第一个选项为空 for _, node := range nodes { choices = append(choices, wtforms.Choice{Value: node.Id_.Hex(), Label: node.Name}) } form := wtforms.NewForm( wtforms.NewHiddenField("html", ""), wtforms.NewSelectField("node", "节点", choices, topic.NodeId.Hex(), &wtforms.Required{}), wtforms.NewTextArea("title", "标题", topic.Title, &wtforms.Required{}), wtforms.NewTextArea("content", "内容", topic.Markdown), ) content := topic.Markdown html := topic.Html if r.Method == "POST" { if form.Validate(r) { html2 := form.Value("html") html2 = strings.Replace(html2, "<pre>", `<pre class="prettyprint linenums">`, -1) nodeId := bson.ObjectIdHex(form.Value("node")) c = DB.C("contents") c.Update(bson.M{"_id": topic.Id_}, bson.M{"$set": bson.M{ "nodeid": nodeId, "content.title": form.Value("title"), "content.markdown": form.Value("content"), "content.html": template.HTML(html2), "content.updatedat": time.Now(), "content.updatedby": user.Id_.Hex(), }}) // 如果两次的节点不同,更新节点的主题数量 if topic.NodeId != nodeId { c = DB.C("nodes") c.Update(bson.M{"_id": topic.NodeId}, bson.M{"$inc": bson.M{"topiccount": -1}}) c.Update(bson.M{"_id": nodeId}, bson.M{"$inc": bson.M{"topiccount": 1}}) } http.Redirect(w, r, "/t/"+topic.Id_.Hex(), http.StatusFound) return } content = form.Value("content") html = template.HTML(form.Value("html")) form.SetValue("html", "") } renderTemplate(w, r, "topic/form.html", map[string]interface{}{ "form": form, "title": "编辑", "action": "/t/" + topicId + "/edit", "html": html, "content": content, "active": "topic", }) }
// URL: /t/{topicId}/edit // 编辑主题 func editTopicHandler(handler *Handler) { user, _ := currentUser(handler) topicId := bson.ObjectIdHex(mux.Vars(handler.Request)["topicId"]) c := handler.DB.C(CONTENTS) var topic Topic err := c.Find(bson.M{"_id": topicId, "content.type": TypeTopic}).One(&topic) if err != nil { message(handler, "没有该主题", "没有该主题,不能编辑", "error") return } if !topic.CanEdit(user.Username, handler.DB) { message(handler, "没有该权限", "对不起,你没有权限编辑该主题", "error") return } var nodes []Node c = handler.DB.C(NODES) c.Find(nil).All(&nodes) var choices = []wtforms.Choice{wtforms.Choice{}} // 第一个选项为空 for _, node := range nodes { choices = append(choices, wtforms.Choice{Value: node.Id_.Hex(), Label: node.Name}) } form := wtforms.NewForm( wtforms.NewSelectField("node", "节点", choices, topic.NodeId.Hex(), &wtforms.Required{}), wtforms.NewTextArea("title", "标题", topic.Title, &wtforms.Required{}), wtforms.NewTextArea("editormd-markdown-doc", "内容", topic.Markdown), wtforms.NewTextArea("editormd-html-code", "html", ""), ) if handler.Request.Method == "POST" { if form.Validate(handler.Request) { nodeId := bson.ObjectIdHex(form.Value("node")) c = handler.DB.C(CONTENTS) c.Update(bson.M{"_id": topic.Id_}, bson.M{"$set": bson.M{ "nodeid": nodeId, "content.title": form.Value("title"), "content.markdown": form.Value("editormd-markdown-doc"), "content.html": template.HTML(form.Value("editormd-html-code")), "content.updatedat": time.Now(), "content.updatedby": user.Id_.Hex(), }}) // 如果两次的节点不同,更新节点的主题数量 if topic.NodeId != nodeId { c = handler.DB.C(NODES) c.Update(bson.M{"_id": topic.NodeId}, bson.M{"$inc": bson.M{"topiccount": -1}}) c.Update(bson.M{"_id": nodeId}, bson.M{"$inc": bson.M{"topiccount": 1}}) } http.Redirect(handler.ResponseWriter, handler.Request, "/t/"+topic.Id_.Hex(), http.StatusFound) return } } handler.renderTemplate("topic/form.html", BASE, map[string]interface{}{ "form": form, "title": "编辑", "action": "/t/" + topicId + "/edit", "active": "topic", }) }
// URL: /package/{packageId}/edit // 编辑第三方包 func editPackageHandler(handler *Handler) { user, _ := currentUser(handler) vars := mux.Vars(handler.Request) packageId := vars["packageId"] if !bson.IsObjectIdHex(packageId) { http.NotFound(handler.ResponseWriter, handler.Request) return } package_ := Package{} c := handler.DB.C(CONTENTS) err := c.Find(bson.M{"_id": bson.ObjectIdHex(packageId), "content.type": TypePackage}).One(&package_) if err != nil { message(handler, "没有该包", "没有该包", "error") return } if !package_.CanEdit(user.Username, handler.DB) { message(handler, "没有权限", "你没有权限编辑该包", "error") return } var categories []PackageCategory c = handler.DB.C(PACKAGE_CATEGORIES) c.Find(nil).All(&categories) var choices []wtforms.Choice for _, category := range categories { choices = append(choices, wtforms.Choice{Value: category.Id_.Hex(), Label: category.Name}) } form := wtforms.NewForm( wtforms.NewHiddenField("html", ""), wtforms.NewTextField("name", "名称", package_.Title, wtforms.Required{}), wtforms.NewSelectField("category_id", "分类", choices, package_.CategoryId.Hex()), wtforms.NewTextField("url", "网址", package_.Url, wtforms.Required{}, wtforms.URL{}), wtforms.NewTextArea("description", "描述", package_.Markdown, wtforms.Required{}), ) if handler.Request.Method == "POST" && form.Validate(handler.Request) { c = handler.DB.C(CONTENTS) categoryId := bson.ObjectIdHex(form.Value("category_id")) html := form.Value("html") html = strings.Replace(html, "<pre>", `<pre class="prettyprint linenums">`, -1) c.Update(bson.M{"_id": package_.Id_}, bson.M{"$set": bson.M{ "categoryid": categoryId, "url": form.Value("url"), "content.title": form.Value("name"), "content.markdown": form.Value("description"), "content.html": template.HTML(html), "content.updateDBy": user.Id_.Hex(), "content.updatedat": time.Now(), }}) c = handler.DB.C(PACKAGE_CATEGORIES) if categoryId != package_.CategoryId { // 减少原来类别的包数量 c.Update(bson.M{"_id": package_.CategoryId}, bson.M{"$inc": bson.M{"packagecount": -1}}) // 增加新类别的包数量 c.Update(bson.M{"_id": categoryId}, bson.M{"$inc": bson.M{"packagecount": 1}}) } http.Redirect(handler.ResponseWriter, handler.Request, "/p/"+package_.Id_.Hex(), http.StatusFound) return } form.SetValue("html", "") handler.renderTemplate("package/form.html", BASE, map[string]interface{}{ "form": form, "title": "编辑第三方包", "action": "/p/" + packageId + "/edit", "active": "package", }) }
// URL: /topic/new // 新建主题 func newTopicHandler(handler *Handler) { nodeId := mux.Vars(handler.Request)["node"] var nodes []Node c := handler.DB.C(NODES) c.Find(nil).All(&nodes) var choices = []wtforms.Choice{wtforms.Choice{}} // 第一个选项为空 for _, node := range nodes { choices = append(choices, wtforms.Choice{Value: node.Id_.Hex(), Label: node.Name}) } form := wtforms.NewForm( wtforms.NewSelectField("node", "节点", choices, nodeId, &wtforms.Required{}), wtforms.NewTextArea("title", "标题", "", &wtforms.Required{}), wtforms.NewTextArea("editormd-markdown-doc", "内容", ""), wtforms.NewTextArea("editormd-html-code", "HTML", ""), ) if handler.Request.Method == "POST" { if form.Validate(handler.Request) { user, _ := currentUser(handler) c = handler.DB.C(CONTENTS) id_ := bson.NewObjectId() now := time.Now() nodeId := bson.ObjectIdHex(form.Value("node")) err := c.Insert(&Topic{ Content: Content{ Id_: id_, Type: TypeTopic, Title: form.Value("title"), Markdown: form.Value("editormd-markdown-doc"), Html: template.HTML(form.Value("editormd-html-code")), CreatedBy: user.Id_, CreatedAt: now, }, Id_: id_, NodeId: nodeId, LatestRepliedAt: now, }) if err != nil { fmt.Println("newTopicHandler:", err.Error()) return } // 增加Node.TopicCount c = handler.DB.C(NODES) c.Update(bson.M{"_id": nodeId}, bson.M{"$inc": bson.M{"topiccount": 1}}) c = handler.DB.C(STATUS) c.Update(nil, bson.M{"$inc": bson.M{"topiccount": 1}}) http.Redirect(handler.ResponseWriter, handler.Request, "/t/"+id_.Hex(), http.StatusFound) return } } handler.renderTemplate("topic/form.html", BASE, map[string]interface{}{ "form": form, "title": "新建", "action": "/topic/new", "active": "topic", }) }
// URL: /article/new // 新建文章 func newArticleHandler(w http.ResponseWriter, r *http.Request) { var categories []ArticleCategory c := DB.C("articlecategories") c.Find(nil).All(&categories) var choices []wtforms.Choice for _, category := range categories { choices = append(choices, wtforms.Choice{Value: category.Id_.Hex(), Label: category.Name}) } form := wtforms.NewForm( wtforms.NewHiddenField("html", ""), wtforms.NewTextField("title", "标题", "", wtforms.Required{}), wtforms.NewTextArea("content", "内容", "", wtforms.Required{}), wtforms.NewTextField("original_source", "原始出处", "", wtforms.Required{}), wtforms.NewTextField("original_url", "原始链接", "", wtforms.URL{}), wtforms.NewSelectField("category", "分类", choices, ""), ) if r.Method == "POST" && form.Validate(r) { session, _ := store.Get(r, "user") username, _ := session.Values["username"] username = username.(string) user := User{} c = DB.C("users") c.Find(bson.M{"username": username}).One(&user) c = DB.C("contents") id_ := bson.NewObjectId() html := form.Value("html") html = strings.Replace(html, "<pre>", `<pre class="prettyprint linenums">`, -1) categoryId := bson.ObjectIdHex(form.Value("category")) err := c.Insert(&Article{ Content: Content{ Id_: id_, Type: TypeArticle, Title: form.Value("title"), Markdown: form.Value("content"), Html: template.HTML(html), CreatedBy: user.Id_, CreatedAt: time.Now(), }, Id_: id_, CategoryId: categoryId, OriginalSource: form.Value("original_source"), OriginalUrl: form.Value("original_url"), }) if err != nil { fmt.Println("newArticleHandler:", err.Error()) return } http.Redirect(w, r, "/a/"+id_.Hex(), http.StatusFound) return } renderTemplate(w, r, "article/form.html", map[string]interface{}{ "form": form, "title": "新建", "action": "/article/new", "active": "article", }) }
// URL: /admin/ad/{id}/edit // 编辑广告 func adminEditAdHandler(handler *Handler) { defer deferclient.Persist() id := mux.Vars(handler.Request)["id"] c := handler.DB.C(ADS) var ad AD c.Find(bson.M{"_id": bson.ObjectIdHex(id)}).One(&ad) choices := []wtforms.Choice{ wtforms.Choice{"top", "顶部"}, wtforms.Choice{"frontpage", "首页"}, wtforms.Choice{"3cols", "3列宽度"}, wtforms.Choice{"4cols", "4列宽度"}, } form := wtforms.NewForm( wtforms.NewSelectField("position", "位置", choices, ad.Position, wtforms.Required{}), wtforms.NewTextField("name", "名称", ad.Name, wtforms.Required{}), wtforms.NewTextField("index", "序号", strconv.Itoa(ad.Index), wtforms.Required{}), wtforms.NewTextArea("code", "代码", ad.Code, wtforms.Required{}), ) if handler.Request.Method == "POST" { if !form.Validate(handler.Request) { handler.renderTemplate("ad/form.html", ADMIN, map[string]interface{}{ "form": form, "isNew": false, }) return } index, err := strconv.Atoi(form.Value("index")) if err != nil { form.AddError("index", "请输入正确的数字") handler.renderTemplate("ad/form.html", ADMIN, map[string]interface{}{ "form": form, "isNew": false, }) return } err = c.Update(bson.M{"_id": ad.Id_}, bson.M{"$set": bson.M{ "position": form.Value("position"), "name": form.Value("name"), "code": form.Value("code"), "index": index, }}) if err != nil { panic(err) } http.Redirect(handler.ResponseWriter, handler.Request, "/admin/ads", http.StatusFound) return } handler.renderTemplate("ad/form.html", ADMIN, map[string]interface{}{ "form": form, "isNew": false, }) }
// URL: /site/{siteId}/edit // 修改提交过的站点信息,提交者自己或者管理员可以修改 func editSiteHandler(w http.ResponseWriter, r *http.Request) { user, ok := currentUser(r) if !ok { http.Redirect(w, r, "/signin", http.StatusFound) return } siteId := mux.Vars(r)["siteId"] var site Site c := db.C("contents") err := c.Find(bson.M{"_id": bson.ObjectIdHex(siteId), "content.type": TypeSite}).One(&site) if err != nil { message(w, r, "错误的连接", "错误的连接", "error") return } if !site.CanEdit(user.Username) { message(w, r, "没有权限", "你没有权限可以修改站点", "error") return } var categories []SiteCategory c = db.C("sitecategories") c.Find(nil).All(&categories) var choices []wtforms.Choice for _, category := range categories { choices = append(choices, wtforms.Choice{Value: category.Id_.Hex(), Label: category.Name}) } form := wtforms.NewForm( wtforms.NewTextField("name", "网站名称", site.Title, wtforms.Required{}), wtforms.NewTextField("url", "地址", site.Url, wtforms.Required{}, wtforms.URL{}), wtforms.NewTextArea("description", "描述", site.Markdown), wtforms.NewSelectField("category", "分类", choices, site.CategoryId.Hex(), wtforms.Required{}), ) if r.Method == "POST" && form.Validate(r) { // 检查是否用重复 var site2 Site c = db.C("contents") err := c.Find(bson.M{"url": form.Value("url"), "_id": bson.M{"$ne": site.Id_}}).One(&site2) if err == nil { form.AddError("url", "该站点已经有了") renderTemplate(w, r, "site/form.html", map[string]interface{}{"form": form, "action": "/site/" + siteId + "/edit", "title": "编辑"}) return } c.Update(bson.M{"_id": site.Id_}, bson.M{"$set": bson.M{ "content.title": form.Value("name"), "content.markdown": form.Value("description"), "content.updatedby": user.Id_.Hex(), "content.updatedat": time.Now(), "url": form.Value("url"), "categoryid": bson.ObjectIdHex(form.Value("category")), }, }) http.Redirect(w, r, "/sites#site-"+site.Id_.Hex(), http.StatusFound) return } renderTemplate(w, r, "site/form.html", map[string]interface{}{ "form": form, "action": "/site/" + siteId + "/edit", "title": "编辑", "active": "site", }) }
// URL: /site/new // 提交站点 func newSiteHandler(w http.ResponseWriter, r *http.Request) { user, ok := currentUser(r) if !ok { http.Redirect(w, r, "/signin", http.StatusFound) return } var categories []SiteCategory c := db.C("sitecategories") c.Find(nil).All(&categories) var choices []wtforms.Choice for _, category := range categories { choices = append(choices, wtforms.Choice{Value: category.Id_.Hex(), Label: category.Name}) } form := wtforms.NewForm( wtforms.NewTextField("name", "网站名称", "", wtforms.Required{}), wtforms.NewTextField("url", "地址", "", wtforms.Required{}, wtforms.URL{}), wtforms.NewTextArea("description", "描述", ""), wtforms.NewSelectField("category", "分类", choices, "", wtforms.Required{}), ) if r.Method == "POST" { if !form.Validate(r) { renderTemplate(w, r, "site/form.html", map[string]interface{}{"form": form, "action": "/site/new", "title": "新建"}) return } var site Site c = db.C("contents") err := c.Find(bson.M{"url": form.Value("url")}).One(&site) if err == nil { form.AddError("url", "该站点已经有了") renderTemplate(w, r, "site/form.html", map[string]interface{}{"form": form, "action": "/site/new", "title": "新建"}) return } id_ := bson.NewObjectId() c.Insert(&Site{ Id_: id_, Content: Content{ Id_: id_, Type: TypeSite, Title: form.Value("name"), Markdown: form.Value("description"), CreatedBy: user.Id_, CreatedAt: time.Now(), }, Url: form.Value("url"), CategoryId: bson.ObjectIdHex(form.Value("category")), }) http.Redirect(w, r, "/sites#site-"+id_.Hex(), http.StatusFound) return } renderTemplate(w, r, "site/form.html", map[string]interface{}{ "form": form, "action": "/site/new", "title": "新建", "active": "site", }) }