mirror of
https://github.com/Eggbertx/gochan.git
synced 2025-08-20 09:26:23 -07:00
Add board catalog building
This commit is contained in:
parent
6a77bb9424
commit
75b35bdea9
10 changed files with 164 additions and 53 deletions
|
@ -42,6 +42,21 @@ a.anchor {
|
|||
visibility: hidden;
|
||||
}
|
||||
|
||||
div.catalog-thread {
|
||||
width:200px;
|
||||
max-height: 250px;
|
||||
display:inline-block;
|
||||
position:relative;
|
||||
vertical-align:top;
|
||||
overflow: hidden;
|
||||
text-align: center;
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
div.catalog-thread a {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
table#pages {
|
||||
margin-bottom:8px;
|
||||
margin-top:4px;
|
||||
|
|
|
@ -357,23 +357,68 @@ func buildBoardPages(board *BoardsTable) (html string) {
|
|||
// The return value is a string of HTML with debug information produced by the build process.
|
||||
// TODO: make this a variadic function (which ...int)
|
||||
func buildBoards(all bool, which int) (html string) {
|
||||
// if all is set to true, ignore which, otherwise, which = build only specified boardid
|
||||
if !all {
|
||||
if all {
|
||||
boards, _ := getBoardArr(nil, "")
|
||||
if len(boards) == 0 {
|
||||
return html + "No boards to build.<br />\n"
|
||||
}
|
||||
for _, board := range boards {
|
||||
html += buildBoardPages(&board) + "<br />\n"
|
||||
if board.EnableCatalog {
|
||||
html += buildCatalog(board.ID) + "<br />\n"
|
||||
}
|
||||
|
||||
html += buildThreads(true, board.ID, 0)
|
||||
}
|
||||
} else {
|
||||
boardArr, _ := getBoardArr(map[string]interface{}{"id": which}, "")
|
||||
board := boardArr[0]
|
||||
html += buildBoardPages(&board) + "<br />\n"
|
||||
if board.EnableCatalog {
|
||||
html += buildCatalog(board.ID) + "<br />\n"
|
||||
}
|
||||
html += buildThreads(true, board.ID, 0)
|
||||
return
|
||||
}
|
||||
boards, _ := getBoardArr(nil, "")
|
||||
if len(boards) == 0 {
|
||||
return html + "No boards to build.<br />\n"
|
||||
}
|
||||
|
||||
for _, board := range boards {
|
||||
html += buildBoardPages(&board) + "<br />\n"
|
||||
html += buildThreads(true, board.ID, 0)
|
||||
return
|
||||
}
|
||||
|
||||
func buildCatalog(which int) (html string) {
|
||||
board, err := getBoardFromID(which)
|
||||
if err != nil {
|
||||
html += handleError(1, err.Error())
|
||||
}
|
||||
catalogPath := path.Join(config.DocumentRoot, board.Dir, "catalog.html")
|
||||
catalogFile, err := os.OpenFile(catalogPath, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0777)
|
||||
if err != nil {
|
||||
html += handleError(1, "Failed opening /"+board.Dir+"/catalog.html: "+err.Error())
|
||||
return
|
||||
}
|
||||
threadOPs, err := getPostArr(map[string]interface{}{
|
||||
"boardid": which,
|
||||
"parentid": 0,
|
||||
"deleted_timestamp": nilTimestamp,
|
||||
}, "ORDER BY `bumped` ASC")
|
||||
if err != nil {
|
||||
html += handleError(1, "Error building catalog for /%s/: %s", board.Dir, err.Error())
|
||||
return
|
||||
}
|
||||
var threadInterfaces []interface{}
|
||||
for _, thread := range threadOPs {
|
||||
threadInterfaces = append(threadInterfaces, thread)
|
||||
}
|
||||
threadPages := paginate(config.PostsPerThreadPage, threadInterfaces)
|
||||
if err = catalog_tmpl.Execute(catalogFile, map[string]interface{}{
|
||||
"boards": allBoards,
|
||||
"config": config,
|
||||
"board": board,
|
||||
"sections": allSections,
|
||||
"threadPages": threadPages,
|
||||
}); err != nil {
|
||||
html += handleError(1, "Error building catalog for /%s/: %s", board.Dir, err.Error())
|
||||
return
|
||||
}
|
||||
html += fmt.Sprintf("Built catalog for /%s/ successfully", board.Dir)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -457,16 +502,14 @@ func buildThreadPages(op *PostTable) (html string) {
|
|||
return
|
||||
}
|
||||
|
||||
success_text := fmt.Sprintf("Built /%s/%d successfully", board.Dir, op.ID)
|
||||
html += success_text + "<br />\n"
|
||||
println(2, success_text)
|
||||
html += fmt.Sprintf("Built /%s/%d successfully", board.Dir, op.ID)
|
||||
|
||||
for page_num, page_posts := range thread_pages {
|
||||
op.CurrentPage = page_num + 1
|
||||
current_page_filepath := path.Join(config.DocumentRoot, board.Dir, "res", strconv.Itoa(op.ID)+"p"+strconv.Itoa(op.CurrentPage)+".html")
|
||||
current_page_file, err = os.OpenFile(current_page_filepath, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0777)
|
||||
if err != nil {
|
||||
html += handleError(1, "Failed opening "+current_page_filepath+": "+err.Error()) + "<br />\n"
|
||||
html += handleError(1, "<br />Failed opening "+current_page_filepath+": "+err.Error()) + "<br />\n"
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -478,13 +521,11 @@ func buildThreadPages(op *PostTable) (html string) {
|
|||
"posts": page_posts,
|
||||
"op": op,
|
||||
}); err != nil {
|
||||
html += handleError(1, "Failed building /%s/%d: %s", board.Dir, op.ID, err.Error())
|
||||
html += handleError(1, "<br />Failed building /%s/%d: %s", board.Dir, op.ID, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
success_text := fmt.Sprintf("Built /%s/%dp%d successfully", board.Dir, op.ID, op.CurrentPage)
|
||||
html += success_text + "<br />\n"
|
||||
println(2, success_text)
|
||||
html += fmt.Sprintf("<br />Built /%s/%dp%d successfully", board.Dir, op.ID, op.CurrentPage)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
@ -123,6 +123,9 @@ var funcMap = template.FuncMap{
|
|||
|
||||
// Imageboard functions
|
||||
"bannedForever": bannedForever,
|
||||
"getCatalogThumbnail": func(img string) string {
|
||||
return getThumbnailPath("catalog", img)
|
||||
},
|
||||
"getThreadID": func(post_i interface{}) (thread int) {
|
||||
post := post_i.(PostTable)
|
||||
if post.ParentID == 0 {
|
||||
|
@ -132,19 +135,8 @@ var funcMap = template.FuncMap{
|
|||
}
|
||||
return
|
||||
},
|
||||
"getThumbnailFilename": func(name string) string {
|
||||
if name == "" || name == "deleted" {
|
||||
return ""
|
||||
}
|
||||
|
||||
if name[len(name)-3:] == "gif" {
|
||||
name = name[:len(name)-3] + "jpg"
|
||||
} else if name[len(name)-4:] == "webm" {
|
||||
name = name[:len(name)-4] + "jpg"
|
||||
}
|
||||
extBegin := strings.LastIndex(name, ".")
|
||||
newName := name[:extBegin] + "t." + getFileExtension(name)
|
||||
return newName
|
||||
"getThreadThumbnail": func(img string) string {
|
||||
return getThumbnailPath("thread", img)
|
||||
},
|
||||
"getUploadType": func(name string) string {
|
||||
extension := getFileExtension(name)
|
||||
|
@ -162,7 +154,7 @@ var funcMap = template.FuncMap{
|
|||
}
|
||||
return uploadType
|
||||
},
|
||||
"imageToThumbnailPath": func(img string) string {
|
||||
"imageToThumbnailPath": func(thumbType string, img string) string {
|
||||
filetype := strings.ToLower(img[strings.LastIndex(img, ".")+1:])
|
||||
if filetype == "gif" || filetype == "webm" {
|
||||
filetype = "jpg"
|
||||
|
@ -171,9 +163,14 @@ var funcMap = template.FuncMap{
|
|||
if index < 0 || index > len(img) {
|
||||
return ""
|
||||
}
|
||||
return img[0:index] + "t." + filetype
|
||||
thumbSuffix := "t." + filetype
|
||||
if thumbType == "catalog" {
|
||||
thumbSuffix = "c." + filetype
|
||||
}
|
||||
return img[0:index] + thumbSuffix
|
||||
},
|
||||
"isBanned": isBanned,
|
||||
"isBanned": isBanned,
|
||||
"numReplies": numReplies,
|
||||
|
||||
// Template convenience functions
|
||||
"makeLoop": func(n int, offset int) []int {
|
||||
|
@ -242,6 +239,7 @@ var funcMap = template.FuncMap{
|
|||
|
||||
var (
|
||||
banpage_tmpl *template.Template
|
||||
catalog_tmpl *template.Template
|
||||
errorpage_tmpl *template.Template
|
||||
front_page_tmpl *template.Template
|
||||
img_boardpage_tmpl *template.Template
|
||||
|
@ -279,6 +277,11 @@ func initTemplates() error {
|
|||
return templateError("banpage.html", err)
|
||||
}
|
||||
|
||||
catalog_tmpl, err = loadTemplate("catalog.html", "img_header.html", "global_footer.html")
|
||||
if err != nil {
|
||||
return templateError("catalog.html", err)
|
||||
}
|
||||
|
||||
errorpage_tmpl, err = loadTemplate("error.html")
|
||||
if err != nil {
|
||||
return templateError("error.html", err)
|
||||
|
|
26
src/util.go
26
src/util.go
|
@ -401,6 +401,22 @@ func humanReadableTime(t time.Time) string {
|
|||
return t.Format(config.DateTimeFormat)
|
||||
}
|
||||
|
||||
func getThumbnailPath(thumbType string, img string) string {
|
||||
filetype := strings.ToLower(img[strings.LastIndex(img, ".")+1:])
|
||||
if filetype == "gif" || filetype == "webm" {
|
||||
filetype = "jpg"
|
||||
}
|
||||
index := strings.LastIndex(img, ".")
|
||||
if index < 0 || index > len(img) {
|
||||
return ""
|
||||
}
|
||||
thumbSuffix := "t." + filetype
|
||||
if thumbType == "catalog" {
|
||||
thumbSuffix = "c." + filetype
|
||||
}
|
||||
return img[0:index] + thumbSuffix
|
||||
}
|
||||
|
||||
// paginate returns a 2d array of a specified interface from a 1d array passed in,
|
||||
// with a specified number of values per array in the 2d array.
|
||||
// interface_length is the number of interfaces per array in the 2d array (e.g, threads per page)
|
||||
|
@ -582,6 +598,16 @@ func makePostJSON(post PostTable, anonymous string) (postObj PostJSON) {
|
|||
return
|
||||
}
|
||||
|
||||
func numReplies(boardid, threadid int) int {
|
||||
var num int
|
||||
if err := queryRowSQL("SELECT COUNT(*) FROM `"+config.DBprefix+"posts` WHERE `boardid` = ? AND `parentid` = ?",
|
||||
[]interface{}{boardid, threadid}, []interface{}{&num},
|
||||
); err != nil {
|
||||
return 0
|
||||
}
|
||||
return num
|
||||
}
|
||||
|
||||
func ipMatch(newIP, existingIP string) bool {
|
||||
if newIP == existingIP {
|
||||
// both are single IPs and are the same
|
||||
|
|
27
templates/catalog.html
Normal file
27
templates/catalog.html
Normal file
|
@ -0,0 +1,27 @@
|
|||
{{template "img_header.html" .}}
|
||||
<header>
|
||||
<h1>/{{$.board.Dir}}/ - {{$.board.Title}}</h1>
|
||||
<div id="board-subtitle">Catalog</div>
|
||||
</header><hr />
|
||||
<div id="catalog-links" style="float: left;">
|
||||
[<a href="{{$.config.SiteWebfolder}}{{$.board.Dir}}">Return</a>]
|
||||
[<a href="{{$.config.SiteWebfolder}}{{$.board.Dir}}/catalog.html">Refresh</a>]
|
||||
</div>
|
||||
<div id="catalog-controls" style="float: right;">
|
||||
Sort by: <select>
|
||||
<option value="bumped">Bump order</option>
|
||||
<option value="created">Creation time</option>
|
||||
<option value="replies">Reply count</option>
|
||||
</select>
|
||||
</div><hr />
|
||||
<div id="content">{{range $_, $page := .threadPages}}{{range $_,$thread := $page}}
|
||||
<div class="catalog-thread">
|
||||
<a href="{{$.config.SiteWebfolder}}{{$.board.Dir}}/res/{{$thread.ID}}.html">
|
||||
{{if eq $thread.Filename ""}}(No file){{else if eq $thread.Filename "deleted"}}(File deleted){{else}}
|
||||
<img src="{{$.config.SiteWebfolder}}{{$.board.Dir}}/thumb/{{getThreadThumbnail $thread.Filename}}" alt="{{$.config.SiteWebfolder}}{{$.board.Dir}}/src/{{$thread.Filename}}" width="{{$thread.ThumbW}}" height="{{$thread.ThumbH}}" />
|
||||
{{end}}</a><br />
|
||||
<b>{{if eq $thread.Name ""}}Anonymous{{else}}{{$thread.Name}}{{end}}</b> | <b>R:</b> {{numReplies $.board.ID $thread.ID}}<br />
|
||||
{{$thread.MessageHTML}}
|
||||
</div>{{end}}{{end}}
|
||||
</div><hr />
|
||||
{{template "global_footer.html" .}}
|
|
@ -5,7 +5,6 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{{.config.SiteName}}</title>
|
||||
<script type="text/javascript" src="{{.config.SiteWebfolder}}javascript/jquery-3.3.1.min.js"></script>
|
||||
<script type="text/javascript" src="{{.config.SiteWebfolder}}javascript/msgpack.js"></script>
|
||||
<script type="text/javascript">
|
||||
var styles = [{{range $ii, $style := .config.Styles}}{{if gt $ii 0}}, {{end}}"{{$style}}"{{end}}];
|
||||
var webroot = "{{.config.SiteWebfolder}}"
|
||||
|
@ -90,15 +89,10 @@
|
|||
<span class="section-title"><a href="{{$post.BoardName}}/res/{{if eq $post.ParentID 0}}{{intToString $post.PostID}}.html{{else}}{{intToString $post.ParentID}}.html#{{intToString $post.PostID}}{{end}}">/{{$post.BoardName}}/</a></span> - {{$appended := stringAppend $post.Name $post.Tripcode}}{{if eq $appended ""}}<b>Anonymous</b>{{else}}<b>{{$post.Name}}</b>{{if ne $post.Tripcode ""}}!{{$post.Tripcode}}{{end}}{{end}}
|
||||
</div>
|
||||
<div class="section-body">
|
||||
{{if ne $post.Filename ""}}<a href="{{$.config.SiteWebfolder}}{{$post.BoardName}}/src/{{$post.Filename}}" target="_blank"><img src="{{$.config.SiteWebfolder}}{{$post.BoardName}}/thumb/{{getThumbnailFilename $post.Filename}}" alt="post thumbnail"/></a>{{end}}
|
||||
{{if ne $post.Filename ""}}<a href="{{$.config.SiteWebfolder}}{{$post.BoardName}}/src/{{$post.Filename}}" target="_blank"><img src="{{$.config.SiteWebfolder}}{{$post.BoardName}}/thumb/{{getThreadThumbnail $post.Filename}}" alt="post thumbnail"/></a>{{end}}
|
||||
{{truncateMessage $post.Message 225 12}}
|
||||
</div>
|
||||
</div>{{end}}{{end}}
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<a href="{{.config.SiteWebfolder}}">Home</a> | <a href="{{.config.SiteWebfolder}}#boards">Boards</a> | <a href="{{.config.SiteWebfolder}}#rules">Rules</a> | <a href="{{.config.SiteWebfolder}}#faq">FAQ</a><br />
|
||||
Powered by <a href="http://github.com/eggbertx/gochan">Gochan {{.config.Version}}</a><br />
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
{{template "global_footer.html" .}}
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
{{template "img_header.html" .}}
|
||||
<header>
|
||||
<h1>/{{$.board.Dir}}/ - {{$.board.Title}}</h1>
|
||||
<div id="board-subtitle">{{$.board.Subtitle}}</div>
|
||||
</header>
|
||||
<hr />
|
||||
<div id="right-sidelinks">
|
||||
<a href="{{.config.SiteWebfolder}}{{.board.Dir}}/catalog.html">Board catalog</a><br />
|
||||
</div>
|
||||
|
@ -13,7 +18,7 @@
|
|||
{{if ne $op.Filename ""}}
|
||||
{{if ne $op.Filename "deleted"}}
|
||||
<div class="file-info">File: <a href="{{$.config.SiteWebfolder}}{{$.board.Dir}}/src/{{$op.Filename}}" target="_blank">{{$op.Filename}}</a> - ({{formatFilesize $op.Filesize}} , {{$op.ImageW}}x{{$op.ImageH}}, {{$op.FilenameOriginal}})</div>
|
||||
<a class="upload-container" href="{{$.config.SiteWebfolder}}{{$.board.Dir}}/src/{{$op.Filename}}"><img src="{{$.config.SiteWebfolder}}{{$.board.Dir}}/thumb/{{imageToThumbnailPath $op.Filename}}" alt="{{$.config.SiteWebfolder}}{{$.board.Dir}}/src/{{$op.Filename}}" width="{{$op.ThumbW}}" height="{{$op.ThumbH}}" class="upload" /></a>
|
||||
<a class="upload-container" href="{{$.config.SiteWebfolder}}{{$.board.Dir}}/src/{{$op.Filename}}"><img src="{{$.config.SiteWebfolder}}{{$.board.Dir}}/thumb/{{getThreadThumbnail $op.Filename}}" alt="{{$.config.SiteWebfolder}}{{$.board.Dir}}/src/{{$op.Filename}}" width="{{$op.ThumbW}}" height="{{$op.ThumbH}}" class="upload" /></a>
|
||||
{{else}}
|
||||
<div class="file-deleted-box" style="text-align:center;">File removed</div>
|
||||
{{end}}
|
||||
|
@ -32,7 +37,7 @@
|
|||
{{if ne $reply.Filename ""}}
|
||||
{{if ne $reply.Filename "deleted"}}
|
||||
<span class="file-info">File: <a href="{{$.config.SiteWebfolder}}{{$.board.Dir}}/src/{{$reply.Filename}}" target="_blank">{{$reply.Filename}}</a> - ({{formatFilesize $reply.Filesize}} , {{$reply.ImageW}}x{{$reply.ImageH}}, {{$reply.FilenameOriginal}})</span><br />
|
||||
<a class="upload-container" href="{{$.config.SiteWebfolder}}{{$.board.Dir}}/src/{{$reply.Filename}}"><img src="{{$.config.SiteWebfolder}}{{$.board.Dir}}/thumb/{{imageToThumbnailPath $reply.Filename}}" alt="{{$.config.SiteWebfolder}}{{$.board.Dir}}/src/{{$reply.Filename}}" width="{{$reply.ThumbW}}" height="{{$reply.ThumbH}}" class="upload" /></a>
|
||||
<a class="upload-container" href="{{$.config.SiteWebfolder}}{{$.board.Dir}}/src/{{$reply.Filename}}"><img src="{{$.config.SiteWebfolder}}{{$.board.Dir}}/thumb/{{getThreadThumbnail $reply.Filename}}" alt="{{$.config.SiteWebfolder}}{{$.board.Dir}}/src/{{$reply.Filename}}" width="{{$reply.ThumbW}}" height="{{$reply.ThumbH}}" class="upload" /></a>
|
||||
{{else}}
|
||||
<div class="file-deleted-box" style="text-align:center;">File removed</div>
|
||||
{{end}}{{end}}
|
||||
|
|
|
@ -31,8 +31,3 @@
|
|||
<div id="topbar">
|
||||
{{range $i, $board := .boards}}<a href="{{$.config.SiteWebfolder}}{{$board.Dir}}/" class="topbar-item">/{{$board.Dir}}/</a>{{end}}
|
||||
</div>
|
||||
<header>
|
||||
<h1>/{{$.board.Dir}}/ - {{$.board.Title}}</h1>
|
||||
<div id="board-subtitle">{{$.board.Subtitle}}</div>
|
||||
</header>
|
||||
<hr />
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
{{template "img_header.html" .}}
|
||||
<header>
|
||||
<h1>/{{$.board.Dir}}/ - {{$.board.Title}}</h1>
|
||||
<div id="board-subtitle">{{$.board.Subtitle}}</div>
|
||||
</header>
|
||||
<hr />
|
||||
<div id="threadlinks-top">
|
||||
<a href="{{$.config.SiteWebfolder}}{{$.board.Dir}}/board.html" >Return</a><br />
|
||||
<select id="changepage" onchange="changePage(this)">
|
||||
|
@ -20,8 +25,8 @@
|
|||
<div class="op-post" id="op{{.op.ID}}">
|
||||
{{if ne $.op.Filename ""}}
|
||||
{{if ne $.op.Filename "deleted"}}
|
||||
<div class="file-info">File: <a href="../src/{{.op.Filename}}" target="_blank">{{.op.Filename}}</a> - ({{formatFilesize .op.Filesize}} , {{.op.ImageW}}x{{.op.ImageH}}, {{.op.FilenameOriginal}})</div>
|
||||
<a class="upload-container" href="{{.config.SiteWebfolder}}{{.board.Dir}}/src/{{.op.Filename}}"><img src="{{.config.SiteWebfolder}}{{.board.Dir}}/thumb/{{imageToThumbnailPath .op.Filename}}" alt="{{$.config.SiteWebfolder}}{{$.board.Dir}}/src/{{.op.Filename}}" width="{{.op.ThumbW}}" height="{{.op.ThumbH}}" class="upload" /></a>
|
||||
<div class="file-info">File: <a href="../src/{{.op.Filename}}" target="_blank">{{$.op.Filename}}</a> - ({{formatFilesize $.op.Filesize}} , {{$.op.ImageW}}x{{$.op.ImageH}}, {{$.op.FilenameOriginal}})</div>
|
||||
<a class="upload-container" href="{{.config.SiteWebfolder}}{{.board.Dir}}/src/{{.op.Filename}}"><img src="{{.config.SiteWebfolder}}{{.board.Dir}}/thumb/{{getThreadThumbnail .op.Filename}}" alt="{{$.config.SiteWebfolder}}{{$.board.Dir}}/src/{{.op.Filename}}" width="{{.op.ThumbW}}" height="{{.op.ThumbH}}" class="upload" /></a>
|
||||
{{else}}
|
||||
<div class="file-deleted-box" style="text-align:center;">File removed</div>
|
||||
{{end}}{{end}}
|
||||
|
@ -36,7 +41,7 @@
|
|||
{{if ne $reply.Filename ""}}
|
||||
{{if ne $reply.Filename "deleted"}}
|
||||
<span class="file-info">File: <a href="../src/{{$reply.Filename}}" target="_blank">{{$reply.Filename}}</a> - ({{formatFilesize $reply.Filesize}} , {{$reply.ImageW}}x{{$reply.ImageH}}, {{$reply.FilenameOriginal}})</span><br />
|
||||
<a class="upload-container" href="{{$.config.SiteWebfolder}}{{$.board.Dir}}/src/{{$reply.Filename}}"><img src="{{$.config.SiteWebfolder}}{{$.board.Dir}}/thumb/{{imageToThumbnailPath $reply.Filename}}" alt="{{$.config.SiteWebfolder}}{{$.board.Dir}}/src/{{$reply.Filename}}" width="{{$reply.ThumbW}}" height="{{$reply.ThumbH}}" class="upload" /></a>
|
||||
<a class="upload-container" href="{{$.config.SiteWebfolder}}{{$.board.Dir}}/src/{{$reply.Filename}}"><img src="{{$.config.SiteWebfolder}}{{$.board.Dir}}/thumb/{{getThreadThumbnail $reply.Filename}}" alt="{{$.config.SiteWebfolder}}{{$.board.Dir}}/src/{{$reply.Filename}}" width="{{$reply.ThumbW}}" height="{{$reply.ThumbH}}" class="upload" /></a>
|
||||
{{else}}
|
||||
<div class="file-deleted-box" style="text-align:center;">File removed</div>
|
||||
{{end}}{{end}}
|
||||
|
|
2
version
2
version
|
@ -1 +1 @@
|
|||
2.0.0
|
||||
2.1.0
|
Loading…
Add table
Add a link
Reference in a new issue