// /tags func pageTags(w http.ResponseWriter, r *http.Request) { info, err := getInfo() if err != nil { logs.Error("pageTags:", err) pageHttpStatusCode(w, r, http.StatusInternalServerError) return } info.Canonical = app.URL(app.TagsURL()) info.Title = "标签" sql := `SELECT {id} AS {ID}, {name} AS {Name}, {title} AS {Title} FROM #tags` rows, err := db.Query(true, sql) if err != nil { logs.Error("pageTags:", err) pageHttpStatusCode(w, r, http.StatusInternalServerError) return } defer rows.Close() tags := make([]*Tag, 0, 100) if _, err = fetch.Obj(&tags, rows); err != nil { logs.Error("pageTags:", err) pageHttpStatusCode(w, r, http.StatusInternalServerError) return } data := map[string]interface{}{"info": info, "tags": tags} render(w, r, "tags", data, map[string]string{"Content-Type": "text/html"}) }
// /tags/1.html func pageTag(w http.ResponseWriter, r *http.Request) { tagName, ok := util.ParamString(w, r, "id") if !ok { return } tagName = strings.TrimSuffix(tagName, opt.Suffix) sql := `SELECT {id} AS {ID}, {name} AS {Name}, {title} AS {Title}, {description} AS {Description} FROM #tags WHERE {name}=?` rows, err := db.Query(true, sql, tagName) if err != nil { logs.Error("pageTag:", err) pageHttpStatusCode(w, r, http.StatusInternalServerError) return } defer rows.Close() tag := &Tag{} if _, err = fetch.Obj(tag, rows); err != nil { logs.Error("pageTag:", err) pageHttpStatusCode(w, r, http.StatusInternalServerError) return } info, err := getInfo() if err != nil { logs.Error("pageTag:", err) pageHttpStatusCode(w, r, http.StatusInternalServerError) return } info.Canonical = app.URL(tag.Permalink()) info.Title = tag.Title page := conv.MustInt(r.FormValue("page"), 1) if page < 1 { // 不能小于1 page = 1 } else if page > 1 { // 为1的时候,不需要prev info.PrevPage = &Anchor{Title: "上一页", Link: app.TagURL(tagName, page-1)} } if page*opt.SidebarSize < tag.Count() { info.NextPage = &Anchor{Title: "下一页", Link: app.TagURL(tagName, page+1)} } posts, err := getTagPosts(page-1, tag.ID) if err != nil { logs.Error("pageTag:", err) pageHttpStatusCode(w, r, http.StatusInternalServerError) return } data := map[string]interface{}{ "info": info, "tag": tag, "posts": posts, } render(w, r, "tag", data, map[string]string{"Content-Type": "text/html"}) }
func getTags() ([]*Tag, error) { sql := "SELECT {title} AS {Title}, {name} AS {Name} FROM #tags" rows, err := db.Query(true, sql) if err != nil { return nil, err } tags := make([]*Tag, 0, opt.SidebarSize) _, err = fetch.Obj(&tags, rows) rows.Close() if err != nil { return nil, err } return tags, nil }
func getPosts(page int) ([]*Post, error) { posts := make([]*Post, 0, opt.PageSize) sql := `SELECT {id} AS {ID}, {name} AS {Name}, {title} AS {Title}, {summary} AS {Summary}, {content} AS {Content}, {created} AS {Created}, {modified} AS {Mofified}, {allowComment} AS {AllowComment} FROM #posts WHERE {state}=? ORDER BY {order} ASC, {created} DESC LIMIT ? OFFSET ?` rows, err := db.Query(true, sql, models.PostStatePublished, opt.PageSize, opt.PageSize*page) if err != nil { return nil, err } _, err = fetch.Obj(&posts, rows) rows.Close() return posts, err }
func getTagPosts(page int, tagID int64) ([]*Post, error) { posts := make([]*Post, 0, opt.PageSize) sql := `SELECT p.{id} AS {ID}, p.{name} AS {Name}, p.{title} AS {Title}, p.{summary} AS {Summary}, p.{content} as {Content}, p.{created} AS {Created}, p.{allowComment} AS {AllowComment} FROM #relationships AS r LEFT JOIN #posts AS p ON p.{id}=r.{postID} WHERE p.{state}=? AND r.{tagID}=? ORDER BY {order} ASC, {created} DESC LIMIT ? OFFSET ?` rows, err := db.Query(true, sql, models.PostStatePublished, tagID, opt.PageSize, opt.PageSize*page) if err != nil { return nil, err } _, err = fetch.Obj(&posts, rows) rows.Close() return posts, err }
// 获取与当前文章相关的标签。 func (p *Post) Tags() []*Tag { sql := `SELECT t.{name} AS {Name}, t.{title} AS {Title} FROM #relationships AS r LEFT JOIN #tags AS t on t.{id}=r.{tagID} WHERE r.{postID}=?` rows, err := db.Query(true, sql, p.ID) if err != nil { logs.Error("front.Post.Tags:", err) return nil } defer rows.Close() tags := make([]*Tag, 0, 5) if _, err = fetch.Obj(&tags, rows); err != nil { logs.Error("front.Post.Tags:", err) return nil } return tags }
func addTagsToSitemap(buf *bytes.Buffer, db *orm.DB, opt *app.Options) error { sql := "SELECT {id} AS ID, {name} AS Name, {title} AS Title, {description} AS Description FROM #tags" rows, err := db.Query(true, sql) if err != nil { return err } defer rows.Close() tags := make([]*front.Tag, 0, 100) if _, err := fetch.Obj(&tags, rows); err != nil { return err } now := time.Now().Unix() for _, tag := range tags { addItemToSitemap(buf, tag.Permalink(), opt.TagsChangefreq, now, opt.TagsPriority) } return nil }
func getTops() ([]*Comment, error) { sql := `SELECT c.{content} AS {Content}, c.{id} AS {ID}, p.{id} AS {PostID}, p.{name} AS {PostName} FROM #comments AS c LEFT JOIN #posts AS p ON c.{postID}=p.{id} WHERE c.{state}=? ORDER BY c.{id} DESC LIMIT ?` rows, err := db.Query(true, sql, models.CommentStateApproved, opt.SidebarSize) if err != nil { return nil, err } tops := make([]*Comment, 0, opt.SidebarSize) _, err = fetch.Obj(&tops, rows) rows.Close() if err != nil { return nil, err } return tops, nil }
func addPostsToSitemap(buf *bytes.Buffer, db *orm.DB, opt *app.Options) error { sql := `SELECT {id} AS ID, {name} AS Name, {title} AS Title, {summary} AS Summary, {content} AS Content, {created} AS Created, {modified} AS Modified FROM #posts WHERE {state}=?` rows, err := db.Query(true, sql, models.PostStatePublished) if err != nil { return err } defer rows.Close() posts := make([]*front.Post, 0, 100) if _, err := fetch.Obj(&posts, rows); err != nil { return err } for _, p := range posts { addItemToSitemap(buf, p.Permalink(), opt.PostsChangefreq, p.Modified, opt.PostsPriority) } return nil }
// 获取与某post相关联的标签 func getPostTags(postID int64) ([]*models.Tag, error) { sql := `SELECT t.{title},t.{id} FROM #relationships AS rs LEFT JOIN #tags AS t ON t.{id}=rs.{tagID} WHERE rs.{postID}=?` rows, err := db.Query(true, sql, postID) if err != nil { return nil, err } defer rows.Close() tags := make([]*models.Tag, 0, 0) num, err := fetch.Obj(&tags, rows) if err != nil { return nil, err } if num == 0 { return nil, nil } lastUpdated() return tags, nil }
// 返回文章的评论信息。 func (p *Post) Comments() []*Comment { sql := `SELECT {id} AS {ID}, {created} AS {Created}, {agent} AS {Agent}, {content} AS {Content}, {isAdmin} AS {IsAdmin}, {authorName} AS {AuthorName}, {authorURL} AS {AuthorURL}, {postID} AS {PostID} FROM #comments WHERE {postID}=? AND {state}=? ORDER BY {created} ` if opt.CommentOrder == app.CommentOrderDesc { sql += `DESC ` } rows, err := db.Query(true, sql, p.ID, models.CommentStateApproved) if err != nil { logs.Error("front.Post.Comment:", err) return nil } defer rows.Close() comments := make([]*Comment, 0, opt.PageSize) if _, err := fetch.Obj(&comments, rows); err != nil { logs.Error("front.Post.Comment:", err) return nil } return comments }
// /posts/1.html // /posts/about.html func pagePost(w http.ResponseWriter, r *http.Request) { idStr, ok := util.ParamString(w, r, "id") if !ok { return } idStr = strings.TrimSuffix(idStr, opt.Suffix) var rows *sql.Rows var err error postID, err := strconv.ParseInt(idStr, 10, 64) if err != nil { sql := `SELECT * FROM #posts WHERE {name}=?` rows, err = db.Query(true, sql, idStr) } else { sql := `SELECT * FROM #posts WHERE {id}=?` rows, err = db.Query(true, sql, postID) } if err != nil { logs.Error("pagePost:", err) pageHttpStatusCode(w, r, http.StatusInternalServerError) return } defer rows.Close() mp := &models.Post{} if _, err = fetch.Obj(mp, rows); err != nil { logs.Error("pagePost:", err) pageHttpStatusCode(w, r, http.StatusInternalServerError) return } if len(mp.Title) == 0 || mp.State != models.PostStatePublished { pageHttpStatusCode(w, r, http.StatusNotFound) return } if r.Method == "POST" { if err := insertComment(mp.ID, r); err != nil { logs.Error("pagePost:", err) } else { stats.WaitingCommentsSize++ stats.CommentsSize++ } } post := &Post{ ID: mp.ID, Name: mp.Name, Title: mp.Title, Summary: mp.Summary, Content: mp.Content, Author: opt.ScreenName, Created: mp.Created, Modified: mp.Modified, AllowComment: mp.AllowComment, } info, err := getInfo() if err != nil { logs.Error("pagePost:", err) pageHttpStatusCode(w, r, http.StatusInternalServerError) return } info.Canonical = app.URL(post.Permalink()) info.Title = post.Title info.Description = post.Summary info.Keywords = post.Keywords() data := map[string]interface{}{ "info": info, "post": post, } render(w, r, "post", data, map[string]string{"Content-Type": "text/html"}) }