mirror of
https://github.com/Eggbertx/gochan.git
synced 2025-09-16 12:06:23 -07:00
Make board pages, thread pages, and catalogs render properly
This commit is contained in:
parent
29c7493715
commit
8bc5e2148b
8 changed files with 151 additions and 136 deletions
|
@ -35,8 +35,13 @@ func boolToInt(b bool) int {
|
|||
|
||||
// BuildBoardPages builds the front pages for the given board, and returns any error it encountered.
|
||||
func BuildBoardPages(board *gcsql.Board) error {
|
||||
errEv := gcutil.LogError(nil).
|
||||
Int("boardID", board.ID).
|
||||
Str("boardDir", board.Dir)
|
||||
defer errEv.Discard()
|
||||
err := gctemplates.InitTemplates("boardpage")
|
||||
if err != nil {
|
||||
errEv.Err(err).Caller().Msg("unable to initialize boardpage template")
|
||||
return err
|
||||
}
|
||||
var currentPageFile *os.File
|
||||
|
@ -47,8 +52,7 @@ func BuildBoardPages(board *gcsql.Board) error {
|
|||
|
||||
threads, err := board.GetThreads(true)
|
||||
if err != nil {
|
||||
gcutil.LogError(err).
|
||||
Int("boardID", board.ID).
|
||||
errEv.Err(err).
|
||||
Caller().Msg("Failed getting board threads")
|
||||
return fmt.Errorf("error getting OP posts for /%s/: %s", board.Dir, err.Error())
|
||||
}
|
||||
|
@ -58,10 +62,9 @@ func BuildBoardPages(board *gcsql.Board) error {
|
|||
Locked: boolToInt(thread.Locked),
|
||||
Sticky: boolToInt(thread.Stickied),
|
||||
}
|
||||
errEv.Int("threadID", thread.ID)
|
||||
if catalogThread.Images, err = thread.GetReplyFileCount(); err != nil {
|
||||
gcutil.LogError(err).
|
||||
Str("boardDir", board.Dir).
|
||||
Int("threadID", thread.ID).
|
||||
errEv.Err(err).
|
||||
Caller().Msg("Failed getting file count")
|
||||
return err
|
||||
}
|
||||
|
@ -78,42 +81,43 @@ func BuildBoardPages(board *gcsql.Board) error {
|
|||
}
|
||||
catalogThread.Replies, err = thread.GetReplyCount()
|
||||
if err != nil {
|
||||
gcutil.LogError(err).
|
||||
Str("boardDir", board.Dir).
|
||||
Int("threadID", thread.ID).
|
||||
errEv.Err(err).
|
||||
Caller().Msg("Failed getting reply count")
|
||||
return errors.New("Error getting reply count: " + err.Error())
|
||||
}
|
||||
catalogThread.posts, err = thread.GetPosts(false, true, maxRepliesOnBoardPage)
|
||||
|
||||
catalogThread.Posts, err = getThreadPosts(&thread)
|
||||
if err != nil {
|
||||
gcutil.LogError(err).
|
||||
Int("threadid", thread.ID).
|
||||
Str("boardDir", board.Dir).
|
||||
Msg("Failed getting replies")
|
||||
errEv.Err(err).
|
||||
Caller().Msg("Failed getting replies")
|
||||
return errors.New("Failed getting replies: " + err.Error())
|
||||
}
|
||||
if len(catalogThread.Posts) > maxRepliesOnBoardPage {
|
||||
op := catalogThread.Posts[0]
|
||||
replies := catalogThread.Posts[len(catalogThread.Posts)-maxRepliesOnBoardPage:]
|
||||
catalogThread.Posts = []Post{op}
|
||||
catalogThread.Posts = append(catalogThread.Posts, replies...)
|
||||
}
|
||||
catalogThread.uploads, err = thread.GetUploads()
|
||||
if err != nil {
|
||||
gcutil.LogError(err).
|
||||
Int("threadid", thread.ID).
|
||||
Str("boardDir", board.Dir).
|
||||
errEv.Err(err).
|
||||
Caller().Msg("Failed getting thread uploads")
|
||||
return errors.New("Failed getting thread uploads: " + err.Error())
|
||||
}
|
||||
|
||||
var imagesOnBoardPage int
|
||||
for _, upload := range catalogThread.uploads {
|
||||
for _, post := range catalogThread.posts {
|
||||
for _, post := range catalogThread.Posts {
|
||||
if post.ID == upload.PostID {
|
||||
imagesOnBoardPage++
|
||||
}
|
||||
}
|
||||
}
|
||||
if catalogThread.Replies > maxRepliesOnBoardPage {
|
||||
catalogThread.OmittedPosts = catalogThread.Replies - len(catalogThread.posts)
|
||||
catalogThread.OmittedPosts = catalogThread.Replies - len(catalogThread.Posts)
|
||||
catalogThread.OmittedImages = len(catalogThread.uploads) - imagesOnBoardPage
|
||||
}
|
||||
catalogThread.OmittedPosts = catalogThread.Replies - len(catalogThread.posts)
|
||||
catalogThread.OmittedPosts = catalogThread.Replies - len(catalogThread.Posts)
|
||||
|
||||
// Add thread struct to appropriate list
|
||||
if thread.Stickied {
|
||||
|
@ -131,6 +135,7 @@ func BuildBoardPages(board *gcsql.Board) error {
|
|||
|
||||
// If there are no posts on the board
|
||||
var boardPageFile *os.File
|
||||
boardConfig := config.GetBoardConfig(board.Dir)
|
||||
if len(threads) == 0 {
|
||||
catalog.currentPage = 1
|
||||
|
||||
|
@ -138,14 +143,12 @@ func BuildBoardPages(board *gcsql.Board) error {
|
|||
boardPageFile, err = os.OpenFile(path.Join(criticalCfg.DocumentRoot, board.Dir, "1.html"),
|
||||
os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0777)
|
||||
if err != nil {
|
||||
gcutil.LogError(err).
|
||||
Str("boardDir", board.Dir).
|
||||
errEv.Err(err).
|
||||
Str("page", "board.html").
|
||||
Caller().Msg("Failed getting board page")
|
||||
return fmt.Errorf("failed opening /%s/board.html: %s", board.Dir, err.Error())
|
||||
}
|
||||
|
||||
boardConfig := config.GetBoardConfig(board.Dir)
|
||||
defer boardPageFile.Close()
|
||||
// Render board page template to the file,
|
||||
// packaging the board/section list, threads, and board info
|
||||
if err = serverutil.MinifyTemplate(gctemplates.BoardPage, map[string]interface{}{
|
||||
|
@ -153,12 +156,12 @@ func BuildBoardPages(board *gcsql.Board) error {
|
|||
"boards": gcsql.AllBoards,
|
||||
"sections": gcsql.AllSections,
|
||||
"threads": threads,
|
||||
"numPages": len(threads) / boardConfig.ThreadsPerPage,
|
||||
"numPages": 1,
|
||||
"currentPage": 1,
|
||||
"board": board,
|
||||
"board_config": boardConfig,
|
||||
}, boardPageFile, "text/html"); err != nil {
|
||||
gcutil.LogError(err).
|
||||
Str("boardDir", board.Dir).
|
||||
errEv.Err(err).
|
||||
Str("page", "board.html").
|
||||
Caller().Msg("Failed building board")
|
||||
return fmt.Errorf("failed building /%s/: %s", board.Dir, err.Error())
|
||||
|
@ -173,17 +176,16 @@ func BuildBoardPages(board *gcsql.Board) error {
|
|||
// Create array of page wrapper objects, and open the file.
|
||||
var catalogPages boardCatalog
|
||||
|
||||
// catalog JSON file is built with the pages because pages are recorded in the JSON file
|
||||
catalogJSONFile, err := os.OpenFile(path.Join(criticalCfg.DocumentRoot, board.Dir, "catalog.json"), os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0777)
|
||||
if err != nil {
|
||||
gcutil.LogError(err).
|
||||
errEv.Err(err).
|
||||
Str("subject", "catalog.json").
|
||||
Str("boardDir", board.Dir).
|
||||
Msg("Failed opening catalog.json")
|
||||
Caller().Msg("Failed opening catalog.json")
|
||||
return fmt.Errorf("failed opening /%s/catalog.json: %s", board.Dir, err.Error())
|
||||
}
|
||||
defer catalogJSONFile.Close()
|
||||
|
||||
// currentBoardPage := catalog.currentPage
|
||||
for _, page := range catalog.pages {
|
||||
catalog.currentPage++
|
||||
var currentPageFilepath string
|
||||
|
@ -191,10 +193,9 @@ func BuildBoardPages(board *gcsql.Board) error {
|
|||
currentPageFilepath = path.Join(criticalCfg.DocumentRoot, board.Dir, pageFilename)
|
||||
currentPageFile, err = os.OpenFile(currentPageFilepath, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0777)
|
||||
if err != nil {
|
||||
gcutil.LogError(err).
|
||||
Str("boardDir", board.Dir).
|
||||
errEv.Err(err).
|
||||
Str("page", pageFilename).
|
||||
Msg("Failed getting board page")
|
||||
Caller().Msg("Failed getting board page")
|
||||
continue
|
||||
}
|
||||
defer currentPageFile.Close()
|
||||
|
@ -205,37 +206,34 @@ func BuildBoardPages(board *gcsql.Board) error {
|
|||
"boards": gcsql.AllBoards,
|
||||
"sections": gcsql.AllSections,
|
||||
"threads": page.Threads,
|
||||
"numPages": len(threads) / boardConfig.ThreadsPerPage,
|
||||
"currentPage": catalog.currentPage,
|
||||
"board": board,
|
||||
"board_config": boardCfg,
|
||||
"posts": []interface{}{
|
||||
gcsql.Post{},
|
||||
},
|
||||
}, currentPageFile, "text/html"); err != nil {
|
||||
gcutil.LogError(err).
|
||||
Str("boardDir", board.Dir).
|
||||
Msg("Failed building boardpage")
|
||||
return fmt.Errorf("Failed building /%s/ boardpage: %s", board.Dir, err.Error())
|
||||
errEv.Err(err).
|
||||
Caller().Send()
|
||||
return fmt.Errorf("failed building /%s/ boardpage: %s", board.Dir, err.Error())
|
||||
}
|
||||
|
||||
// Collect up threads for this page.
|
||||
page := catalogPage{}
|
||||
page.PageNum = catalog.currentPage
|
||||
// page.Threads = page.Threads
|
||||
catalogPages.pages = append(catalogPages.pages, page)
|
||||
}
|
||||
// board.CurrentPage = currentBoardPage
|
||||
|
||||
var catalogJSON []byte
|
||||
if catalogJSON, err = json.Marshal(catalog.pages); err != nil {
|
||||
gcutil.LogError(err).
|
||||
Str("boardDir", board.Dir).
|
||||
Msg("Failed to marshal to JSON")
|
||||
errEv.Err(err).
|
||||
Caller().Send()
|
||||
return errors.New("failed to marshal to JSON: " + err.Error())
|
||||
}
|
||||
if _, err = catalogJSONFile.Write(catalogJSON); err != nil {
|
||||
gcutil.LogError(err).
|
||||
Str("boardDir", board.Dir).
|
||||
Msg("Failed writing catalog.json")
|
||||
errEv.Err(err).
|
||||
Caller().Msg("Failed writing catalog.json")
|
||||
return fmt.Errorf("failed writing /%s/catalog.json: %s", board.Dir, err.Error())
|
||||
}
|
||||
return nil
|
||||
|
@ -256,7 +254,7 @@ func BuildBoards(verbose bool, which ...int) error {
|
|||
gcutil.LogError(err).
|
||||
Int("boardid", boardID).
|
||||
Caller().Msg("Unable to get board information")
|
||||
return fmt.Errorf("Error getting board information (ID: %d): %s", boardID, err.Error())
|
||||
return fmt.Errorf("unable to get board information (ID: %d): %s", boardID, err.Error())
|
||||
}
|
||||
boards = append(boards, *board)
|
||||
}
|
||||
|
@ -277,53 +275,6 @@ func BuildBoards(verbose bool, which ...int) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// BuildCatalog builds the catalog for a board with a given id
|
||||
func BuildCatalog(boardID int) error {
|
||||
errEv := gcutil.LogError(nil).
|
||||
Str("building", "catalog").
|
||||
Int("boardID", boardID)
|
||||
err := gctemplates.InitTemplates("catalog")
|
||||
if err != nil {
|
||||
errEv.Err(err).Send()
|
||||
return err
|
||||
}
|
||||
|
||||
board, err := gcsql.GetBoardFromID(boardID)
|
||||
if err != nil {
|
||||
errEv.Err(err).
|
||||
Caller().Msg("Unable to get board information")
|
||||
return err
|
||||
}
|
||||
errEv.Str("boardDir", board.Dir)
|
||||
criticalCfg := config.GetSystemCriticalConfig()
|
||||
catalogPath := path.Join(criticalCfg.DocumentRoot, board.Dir, "catalog.html")
|
||||
catalogFile, err := os.OpenFile(catalogPath, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0777)
|
||||
if err != nil {
|
||||
errEv.Err(err).Caller().Send()
|
||||
return fmt.Errorf("failed opening /%s/catalog.html: %s<br/>", board.Dir, err.Error())
|
||||
}
|
||||
|
||||
threadOPs, err := getBoardTopPosts(boardID)
|
||||
if err != nil {
|
||||
errEv.Err(err).Caller().Send()
|
||||
return fmt.Errorf("failed building catalog for /%s/: %s<br/>", board.Dir, err.Error())
|
||||
}
|
||||
boardConfig := config.GetBoardConfig(board.Dir)
|
||||
|
||||
if err = serverutil.MinifyTemplate(gctemplates.Catalog, map[string]interface{}{
|
||||
"boards": gcsql.AllBoards,
|
||||
"webroot": criticalCfg.WebRoot,
|
||||
"board": board,
|
||||
"board_config": boardConfig,
|
||||
"sections": gcsql.AllSections,
|
||||
"threads": threadOPs,
|
||||
}, catalogFile, "text/html"); err != nil {
|
||||
errEv.Err(err).Caller().Send()
|
||||
return fmt.Errorf("failed building catalog for /%s/: %s", board.Dir, err.Error())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Build builds the board and its thread files
|
||||
// if force is true, it doesn't fail if the directories exist but does fail if it is a file
|
||||
func buildBoard(board *gcsql.Board, force bool) error {
|
||||
|
|
|
@ -1,17 +1,26 @@
|
|||
package building
|
||||
|
||||
import "github.com/gochan-org/gochan/pkg/gcsql"
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/gochan-org/gochan/pkg/config"
|
||||
"github.com/gochan-org/gochan/pkg/gcsql"
|
||||
"github.com/gochan-org/gochan/pkg/gctemplates"
|
||||
"github.com/gochan-org/gochan/pkg/gcutil"
|
||||
"github.com/gochan-org/gochan/pkg/serverutil"
|
||||
)
|
||||
|
||||
type catalogThreadData struct {
|
||||
Replies int `json:"replies"`
|
||||
Images int `json:"images"`
|
||||
OmittedPosts int `json:"omitted_posts"` // posts in the thread but not shown on the board page
|
||||
OmittedImages int `json:"omitted_images"` // uploads in the thread but not shown on the board page
|
||||
Sticky int `json:"sticky"`
|
||||
Locked int `json:"locked"`
|
||||
// numPages int
|
||||
posts []gcsql.Post
|
||||
uploads []gcsql.Upload
|
||||
Replies int `json:"replies"`
|
||||
Images int `json:"images"`
|
||||
OmittedPosts int `json:"omitted_posts"` // posts in the thread but not shown on the board page
|
||||
OmittedImages int `json:"omitted_images"` // uploads in the thread but not shown on the board page
|
||||
Sticky int `json:"sticky"`
|
||||
Locked int `json:"locked"`
|
||||
Posts []Post `json:"-"`
|
||||
uploads []gcsql.Upload
|
||||
}
|
||||
|
||||
type catalogPage struct {
|
||||
|
@ -52,18 +61,49 @@ func (catalog *boardCatalog) fillPages(threadsPerPage int, threads []catalogThre
|
|||
}
|
||||
}
|
||||
|
||||
// func paginateBoards(threadsPerPage int, threads []catalogThreadData) [][]catalogThreadData {
|
||||
// var paginatedThreads [][]catalogThreadData
|
||||
// numArrays := len(threads) / threadsPerPage
|
||||
// remainder := len(threads) % threadsPerPage
|
||||
// currentIndex := 0
|
||||
// for l := 0; l < numArrays; l++ {
|
||||
// paginatedThreads = append(paginatedThreads,
|
||||
// threads[currentIndex:currentIndex+threadsPerPage])
|
||||
// currentIndex += threadsPerPage
|
||||
// }
|
||||
// if remainder > 0 {
|
||||
// paginatedThreads = append(paginatedThreads, threads[len(threads)-remainder:])
|
||||
// }
|
||||
// return paginatedThreads
|
||||
// }
|
||||
// BuildCatalog builds the catalog for a board with a given id
|
||||
func BuildCatalog(boardID int) error {
|
||||
errEv := gcutil.LogError(nil).
|
||||
Str("building", "catalog").
|
||||
Int("boardID", boardID)
|
||||
err := gctemplates.InitTemplates("catalog")
|
||||
if err != nil {
|
||||
errEv.Err(err).Send()
|
||||
return err
|
||||
}
|
||||
|
||||
board, err := gcsql.GetBoardFromID(boardID)
|
||||
if err != nil {
|
||||
errEv.Err(err).
|
||||
Caller().Msg("Unable to get board information")
|
||||
return err
|
||||
}
|
||||
errEv.Str("boardDir", board.Dir)
|
||||
criticalCfg := config.GetSystemCriticalConfig()
|
||||
catalogPath := path.Join(criticalCfg.DocumentRoot, board.Dir, "catalog.html")
|
||||
catalogFile, err := os.OpenFile(catalogPath, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0777)
|
||||
if err != nil {
|
||||
errEv.Err(err).Caller().Send()
|
||||
return fmt.Errorf("failed opening /%s/catalog.html: %s<br/>", board.Dir, err.Error())
|
||||
}
|
||||
|
||||
threadOPs, err := getBoardTopPosts(boardID)
|
||||
if err != nil {
|
||||
errEv.Err(err).Caller().Send()
|
||||
return fmt.Errorf("failed building catalog for /%s/: %s<br/>", board.Dir, err.Error())
|
||||
}
|
||||
boardConfig := config.GetBoardConfig(board.Dir)
|
||||
|
||||
if err = serverutil.MinifyTemplate(gctemplates.Catalog, map[string]interface{}{
|
||||
"boards": gcsql.AllBoards,
|
||||
"webroot": criticalCfg.WebRoot,
|
||||
"board": board,
|
||||
"board_config": boardConfig,
|
||||
"sections": gcsql.AllSections,
|
||||
"threads": threadOPs,
|
||||
}, catalogFile, "text/html"); err != nil {
|
||||
errEv.Err(err).Caller().Send()
|
||||
return fmt.Errorf("failed building catalog for /%s/: %s", board.Dir, err.Error())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -33,6 +33,16 @@ const (
|
|||
LEFT JOIN DBPREFIXfiles ON DBPREFIXfiles.post_id = DBPREFIXposts.id WHERE is_deleted = FALSE`
|
||||
)
|
||||
|
||||
func truncateString(msg string, limit int, ellipsis bool) string {
|
||||
if len(msg) > limit {
|
||||
if ellipsis {
|
||||
return msg[:limit] + "..."
|
||||
}
|
||||
return msg[:limit]
|
||||
}
|
||||
return msg
|
||||
}
|
||||
|
||||
type Post struct {
|
||||
ID int `json:"no"`
|
||||
ParentID int `json:"resto"`
|
||||
|
@ -60,6 +70,18 @@ type Post struct {
|
|||
LastModified string `json:"last_modified"`
|
||||
}
|
||||
|
||||
func (p Post) TitleText() string {
|
||||
title := "/" + p.BoardDir + "/ - "
|
||||
if p.Subject != "" {
|
||||
title += truncateString(p.Subject, 20, true)
|
||||
} else if p.Message != "" {
|
||||
title += truncateString(bbcodeTagRE.ReplaceAllString(p.MessageRaw, ""), 20, true)
|
||||
} else {
|
||||
title += "#" + strconv.Itoa(p.ID)
|
||||
}
|
||||
return title
|
||||
}
|
||||
|
||||
func (p Post) WebPath() string {
|
||||
threadID := p.ParentID
|
||||
if threadID == 0 {
|
||||
|
@ -102,7 +124,7 @@ func GetBuildablePost(id int, boardid int) (*Post, error) {
|
|||
}
|
||||
|
||||
func getBoardTopPosts(boardID int) ([]Post, error) {
|
||||
const query = "SELECT * FROM (" + postQueryBase + ") p WHERE boardid = ?"
|
||||
const query = "SELECT * FROM (" + postQueryBase + " AND is_top_post) p WHERE boardid = ?"
|
||||
rows, err := gcsql.QuerySQL(query, boardID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -124,7 +146,7 @@ func getBoardTopPosts(boardID int) ([]Post, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
post.IsTopPost = post.ParentID == 0
|
||||
post.IsTopPost = post.ParentID == 0 || post.ParentID == post.ID
|
||||
posts = append(posts, post)
|
||||
}
|
||||
return posts, nil
|
||||
|
@ -150,7 +172,7 @@ func getThreadPosts(thread *gcsql.Thread) ([]Post, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
post.IsTopPost = post.ParentID == 0
|
||||
post.IsTopPost = post.ParentID == 0 || post.ParentID == post.ID
|
||||
posts = append(posts, post)
|
||||
}
|
||||
return posts, nil
|
||||
|
|
|
@ -245,7 +245,7 @@ func (board *Board) Delete() error {
|
|||
}
|
||||
|
||||
func (board *Board) GetThreads(onlyNotDeleted bool) ([]Thread, error) {
|
||||
query := selectThreadsBaseSQL + " WHERE id = ?"
|
||||
query := selectThreadsBaseSQL + " WHERE board_id = ?"
|
||||
if onlyNotDeleted {
|
||||
query += " AND is_deleted = FALSE"
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ const (
|
|||
SELECT thread_id FROM DBPREFIXposts WHERE id = ?))`
|
||||
selectPostsBaseSQL = `SELECT
|
||||
id, thread_id, is_top_post, ip, created_on, name, tripcode, is_role_signature,
|
||||
email, subject, message, message_raw, password, deleted_at, is_deleted, banned_message
|
||||
email, subject, message, message_raw, password, deleted_at, is_deleted, COALESCE(banned_message,'') AS banned_message
|
||||
FROM DBPREFIXposts `
|
||||
)
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ func GetThreadsWithBoardID(boardID int, onlyNotDeleted bool) ([]Thread, error) {
|
|||
|
||||
func GetThreadReplyCountFromOP(opID int) (int, error) {
|
||||
const query = `SELECT COUNT(*) FROM DBPREFIXposts WHERE thread_id = (
|
||||
SELECT thread_id FROM DBPREFIXposts WHERE id = ?) AND is_deleted = 0`
|
||||
SELECT thread_id FROM DBPREFIXposts WHERE id = ?) AND is_deleted = FALSE AND is_top_post = FALSE`
|
||||
var num int
|
||||
err := QueryRowSQL(query, interfaceSlice(opID), interfaceSlice(&num))
|
||||
return num, err
|
||||
|
|
|
@ -12,14 +12,16 @@
|
|||
{{- template "postbox.html" . -}}<hr />
|
||||
<form action="{{.webroot}}util" method="POST" id="main-form">
|
||||
{{$global := .}}
|
||||
{{- range $t, $thread := .threads}}{{$op := $thread.OP}}
|
||||
{{- range $t, $thread := .threads}}{{$op := index $thread.Posts 0}}
|
||||
<div class="thread">
|
||||
{{- template "post.html" map "global" $global "board" $.board "post" $op "is_board_page" true -}}
|
||||
{{- if gt $thread.NumReplies 3 -}}
|
||||
<b>{{subtract $thread.NumReplies 3}} post{{if gt $thread.NumReplies 4}}s{{end}} omitted</b><br />
|
||||
{{- if gt $thread.Replies 3 -}}
|
||||
<b>{{subtract $thread.Replies 3}} post{{if gt $thread.Replies 4}}s{{end}} omitted</b><br />
|
||||
{{- end -}}
|
||||
{{- range $reply_num,$reply := $thread.BoardReplies -}}
|
||||
{{- template "post.html" map "global" $global "board" $.board "post" $reply -}}
|
||||
{{- range $r,$reply := $thread.Posts -}}
|
||||
{{if gt $r 0}}
|
||||
{{- template "post.html" map "global" $global "board" $.board "post" $reply -}}
|
||||
{{end}}
|
||||
{{- end -}}
|
||||
</div><hr />
|
||||
{{- end}}
|
||||
|
@ -38,20 +40,20 @@
|
|||
<a href="#">Scroll to top</a><br/>
|
||||
<table id="pages">
|
||||
<tr>
|
||||
{{/*<td>{{if gt .board.CurrentPage 1}}
|
||||
{{/*<td>{{if gt $.currentPage 1}}
|
||||
<form method="GET" action='{{.board.PagePath "prev"}}'>
|
||||
<input type="submit" value="Previous" />
|
||||
</form>
|
||||
{{- else}}Previous{{end}}</td> */}}
|
||||
<td>{{range $_,$i := makeLoop .numPages 1 -}}
|
||||
{{- if eq $.board.CurrentPage $i -}}
|
||||
{{- if eq $.currentPage $i -}}
|
||||
[<b>{{$i}}</b>]
|
||||
{{- else -}}
|
||||
[<a href="{{$.board.PagePath $i }}">{{$i}}</a>]
|
||||
{{- end -}}
|
||||
{{- end}}</td>
|
||||
{{/*
|
||||
<td>{{if lt .board.CurrentPage .numPages}}
|
||||
<td>{{if lt $.currentPage .numPages}}
|
||||
<form method="GET" action="{{.board.PagePath `next` }}">
|
||||
<input type="submit" value="Next" />
|
||||
</form>
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
{{with .board -}}
|
||||
{{with $.op -}}
|
||||
{{if ne $.op.Subject "" -}}<title>/{{$.board.Dir}}/ - {{truncateString $.op.Subject 20 true}}</title>
|
||||
{{- else if ne $.op.Message "" -}}<title>/{{$.board.Dir}}/ - {{truncateString $.op.MessageRaw 20 true}}</title>
|
||||
{{- else}}<title>/{{$.board.Dir}}/ - #{{$.op.ID}}</title>{{end}}
|
||||
{{- else}}<title>/{{$.board.Dir}}/ - {{$.board.Title}}</title>{{end}}
|
||||
<title>{{$.op.TitleText}}</title>
|
||||
{{- else}}
|
||||
<title>/{{$.board.Dir}}/ - {{$.board.Title}}</title>
|
||||
{{end}}
|
||||
{{- else}}<title>{{with $.page_title}}{{$.page_title}} - {{end}}{{.site_config.SiteName}}</title>{{end}}
|
||||
<link rel="stylesheet" href="{{.webroot}}css/global.css" />
|
||||
<link id="theme" rel="stylesheet" href="{{.webroot}}css/{{.board_config.DefaultStyle}}" />
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue