Added basic pagination for topics.

Added template functions for arithmetic.
Split the "TO-DO" section of README.md into it's own file.
Themes can now mark themselves as permanently disabled.
Improved the BBCode Bounds Checking.
Fixed a bug with the BBCode parser where part of the content at the end is cut off.
is_super_admin is now a hidden flag and isn't taken into account for Staff CSS.
Themes can now show a custom tag in the Theme Manager.
This commit is contained in:
Azareal 2017-01-21 18:16:27 +00:00
parent d4ad7f1a4c
commit 16bc3a82e2
30 changed files with 726 additions and 318 deletions

2
.gitignore vendored
View File

@ -6,4 +6,4 @@ gosora.exe
gosora.test.exe gosora.test.exe
install.exe install.exe
*.prof *.prof
.DS_Store

View File

@ -104,42 +104,22 @@ We're looking for ways to clean-up the plugin system so that all of them (except
![Cosmo Theme](https://github.com/Azareal/Gosora/blob/master/images/cosmo.png) ![Cosmo Theme](https://github.com/Azareal/Gosora/blob/master/images/cosmo.png)
# Dependencies
# TO-DO Go 1.7
Oh my, you caught me right at the start of this project. There's nothing to see here yet, asides from the absolute basics. You might want to look again later! * MariaDB
* github.com/go-sql-driver/mysql
The various little features which somehow got stuck in the net. Don't worry, I'll get to them! * golang.org/x/crypto/bcrypt
More moderation features. E.g. Move, Approval Queue (Posts made by users in certain usergroups will need to be approved by a moderator before they're publically visible), etc. # Bundled Plugins
Add a simple anti-spam measure. I have quite a few ideas in mind, but it'll take a while to implement the more advanced ones, so I'd like to put off some of those to a later date and focus on the basics. E.g. CAPTCHAs, hidden fields, etc. There are several plugins which are bundled with the software by default. These cover various common tasks which aren't common enough to clutter the core with or which have competing implementation methods (E.g. plugin_markdown vs plugin_bbcode for post mark-up).
Add a modern alert system. * Hello World / Skeleton - Example plugins for helping you learn how to develop plugins.
Add per-forum permissions to finish up the foundations of the permissions system. * BBCode - A plugin in early development for converting BBCode Tags into HTML. Don't use this in production yet.
Add a *better* plugin system. E.g. Allow for plugins written in Javascript and ones written in Go. Also, we need to add many, many, many more plugin hooks. * Markdown - An extremely simple plugin for converting Markdown into HTML.
I will need to ponder over implementing an even faster router. We don't need one immediately, although it would be nice if we could get one in the near future. It really depends. Ideally, it would be one which can easily integrate with the current structure without much work, although I'm not beyond making some alterations to faciliate it, assuming that we don't get too tightly bound to that specific router.
Allow themes to define their own templates and to override core templates with their own.
Add a friend system.
Improve profile customisability.
Implement all the common BBCode tags in plugin_bbcode
Implement all the common Markdown codes in plugin_markdown
Add more administration features.
Add more features for improving user engagement. E.g. A like system. I have a few of these in mind, but I've been pre-occupied with implementing other features.
Add a widget system.
Add support for multi-factor authentication.
Add support for secondary emails for users.

40
TODO.md Normal file
View File

@ -0,0 +1,40 @@
# TO-DO
Oh my, you caught me right at the start of this project. There's nothing to see here yet, asides from the absolute basics. You might want to look again later!
The various little features which somehow got stuck in the net. Don't worry, I'll get to them!
More moderation features. E.g. Move, Approval Queue (Posts made by users in certain usergroups will need to be approved by a moderator before they're publically visible), etc.
Add a simple anti-spam measure. I have quite a few ideas in mind, but it'll take a while to implement the more advanced ones, so I'd like to put off some of those to a later date and focus on the basics. E.g. CAPTCHAs, hidden fields, etc.
Add a modern alert system.
Add per-forum permissions to finish up the foundations of the permissions system.
Add a *better* plugin system. E.g. Allow for plugins written in Javascript and ones written in Go. Also, we need to add many, many, many more plugin hooks.
I will need to ponder over implementing an even faster router. We don't need one immediately, although it would be nice if we could get one in the near future. It really depends. Ideally, it would be one which can easily integrate with the current structure without much work, although I'm not beyond making some alterations to faciliate it, assuming that we don't get too tightly bound to that specific router.
Allow themes to define their own templates and to override core templates with their own.
Add a friend system.
Improve profile customisability.
Implement all the common BBCode tags in plugin_bbcode
Implement all the common Markdown codes in plugin_markdown
Add more administration features.
Add more features for improving user engagement. E.g. A like system. I have a few of these in mind, but I've been pre-occupied with implementing other features.
Add a widget system.
Add support for multi-factor authentication.
Add support for secondary emails for users.
Improve the shell scripts and possibly add support for Make?

View File

@ -22,7 +22,7 @@ var site_email = "" // Should be a setting
var smtp_server = "" var smtp_server = ""
//var noavatar = "https://api.adorable.io/avatars/{width}/{id}@{site_url}.png" //var noavatar = "https://api.adorable.io/avatars/{width}/{id}@{site_url}.png"
var noavatar = "https://api.adorable.io/avatars/285/{id}@" + site_url + ".png" var noavatar = "https://api.adorable.io/avatars/285/{id}@" + site_url + ".png"
var items_per_page = 40 // Should be a setting var items_per_page = 25
var site_url = "localhost:8080" var site_url = "localhost:8080"
var server_port = "8080" var server_port = "8080"

View File

@ -67,6 +67,7 @@ CREATE TABLE `topics`(
`sticky` tinyint DEFAULT 0 not null, `sticky` tinyint DEFAULT 0 not null,
`parentID` int DEFAULT 1 not null, `parentID` int DEFAULT 1 not null,
`ipaddress` varchar(200) DEFAULT '0.0.0.0.0' not null, `ipaddress` varchar(200) DEFAULT '0.0.0.0.0' not null,
`postCount` int DEFAULT 1 not null,
`data` varchar(200) DEFAULT '' not null, `data` varchar(200) DEFAULT '' not null,
primary key(`tid`) primary key(`tid`)
) CHARSET=utf8mb4 COLLATE utf8mb4_general_ci; ) CHARSET=utf8mb4 COLLATE utf8mb4_general_ci;

View File

@ -54,8 +54,8 @@ func BenchmarkTopicTemplate(b *testing.B) {
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"}) replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"})
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"}) replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"})
tpage := TopicPage{"Topic Blah",user,noticeList,replyList,topic,false} tpage := TopicPage{"Topic Blah",user,noticeList,replyList,topic,1,1,false}
tpage2 := TopicPage{"Topic Blah",admin,noticeList,replyList,topic,false} tpage2 := TopicPage{"Topic Blah",admin,noticeList,replyList,topic,1,1,false}
w := ioutil.Discard w := ioutil.Discard
b.Run("compiled_useradmin", func(b *testing.B) { b.Run("compiled_useradmin", func(b *testing.B) {

BIN
images/pagination.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 365 KiB

BIN
images/pagination_test.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 332 KiB

36
main.go
View File

@ -24,7 +24,7 @@ const saltLength int = 32
const sessionLength int = 80 const sessionLength int = 80
var nogrouplog bool = false // This is mainly for benchmarks, as we don't want a lot of information getting in the way of the results var nogrouplog bool = false // This is mainly for benchmarks, as we don't want a lot of information getting in the way of the results
var templates = template.Must(template.ParseGlob("templates/*")) var templates = template.New("")
var no_css_tmpl = template.CSS("") var no_css_tmpl = template.CSS("")
var staff_css_tmpl = template.CSS(staff_css) var staff_css_tmpl = template.CSS(staff_css)
var settings map[string]interface{} = make(map[string]interface{}) var settings map[string]interface{} = make(map[string]interface{})
@ -47,12 +47,12 @@ func compile_templates() {
log.Print("Compiling the templates") log.Print("Compiling the templates")
topic := TopicUser{1,"Blah",template.HTML("Hey there!"),0,false,false,"",0,"","","",no_css_tmpl,0,"","","","",58,"127.0.0.1"} topic := TopicUser{1,"Blah",template.HTML("Hey there!"),0,false,false,"",0,"","127.0.0.1",0,"","",no_css_tmpl,0,"","","","",58}
var replyList []Reply var replyList []Reply
replyList = append(replyList, Reply{0,0,"",template.HTML("Yo!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"}) replyList = append(replyList, Reply{0,0,"",template.HTML("Yo!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"})
var varList map[string]VarItem = make(map[string]VarItem) var varList map[string]VarItem = make(map[string]VarItem)
tpage := TopicPage{"Title",user,noticeList,replyList,topic,false} tpage := TopicPage{"Title",user,noticeList,replyList,topic,1,1,false}
topic_id_tmpl := c.compile_template("topic.html","templates/","TopicPage", tpage, varList) topic_id_tmpl := c.compile_template("topic.html","templates/","TopicPage", tpage, varList)
topic_id_alt_tmpl := c.compile_template("topic_alt.html","templates/","TopicPage", tpage, varList) topic_id_alt_tmpl := c.compile_template("topic_alt.html","templates/","TopicPage", tpage, varList)
@ -71,7 +71,7 @@ func compile_templates() {
forums_tmpl := c.compile_template("forums.html","templates/","ForumsPage", forums_page, varList) forums_tmpl := c.compile_template("forums.html","templates/","ForumsPage", forums_page, varList)
var topicList []TopicUser var topicList []TopicUser
topicList = append(topicList, TopicUser{1,"Topic Title","The topic content.",1,false,false,"",1,"open","Admin","","",0,"","","","",58,"127.0.0.1"}) topicList = append(topicList, TopicUser{1,"Topic Title","The topic content.",1,false,false,"",1,"","127.0.0.1",0,"Admin","","",0,"","","","",58})
topics_page := TopicsPage{"Topic List",user,noticeList,topicList,""} topics_page := TopicsPage{"Topic List",user,noticeList,topicList,""}
topics_tmpl := c.compile_template("topics.html","templates/","TopicsPage", topics_page, varList) topics_tmpl := c.compile_template("topics.html","templates/","TopicsPage", topics_page, varList)
@ -92,6 +92,30 @@ func write_template(name string, content string) {
write_file("./template_" + name + ".go", content) write_file("./template_" + name + ".go", content)
} }
func init_templates() {
compile_templates()
// Filler functions for now...
fmap := make(map[string]interface{})
fmap["add"] = func(in interface{}, in2 interface{})interface{} {
return 1
}
fmap["subtract"] = func(in interface{}, in2 interface{})interface{} {
return 1
}
fmap["multiply"] = func(in interface{}, in2 interface{})interface{} {
return 1
}
fmap["divide"] = func(in interface{}, in2 interface{})interface{} {
return 1
}
// The interpreted templates...
templates.Funcs(fmap)
template.Must(templates.ParseGlob("templates/*"))
template.Must(templates.ParseGlob("pages/*"))
}
func main(){ func main(){
//if profiling { //if profiling {
// f, err := os.Create("startup_cpu.prof") // f, err := os.Create("startup_cpu.prof")
@ -104,7 +128,7 @@ func main(){
init_themes() init_themes()
var err error var err error
init_database(err) init_database(err)
compile_templates() init_templates()
db.SetMaxOpenConns(64) db.SetMaxOpenConns(64)
err = init_errors() err = init_errors()
@ -136,7 +160,7 @@ func main(){
external_sites["YT"] = "https://www.youtube.com/" external_sites["YT"] = "https://www.youtube.com/"
hooks["trow_assign"] = nil hooks["trow_assign"] = nil
hooks["rrow_assign"] = nil hooks["rrow_assign"] = nil
templates.ParseGlob("pages/*")
init_plugins() init_plugins()
router := NewRouter() router := NewRouter()

View File

@ -250,6 +250,11 @@ func route_reply_delete_submit(w http.ResponseWriter, r *http.Request) {
InternalError(err,w,r,user) InternalError(err,w,r,user)
return return
} }
_, err = remove_replies_from_topic_stmt.Exec(1, tid)
if err != nil {
InternalError(err,w,r,user)
return
}
} }
func route_profile_reply_edit_submit(w http.ResponseWriter, r *http.Request) { func route_profile_reply_edit_submit(w http.ResponseWriter, r *http.Request) {
@ -1265,7 +1270,7 @@ func route_panel_themes(w http.ResponseWriter, r *http.Request){
themeList = append(themeList, theme) themeList = append(themeList, theme)
} }
pi := Page{"Theme Manager",user,noticeList,themeList,0} pi := Page{"Theme Manager",user,noticeList,themeList,nil}
err := templates.ExecuteTemplate(w,"panel-themes.html", pi) err := templates.ExecuteTemplate(w,"panel-themes.html", pi)
if err != nil { if err != nil {
log.Print(err) log.Print(err)
@ -1292,6 +1297,10 @@ func route_panel_themes_default(w http.ResponseWriter, r *http.Request){
LocalError("The theme isn't registered in the system",w,r,user) LocalError("The theme isn't registered in the system",w,r,user)
return return
} }
if theme.Disabled {
LocalError("You must not enable this theme",w,r,user)
return
}
var isDefault bool var isDefault bool
err := db.QueryRow("SELECT `default` from `themes` where `uname` = ?", uname).Scan(&isDefault) err := db.QueryRow("SELECT `default` from `themes` where `uname` = ?", uname).Scan(&isDefault)

View File

@ -5,6 +5,7 @@ import "database/sql"
import _ "github.com/go-sql-driver/mysql" import _ "github.com/go-sql-driver/mysql"
import "log" import "log"
import "fmt" import "fmt"
import "strconv"
import "encoding/json" import "encoding/json"
var db *sql.DB var db *sql.DB
@ -12,10 +13,13 @@ var get_session_stmt *sql.Stmt
var get_topic_list_stmt *sql.Stmt var get_topic_list_stmt *sql.Stmt
var get_topic_user_stmt *sql.Stmt var get_topic_user_stmt *sql.Stmt
var get_topic_replies_stmt *sql.Stmt var get_topic_replies_stmt *sql.Stmt
var get_topic_replies_offset_stmt *sql.Stmt
var get_forum_topics_stmt *sql.Stmt var get_forum_topics_stmt *sql.Stmt
var create_topic_stmt *sql.Stmt var create_topic_stmt *sql.Stmt
var create_report_stmt *sql.Stmt var create_report_stmt *sql.Stmt
var create_reply_stmt *sql.Stmt var create_reply_stmt *sql.Stmt
var add_replies_to_topic_stmt *sql.Stmt
var remove_replies_from_topic_stmt *sql.Stmt
var update_forum_cache_stmt *sql.Stmt var update_forum_cache_stmt *sql.Stmt
var edit_topic_stmt *sql.Stmt var edit_topic_stmt *sql.Stmt
var edit_reply_stmt *sql.Stmt var edit_reply_stmt *sql.Stmt
@ -86,13 +90,19 @@ func init_database(err error) {
} }
log.Print("Preparing get_topic_user statement.") log.Print("Preparing get_topic_user statement.")
get_topic_user_stmt, err = db.Prepare("select topics.title, topics.content, topics.createdBy, topics.createdAt, topics.is_closed, topics.sticky, topics.parentID, users.name, users.avatar, users.is_super_admin, users.group, users.url_prefix, users.url_name, users.level, topics.ipaddress from topics left join users ON topics.createdBy = users.uid where tid = ?") get_topic_user_stmt, err = db.Prepare("select topics.title, topics.content, topics.createdBy, topics.createdAt, topics.is_closed, topics.sticky, topics.parentID, topics.ipaddress, topics.postCount, users.name, users.avatar, users.group, users.url_prefix, users.url_name, users.level from topics left join users ON topics.createdBy = users.uid where tid = ?")
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
log.Print("Preparing get_topic_replies statement.") log.Print("Preparing get_topic_replies statement.")
get_topic_replies_stmt, err = db.Prepare("select replies.rid, replies.content, replies.createdBy, replies.createdAt, replies.lastEdit, replies.lastEditBy, users.avatar, users.name, users.is_super_admin, users.group, users.url_prefix, users.url_name, users.level, replies.ipaddress from replies left join users ON replies.createdBy = users.uid where tid = ?") get_topic_replies_stmt, err = db.Prepare("select replies.rid, replies.content, replies.createdBy, replies.createdAt, replies.lastEdit, replies.lastEditBy, users.avatar, users.name, users.group, users.url_prefix, users.url_name, users.level, replies.ipaddress from replies left join users ON replies.createdBy = users.uid where tid = ?")
if err != nil {
log.Fatal(err)
}
log.Print("Preparing get_topic_replies_offset statement.")
get_topic_replies_offset_stmt, err = db.Prepare("select replies.rid, replies.content, replies.createdBy, replies.createdAt, replies.lastEdit, replies.lastEditBy, users.avatar, users.name, users.group, users.url_prefix, users.url_name, users.level, replies.ipaddress from replies left join users ON replies.createdBy = users.uid where tid = ? limit ? , " + strconv.Itoa(items_per_page))
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
@ -121,6 +131,18 @@ func init_database(err error) {
log.Fatal(err) log.Fatal(err)
} }
log.Print("Preparing add_replies_to_topic statement.")
add_replies_to_topic_stmt, err = db.Prepare("UPDATE topics SET postCount = postCount + ? WHERE tid = ?")
if err != nil {
log.Fatal(err)
}
log.Print("Preparing remove_replies_from_topic statement.")
remove_replies_from_topic_stmt, err = db.Prepare("UPDATE topics SET postCount = postCount - ? WHERE tid = ?")
if err != nil {
log.Fatal(err)
}
log.Print("Preparing update_forum_cache statement.") log.Print("Preparing update_forum_cache statement.")
update_forum_cache_stmt, err = db.Prepare("UPDATE forums SET lastTopic = ?, lastTopicID = ?, lastReplyer = ?, lastReplyerID = ?, lastTopicTime = NOW() WHERE fid = ?") update_forum_cache_stmt, err = db.Prepare("UPDATE forums SET lastTopic = ?, lastTopicID = ?, lastReplyer = ?, lastReplyerID = ?, lastTopicTime = NOW() WHERE fid = ?")
if err != nil { if err != nil {

View File

@ -18,6 +18,8 @@ type TopicPage struct
NoticeList []string NoticeList []string
ItemList []Reply ItemList []Reply
Topic TopicUser Topic TopicUser
Page int
LastPage int
ExtData interface{} ExtData interface{}
} }

View File

@ -1,6 +1,6 @@
package main package main
//import "log" //import "log"
//import "fmt" import "fmt"
import "bytes" import "bytes"
//import "strings" //import "strings"
import "strconv" import "strconv"
@ -112,7 +112,7 @@ func bbcode_parse_without_code(data interface{}) interface{} {
has_i := false has_i := false
has_s := false has_s := false
complex_bbc := false complex_bbc := false
for i := 0; (i + 2) < len(msgbytes); i++ { for i := 0; (i + 3) < len(msgbytes); i++ {
if msgbytes[i] == '[' { if msgbytes[i] == '[' {
if msgbytes[i + 2] != ']' { if msgbytes[i + 2] != ']' {
if msgbytes[i + 1] == '/' { if msgbytes[i + 1] == '/' {
@ -170,6 +170,7 @@ func bbcode_parse_without_code(data interface{}) interface{} {
msgbytes = append(msgbytes, closer...) msgbytes = append(msgbytes, closer...)
} }
// Copy the new complex parser over once the rough edges have been smoothed over
if complex_bbc { if complex_bbc {
msg = bbcode_url.ReplaceAllString(msg,"<a href=\"$1$2//$3\" rel=\"nofollow\">$1$2//$3</i>") msg = bbcode_url.ReplaceAllString(msg,"<a href=\"$1$2//$3\" rel=\"nofollow\">$1$2//$3</i>")
msg = bbcode_url_label.ReplaceAllString(msg,"<a href=\"$1$2//$3\" rel=\"nofollow\">$4</i>") msg = bbcode_url_label.ReplaceAllString(msg,"<a href=\"$1$2//$3\" rel=\"nofollow\">$4</i>")
@ -187,7 +188,8 @@ func bbcode_full_parse(data interface{}) interface{} {
has_s := false has_s := false
has_c := false has_c := false
complex_bbc := false complex_bbc := false
for i := 0; (i + 2) < len(msgbytes); i++ { msglen := len(msgbytes)
for i := 0; (i + 3) < msglen; i++ {
if msgbytes[i] == '[' { if msgbytes[i] == '[' {
if msgbytes[i + 2] != ']' { if msgbytes[i + 2] != ']' {
if msgbytes[i + 1] == '/' { if msgbytes[i + 1] == '/' {
@ -213,17 +215,27 @@ func bbcode_full_parse(data interface{}) interface{} {
i += 3 i += 3
} }
} else { } else {
if msgbytes[i + 2] == 'c' && msgbytes[i + 3] == 'o' && msgbytes[i + 4] == 'd' && msgbytes[i + 5] == 'e' { if msglen >= (i+6) && msgbytes[i+2] == 'c' && msgbytes[i+3] == 'o' && msgbytes[i+4] == 'd' && msgbytes[i+5] == 'e' && msgbytes[i+6] == ']' {
has_c = false has_c = false
i += 6 i += 7
} }
//if msglen >= (i+6) {
// fmt.Println("boo")
// fmt.Println(msglen)
// fmt.Println(i+6)
// fmt.Println(string(msgbytes[i:i+6]))
//}
complex_bbc = true complex_bbc = true
} }
} else { } else {
if msgbytes[i + 1] == 'c' && msgbytes[i + 2] == 'o' && msgbytes[i + 3] == 'd' && msgbytes[i + 4] == 'e' { if msglen >= (i+5) && msgbytes[i+1] == 'c' && msgbytes[i+2] == 'o' && msgbytes[i+3] == 'd' && msgbytes[i+4] == 'e' && msgbytes[i+5] == ']' {
has_c = true has_c = true
i += 5 i += 6
} }
//if msglen >= (i+5) {
// fmt.Println("boo2")
// fmt.Println(string(msgbytes[i:i+5]))
//}
complex_bbc = true complex_bbc = true
} }
} else if !has_c { } else if !has_c {
@ -256,16 +268,17 @@ func bbcode_full_parse(data interface{}) interface{} {
} }
if complex_bbc { if complex_bbc {
i := 0
var start int var start int
var lastTag int var lastTag int
outbytes := make([]byte, len(msgbytes)) outbytes := make([]byte, msglen)
//fmt.Println(string(msgbytes)) fmt.Println(string(msgbytes))
for i := 0; i < len(msgbytes); i++ { for ; (i+3) < msglen; i++ {
MainLoop: MainLoop:
if msgbytes[i] == '[' { if msgbytes[i] == '[' {
OuterComplex: OuterComplex:
if msgbytes[i + 1] == 'u' { if msgbytes[i + 1] == 'u' {
if msgbytes[i+2] == 'r' && msgbytes[i+3] == 'l' && msgbytes[i+4] == ']' { if (msglen-1) >= (i+6) && msgbytes[i+2] == 'r' && msgbytes[i+3] == 'l' && msgbytes[i+4] == ']' {
outbytes = append(outbytes, msgbytes[lastTag:i]...) outbytes = append(outbytes, msgbytes[lastTag:i]...)
start = i + 5 start = i + 5
i = start i = start
@ -287,7 +300,12 @@ func bbcode_full_parse(data interface{}) interface{} {
} }
for ;; i++ { for ;; i++ {
if msgbytes[i] == '[' { if msglen < (i + 6) {
//fmt.Println(msglen)
//fmt.Println(i+6)
outbytes = append(outbytes, bbcode_missing_tag...)
goto OuterComplex
} else if msgbytes[i] == '[' {
if !bytes.Equal(msgbytes[i+1:i+6],[]byte("/url]")) { if !bytes.Equal(msgbytes[i+1:i+6],[]byte("/url]")) {
//log.Print("Not the URL closing tag!") //log.Print("Not the URL closing tag!")
//fmt.Println(msgbytes[i + 1:i + 6]) //fmt.Println(msgbytes[i + 1:i + 6])
@ -300,9 +318,6 @@ func bbcode_full_parse(data interface{}) interface{} {
//log.Print("Weird character") //log.Print("Weird character")
//fmt.Println(msgbytes[i]) //fmt.Println(msgbytes[i])
goto MainLoop goto MainLoop
} else if (len(msgbytes) - 1) < (i + 6) {
outbytes = append(outbytes, bbcode_missing_tag...)
goto OuterComplex
} }
} }
outbytes = append(outbytes, bbcode_url_open...) outbytes = append(outbytes, bbcode_url_open...)
@ -314,7 +329,7 @@ func bbcode_full_parse(data interface{}) interface{} {
lastTag = i lastTag = i
} }
} else if msgbytes[i + 1] == 'r' { } else if msgbytes[i + 1] == 'r' {
if bytes.Equal(msgbytes[i+2:i+6],[]byte("and]")) { if msglen >= (i+6) && bytes.Equal(msgbytes[i+2:i+6],[]byte("and]")) {
outbytes = append(outbytes, msgbytes[lastTag:i]...) outbytes = append(outbytes, msgbytes[lastTag:i]...)
start = i + 6 start = i + 6
i = start i = start
@ -340,7 +355,7 @@ func bbcode_full_parse(data interface{}) interface{} {
dat := []byte(strconv.FormatInt((random.Int63n(number)),10)) dat := []byte(strconv.FormatInt((random.Int63n(number)),10))
outbytes = append(outbytes, dat...) outbytes = append(outbytes, dat...)
//log.Print("Outputted the random number") //log.Print("Outputted the random number")
i += 6 i += 7
lastTag = i lastTag = i
} }
} }
@ -348,6 +363,9 @@ func bbcode_full_parse(data interface{}) interface{} {
} }
//fmt.Println(outbytes) //fmt.Println(outbytes)
//fmt.Println(string(outbytes)) //fmt.Println(string(outbytes))
if lastTag != i {
outbytes = append(outbytes, msgbytes[lastTag:]...)
}
if len(outbytes) != 0 { if len(outbytes) != 0 {
return string(outbytes) return string(outbytes)
} }

View File

@ -244,11 +244,13 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
var( var(
err error err error
content string content string
is_super_admin bool
group int group int
page int
offset int
replyList []Reply replyList []Reply
) )
page, _ = strconv.Atoi(r.FormValue("page"))
topic := TopicUser{Css: no_css_tmpl} topic := TopicUser{Css: no_css_tmpl}
topic.ID, err = strconv.Atoi(r.URL.Path[len("/topic/"):]) topic.ID, err = strconv.Atoi(r.URL.Path[len("/topic/"):])
if err != nil { if err != nil {
@ -263,7 +265,7 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
} }
// Get the topic.. // Get the topic..
err = get_topic_user_stmt.QueryRow(topic.ID).Scan(&topic.Title, &content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.CreatedByName, &topic.Avatar, &is_super_admin, &group, &topic.URLPrefix, &topic.URLName, &topic.Level, &topic.IpAddress) err = get_topic_user_stmt.QueryRow(topic.ID).Scan(&topic.Title, &content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.IpAddress, &topic.PostCount, &topic.CreatedByName, &topic.Avatar, &group, &topic.URLPrefix, &topic.URLName, &topic.Level)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
NotFound(w,r,user) NotFound(w,r,user)
return return
@ -287,7 +289,7 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
} else { } else {
topic.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(topic.CreatedBy),1) topic.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(topic.CreatedBy),1)
} }
if is_super_admin || groups[group].Is_Mod || groups[group].Is_Admin { if groups[group].Is_Mod || groups[group].Is_Admin {
topic.Css = staff_css_tmpl topic.Css = staff_css_tmpl
topic.Level = -1 topic.Level = -1
} }
@ -305,16 +307,34 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
} }
} }
// Calculate the offset
last_page := int(topic.PostCount / items_per_page) + 1
if page > 1 {
offset = (items_per_page * page) - items_per_page
} else if page == -1 {
page = last_page
offset = (items_per_page * page) - items_per_page
//fmt.Println(topic.PostCount)
//fmt.Println((topic.PostCount / items_per_page) + 1)
//fmt.Println(page)
//fmt.Println(offset)
} else {
page = 1
}
// Get the replies.. // Get the replies..
rows, err := get_topic_replies_stmt.Query(topic.ID) rows, err := get_topic_replies_offset_stmt.Query(topic.ID, offset)
if err != nil { if err == sql.ErrNoRows {
LocalError("Bad Page. Some of the posts may have been deleted or you got here by directly typing in the page number.",w,r,user)
return
} else if err != nil {
InternalError(err,w,r,user) InternalError(err,w,r,user)
return return
} }
replyItem := Reply{Css: no_css_tmpl} replyItem := Reply{Css: no_css_tmpl}
for rows.Next() { for rows.Next() {
err := rows.Scan(&replyItem.ID, &replyItem.Content, &replyItem.CreatedBy, &replyItem.CreatedAt, &replyItem.LastEdit, &replyItem.LastEditBy, &replyItem.Avatar, &replyItem.CreatedByName, &is_super_admin, &group, &replyItem.URLPrefix, &replyItem.URLName, &replyItem.Level, &replyItem.IpAddress) err := rows.Scan(&replyItem.ID, &replyItem.Content, &replyItem.CreatedBy, &replyItem.CreatedAt, &replyItem.LastEdit, &replyItem.LastEditBy, &replyItem.Avatar, &replyItem.CreatedByName, &group, &replyItem.URLPrefix, &replyItem.URLName, &replyItem.Level, &replyItem.IpAddress)
if err != nil { if err != nil {
InternalError(err,w,r,user) InternalError(err,w,r,user)
return return
@ -323,7 +343,7 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
replyItem.ParentID = topic.ID replyItem.ParentID = topic.ID
replyItem.ContentHtml = template.HTML(parse_message(replyItem.Content)) replyItem.ContentHtml = template.HTML(parse_message(replyItem.Content))
replyItem.ContentLines = strings.Count(replyItem.Content,"\n") replyItem.ContentLines = strings.Count(replyItem.Content,"\n")
if is_super_admin || groups[group].Is_Mod || groups[group].Is_Admin { if groups[group].Is_Mod || groups[group].Is_Admin {
replyItem.Css = staff_css_tmpl replyItem.Css = staff_css_tmpl
replyItem.Level = -1 replyItem.Level = -1
} else { } else {
@ -362,7 +382,7 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
} }
rows.Close() rows.Close()
tpage := TopicPage{topic.Title,user,noticeList,replyList,topic,nil} tpage := TopicPage{topic.Title,user,noticeList,replyList,topic,page,last_page,nil}
if template_topic_handle != nil { if template_topic_handle != nil {
template_topic_handle(tpage,w) template_topic_handle(tpage,w)
} else { } else {
@ -392,7 +412,6 @@ func route_profile(w http.ResponseWriter, r *http.Request){
replyCss template.CSS replyCss template.CSS
replyLines int replyLines int
replyTag string replyTag string
is_super_admin bool
group int group int
replyList []Reply replyList []Reply
@ -439,7 +458,7 @@ func route_profile(w http.ResponseWriter, r *http.Request){
} }
// Get the replies.. // Get the replies..
rows, err := db.Query("select users_replies.rid, users_replies.content, users_replies.createdBy, users_replies.createdAt, users_replies.lastEdit, users_replies.lastEditBy, users.avatar, users.name, users.is_super_admin, users.group from users_replies left join users ON users_replies.createdBy = users.uid where users_replies.uid = ?", puser.ID) rows, err := db.Query("select users_replies.rid, users_replies.content, users_replies.createdBy, users_replies.createdAt, users_replies.lastEdit, users_replies.lastEditBy, users.avatar, users.name, users.group from users_replies left join users ON users_replies.createdBy = users.uid where users_replies.uid = ?", puser.ID)
if err != nil { if err != nil {
InternalError(err,w,r,user) InternalError(err,w,r,user)
return return
@ -447,14 +466,14 @@ func route_profile(w http.ResponseWriter, r *http.Request){
defer rows.Close() defer rows.Close()
for rows.Next() { for rows.Next() {
err := rows.Scan(&rid, &replyContent, &replyCreatedBy, &replyCreatedAt, &replyLastEdit, &replyLastEditBy, &replyAvatar, &replyCreatedByName, &is_super_admin, &group) err := rows.Scan(&rid, &replyContent, &replyCreatedBy, &replyCreatedAt, &replyLastEdit, &replyLastEditBy, &replyAvatar, &replyCreatedByName, &group)
if err != nil { if err != nil {
InternalError(err,w,r,user) InternalError(err,w,r,user)
return return
} }
replyLines = strings.Count(replyContent,"\n") replyLines = strings.Count(replyContent,"\n")
if is_super_admin || groups[group].Is_Mod || groups[group].Is_Admin { if groups[group].Is_Mod || groups[group].Is_Admin {
replyCss = staff_css_tmpl replyCss = staff_css_tmpl
} else { } else {
replyCss = no_css_tmpl replyCss = no_css_tmpl
@ -600,6 +619,11 @@ func route_create_reply(w http.ResponseWriter, r *http.Request) {
return return
} }
_, err = add_replies_to_topic_stmt.Exec(1, tid)
if err != nil {
InternalError(err,w,r,user)
return
}
_, err = update_forum_cache_stmt.Exec(topic_name, tid, user.Name, user.ID, 1) _, err = update_forum_cache_stmt.Exec(topic_name, tid, user.Name, user.ID, 1)
if err != nil { if err != nil {
InternalError(err,w,r,user) InternalError(err,w,r,user)

View File

@ -50,100 +50,106 @@ var header_3 []byte = []byte(`
<div id="back"><div id="main">`) <div id="back"><div id="main">`)
var header_4 []byte = []byte(`<div class="alert">`) var header_4 []byte = []byte(`<div class="alert">`)
var header_5 []byte = []byte(`</div>`) var header_5 []byte = []byte(`</div>`)
var topic_0 []byte = []byte(` var topic_0 []byte = []byte(`<div class="prev_button"><a href="/topic/`)
var topic_1 []byte = []byte(`?page=`)
var topic_2 []byte = []byte(`">&lt;</a></div>`)
var topic_3 []byte = []byte(`<div class="next_button"><a href="/topic/`)
var topic_4 []byte = []byte(`?page=`)
var topic_5 []byte = []byte(`">&gt;</a></div>`)
var topic_6 []byte = []byte(`
<div class="rowblock"> <div class="rowblock">
<form action='/topic/edit/submit/`) <form action='/topic/edit/submit/`)
var topic_1 []byte = []byte(`' method="post"> var topic_7 []byte = []byte(`' method="post">
<div class="rowitem"`) <div class="rowitem"`)
var topic_2 []byte = []byte(` style="background-color: #FFFFEA;"`) var topic_8 []byte = []byte(` style="background-color: #FFFFEA;"`)
var topic_3 []byte = []byte(` style="background-color: #eaeaea;"`) var topic_9 []byte = []byte(` style="background-color: #eaeaea;"`)
var topic_4 []byte = []byte(`> var topic_10 []byte = []byte(`>
<a class='topic_name hide_on_edit'>`) <a class='topic_name hide_on_edit'>`)
var topic_5 []byte = []byte(`</a> var topic_11 []byte = []byte(`</a>
`) `)
var topic_6 []byte = []byte(`<span class='username hide_on_micro topic_status_e topic_status_closed hide_on_edit' title='Status: Closed' style="font-weight:normal;float: right;">&#x1F512;&#xFE0E</span>`) var topic_12 []byte = []byte(`<span class='username hide_on_micro topic_status_e topic_status_closed hide_on_edit' title='Status: Closed' style="font-weight:normal;float: right;">&#x1F512;&#xFE0E</span>`)
var topic_7 []byte = []byte(` var topic_13 []byte = []byte(`
<a href='/topic/edit/`) <a href='/topic/edit/`)
var topic_8 []byte = []byte(`' class="username hide_on_edit open_edit" style="font-weight: normal;margin-left: 6px;">Edit</a> var topic_14 []byte = []byte(`' class="username hide_on_edit open_edit" style="font-weight: normal;margin-left: 6px;">Edit</a>
<a href='/topic/delete/submit/`) <a href='/topic/delete/submit/`)
var topic_9 []byte = []byte(`' class="username" style="font-weight: normal;">Delete</a> var topic_15 []byte = []byte(`' class="username" style="font-weight: normal;">Delete</a>
`) `)
var topic_10 []byte = []byte(`<a href='/topic/unstick/submit/`) var topic_16 []byte = []byte(`<a href='/topic/unstick/submit/`)
var topic_11 []byte = []byte(`' class="username" style="font-weight: normal;">Unpin</a>`) var topic_17 []byte = []byte(`' class="username" style="font-weight: normal;">Unpin</a>`)
var topic_12 []byte = []byte(`<a href='/topic/stick/submit/`) var topic_18 []byte = []byte(`<a href='/topic/stick/submit/`)
var topic_13 []byte = []byte(`' class="username" style="font-weight: normal;">Pin</a>`) var topic_19 []byte = []byte(`' class="username" style="font-weight: normal;">Pin</a>`)
var topic_14 []byte = []byte(` var topic_20 []byte = []byte(`
<input class='show_on_edit topic_name_input' name="topic_name" value='`) <input class='show_on_edit topic_name_input' name="topic_name" value='`)
var topic_15 []byte = []byte(`' type="text" /> var topic_21 []byte = []byte(`' type="text" />
<select name="topic_status" class='show_on_edit topic_status_input' style='float: right;'> <select name="topic_status" class='show_on_edit topic_status_input' style='float: right;'>
<option>open</option> <option>open</option>
<option>closed</option> <option>closed</option>
</select> </select>
<button name="topic-button" class="formbutton show_on_edit submit_edit">Update</button> <button name="topic-button" class="formbutton show_on_edit submit_edit">Update</button>
`) `)
var topic_16 []byte = []byte(` var topic_22 []byte = []byte(`
<a href="/report/submit/`) <a href="/report/submit/`)
var topic_17 []byte = []byte(`?session=`) var topic_23 []byte = []byte(`?session=`)
var topic_18 []byte = []byte(`&type=topic" class="username report_item" style="font-weight: normal;">Report</a> var topic_24 []byte = []byte(`&type=topic" class="username report_item" style="font-weight: normal;">Report</a>
</div> </div>
</form> </form>
</div> </div>
<div class="rowblock post_container"> <div class="rowblock post_container">
<div class="rowitem passive editable_parent post_item" style="border-bottom: none;`) <div class="rowitem passive editable_parent post_item" style="border-bottom: none;`)
var topic_19 []byte = []byte(`background-image: url(`) var topic_25 []byte = []byte(`background-image: url(`)
var topic_20 []byte = []byte(`), url(/static/white-dot.jpg);background-position: 0px `) var topic_26 []byte = []byte(`), url(/static/white-dot.jpg);background-position: 0px `)
var topic_21 []byte = []byte(`-1`) var topic_27 []byte = []byte(`-1`)
var topic_22 []byte = []byte(`0px;background-repeat: no-repeat, repeat-y;background-size: 128px;padding-left: 136px;`) var topic_28 []byte = []byte(`0px;background-repeat: no-repeat, repeat-y;background-size: 128px;padding-left: 136px;`)
var topic_23 []byte = []byte(`"> var topic_29 []byte = []byte(`">
<p class="hide_on_edit topic_content user_content" style="margin: 0;padding: 0;">`) <p class="hide_on_edit topic_content user_content" style="margin: 0;padding: 0;">`)
var topic_24 []byte = []byte(`</p> var topic_30 []byte = []byte(`</p>
<textarea name="topic_content" class="show_on_edit topic_content_input">`) <textarea name="topic_content" class="show_on_edit topic_content_input">`)
var topic_25 []byte = []byte(`</textarea><br /><br /> var topic_31 []byte = []byte(`</textarea><br /><br />
<a href="/user/`) <a href="/user/`)
var topic_26 []byte = []byte(`" class="username real_username">`) var topic_32 []byte = []byte(`" class="username real_username">`)
var topic_27 []byte = []byte(`</a> var topic_33 []byte = []byte(`</a>
<a class="username hide_on_micro" `) <a class="username hide_on_micro" `)
var topic_28 []byte = []byte(`style="float: right;">`) var topic_34 []byte = []byte(`style="float: right;">`)
var topic_29 []byte = []byte(`style="color: #505050;float: right;">Level `) var topic_35 []byte = []byte(`style="color: #505050;float: right;">Level `)
var topic_30 []byte = []byte(`</a> var topic_36 []byte = []byte(`</a>
</div> </div>
</div><br /> </div><br />
<div class="rowblock post_container" style="overflow: hidden;">`) <div class="rowblock post_container" style="overflow: hidden;">`)
var topic_31 []byte = []byte(` var topic_37 []byte = []byte(`
<div class="rowitem rowhead passive deletable_block editable_parent post_item" style="`) <div class="rowitem rowhead passive deletable_block editable_parent post_item" style="`)
var topic_32 []byte = []byte(`background-image: url(`) var topic_38 []byte = []byte(`background-image: url(`)
var topic_33 []byte = []byte(`), url(/static/white-dot.jpg);background-position: 0px `) var topic_39 []byte = []byte(`), url(/static/white-dot.jpg);background-position: 0px `)
var topic_34 []byte = []byte(`-1`) var topic_40 []byte = []byte(`-1`)
var topic_35 []byte = []byte(`0px;background-repeat: no-repeat, repeat-y;background-size: 128px;padding-left: 136px;`) var topic_41 []byte = []byte(`0px;background-repeat: no-repeat, repeat-y;background-size: 128px;padding-left: 136px;`)
var topic_36 []byte = []byte(`"> var topic_42 []byte = []byte(`">
<p class="editable_block user_content" style="margin: 0;padding: 0;">`) <p class="editable_block user_content" style="margin: 0;padding: 0;">`)
var topic_37 []byte = []byte(`</p><br /><br /> var topic_43 []byte = []byte(`</p><br /><br />
<a href="/user/`) <a href="/user/`)
var topic_38 []byte = []byte(`" class="username real_username">`) var topic_44 []byte = []byte(`" class="username real_username">`)
var topic_39 []byte = []byte(`</a> var topic_45 []byte = []byte(`</a>
`) `)
var topic_40 []byte = []byte(`<a href="/reply/edit/submit/`) var topic_46 []byte = []byte(`<a href="/reply/edit/submit/`)
var topic_41 []byte = []byte(`" class="mod_button"><button class="username edit_item">Edit</button></a> `) var topic_47 []byte = []byte(`" class="mod_button"><button class="username edit_item">Edit</button></a> `)
var topic_42 []byte = []byte(`<a href="/reply/delete/submit/`) var topic_48 []byte = []byte(`<a href="/reply/delete/submit/`)
var topic_43 []byte = []byte(`" class="mod_button"><button class="username delete_item">Delete</button></a> `) var topic_49 []byte = []byte(`" class="mod_button"><button class="username delete_item">Delete</button></a> `)
var topic_44 []byte = []byte(` var topic_50 []byte = []byte(`
<a href="/report/submit/`) <a href="/report/submit/`)
var topic_45 []byte = []byte(`?session=`) var topic_51 []byte = []byte(`?session=`)
var topic_46 []byte = []byte(`&type=reply" class="mod_button"><button class="username report_item">Report</button></a> var topic_52 []byte = []byte(`&type=reply" class="mod_button"><button class="username report_item">Report</button></a>
<a class="username hide_on_micro" `) <a class="username hide_on_micro" `)
var topic_47 []byte = []byte(`style="float: right;">`) var topic_53 []byte = []byte(`style="float: right;">`)
var topic_48 []byte = []byte(`style="color: #505050;float: right;">Level `) var topic_54 []byte = []byte(`style="color: #505050;float: right;">Level `)
var topic_49 []byte = []byte(`</a> var topic_55 []byte = []byte(`</a>
</div> </div>
`) `)
var topic_50 []byte = []byte(`</div> var topic_56 []byte = []byte(`</div>
`) `)
var topic_51 []byte = []byte(` var topic_57 []byte = []byte(`
<div class="rowblock"> <div class="rowblock">
<form action="/reply/create/" method="post"> <form action="/reply/create/" method="post">
<input name="tid" value='`) <input name="tid" value='`)
var topic_52 []byte = []byte(`' type="hidden" /> var topic_58 []byte = []byte(`' type="hidden" />
<div class="formrow"> <div class="formrow">
<div class="formitem"><textarea name="reply-content" placeholder="Insert reply here"></textarea></div> <div class="formitem"><textarea name="reply-content" placeholder="Insert reply here"></textarea></div>
</div> </div>
@ -157,42 +163,48 @@ var footer_0 []byte = []byte(` <!--<link rel="stylesheet" href="https://use.fo
</div><div style="clear: both;"></div></div></div> </div><div style="clear: both;"></div></div></div>
</body> </body>
</html>`) </html>`)
var topic_alt_0 []byte = []byte(` var topic_alt_0 []byte = []byte(`<div class="prev_button"><a href="/topic/`)
var topic_alt_1 []byte = []byte(`?page=`)
var topic_alt_2 []byte = []byte(`">&lt;</a></div>`)
var topic_alt_3 []byte = []byte(`<div class="next_button"><a href="/topic/`)
var topic_alt_4 []byte = []byte(`?page=`)
var topic_alt_5 []byte = []byte(`">&gt;</a></div>`)
var topic_alt_6 []byte = []byte(`
<div class="rowblock"> <div class="rowblock">
<form action='/topic/edit/submit/`) <form action='/topic/edit/submit/`)
var topic_alt_1 []byte = []byte(`' method="post"> var topic_alt_7 []byte = []byte(`' method="post">
<div class="rowitem rowhead`) <div class="rowitem rowhead`)
var topic_alt_2 []byte = []byte(` topic_sticky_head`) var topic_alt_8 []byte = []byte(` topic_sticky_head`)
var topic_alt_3 []byte = []byte(` topic_closed_head`) var topic_alt_9 []byte = []byte(` topic_closed_head`)
var topic_alt_4 []byte = []byte(`"> var topic_alt_10 []byte = []byte(`">
<a class='topic_name hide_on_edit'>`) <a class='topic_name hide_on_edit'>`)
var topic_alt_5 []byte = []byte(`</a> var topic_alt_11 []byte = []byte(`</a>
`) `)
var topic_alt_6 []byte = []byte(`<span class='username hide_on_micro topic_status_e topic_status_closed hide_on_edit' title='Status: Closed' style="font-weight:normal;float: right;">&#x1F512;&#xFE0E</span>`) var topic_alt_12 []byte = []byte(`<span class='username hide_on_micro topic_status_e topic_status_closed hide_on_edit' title='Status: Closed' style="font-weight:normal;float: right;">&#x1F512;&#xFE0E</span>`)
var topic_alt_7 []byte = []byte(` var topic_alt_13 []byte = []byte(`
<a href='/topic/edit/`) <a href='/topic/edit/`)
var topic_alt_8 []byte = []byte(`' class="username hide_on_edit open_edit topic_button" style="font-weight: normal;margin-left: 6px;">Edit</a> var topic_alt_14 []byte = []byte(`' class="username hide_on_edit open_edit topic_button" style="font-weight: normal;margin-left: 6px;">Edit</a>
<a href='/topic/delete/submit/`) <a href='/topic/delete/submit/`)
var topic_alt_9 []byte = []byte(`' class="username topic_button" style="font-weight: normal;">Delete</a> var topic_alt_15 []byte = []byte(`' class="username topic_button" style="font-weight: normal;">Delete</a>
`) `)
var topic_alt_10 []byte = []byte(`<a href='/topic/unstick/submit/`) var topic_alt_16 []byte = []byte(`<a href='/topic/unstick/submit/`)
var topic_alt_11 []byte = []byte(`' class="username topic_button" style="font-weight: normal;">Unpin</a>`) var topic_alt_17 []byte = []byte(`' class="username topic_button" style="font-weight: normal;">Unpin</a>`)
var topic_alt_12 []byte = []byte(`<a href='/topic/stick/submit/`) var topic_alt_18 []byte = []byte(`<a href='/topic/stick/submit/`)
var topic_alt_13 []byte = []byte(`' class="username topic_button" style="font-weight: normal;">Pin</a>`) var topic_alt_19 []byte = []byte(`' class="username topic_button" style="font-weight: normal;">Pin</a>`)
var topic_alt_14 []byte = []byte(` var topic_alt_20 []byte = []byte(`
<input class='show_on_edit topic_name_input' name="topic_name" value='`) <input class='show_on_edit topic_name_input' name="topic_name" value='`)
var topic_alt_15 []byte = []byte(`' type="text" /> var topic_alt_21 []byte = []byte(`' type="text" />
<select name="topic_status" class='show_on_edit topic_status_input' style='float: right;'> <select name="topic_status" class='show_on_edit topic_status_input' style='float: right;'>
<option>open</option> <option>open</option>
<option>closed</option> <option>closed</option>
</select> </select>
<button name="topic-button" class="formbutton show_on_edit submit_edit">Update</button> <button name="topic-button" class="formbutton show_on_edit submit_edit">Update</button>
`) `)
var topic_alt_16 []byte = []byte(` var topic_alt_22 []byte = []byte(`
<a href="/report/submit/`) <a href="/report/submit/`)
var topic_alt_17 []byte = []byte(`?session=`) var topic_alt_23 []byte = []byte(`?session=`)
var topic_alt_18 []byte = []byte(`&type=topic" class="username report_item topic_button" style="font-weight: normal;">Report</a> var topic_alt_24 []byte = []byte(`&type=topic" class="username report_item topic_button" style="font-weight: normal;">Report</a>
</div> </div>
</form> </form>
</div> </div>
@ -201,75 +213,75 @@ var topic_alt_18 []byte = []byte(`&type=topic" class="username report_item topic
<div class="rowitem passive deletable_block editable_parent post_item" style="background-color: #eaeaea;padding-top: 4px;padding-left: 5px;clear: both;border-bottom: none;padding-right: 4px;padding-bottom: 2px;"> <div class="rowitem passive deletable_block editable_parent post_item" style="background-color: #eaeaea;padding-top: 4px;padding-left: 5px;clear: both;border-bottom: none;padding-right: 4px;padding-bottom: 2px;">
<div class="userinfo"> <div class="userinfo">
<div class="avatar_item" style="background-image: url(`) <div class="avatar_item" style="background-image: url(`)
var topic_alt_19 []byte = []byte(`), url(/static/white-dot.jpg);background-position: 0px -10px;">&nbsp;</div> var topic_alt_25 []byte = []byte(`), url(/static/white-dot.jpg);background-position: 0px -10px;">&nbsp;</div>
<a href="/user/`) <a href="/user/`)
var topic_alt_20 []byte = []byte(`" class="the_name">`) var topic_alt_26 []byte = []byte(`" class="the_name">`)
var topic_alt_21 []byte = []byte(`</a> var topic_alt_27 []byte = []byte(`</a>
`) `)
var topic_alt_22 []byte = []byte(`<div class="tag_block"><div class="tag_pre"></div><div class="post_tag">`) var topic_alt_28 []byte = []byte(`<div class="tag_block"><div class="tag_pre"></div><div class="post_tag">`)
var topic_alt_23 []byte = []byte(`</div><div class="tag_post"></div></div>`) var topic_alt_29 []byte = []byte(`</div><div class="tag_post"></div></div>`)
var topic_alt_24 []byte = []byte(`<div class="tag_block"><div class="tag_pre"></div><div class="post_tag post_level">Level `) var topic_alt_30 []byte = []byte(`<div class="tag_block"><div class="tag_pre"></div><div class="post_tag post_level">Level `)
var topic_alt_25 []byte = []byte(`</div><div class="tag_post"></div></div>`) var topic_alt_31 []byte = []byte(`</div><div class="tag_post"></div></div>`)
var topic_alt_26 []byte = []byte(` var topic_alt_32 []byte = []byte(`
</div> </div>
<div class="content_container"> <div class="content_container">
<div class="hide_on_edit topic_content user_content">`) <div class="hide_on_edit topic_content user_content">`)
var topic_alt_27 []byte = []byte(`</div> var topic_alt_33 []byte = []byte(`</div>
<textarea name="topic_content" class="show_on_edit topic_content_input">`) <textarea name="topic_content" class="show_on_edit topic_content_input">`)
var topic_alt_28 []byte = []byte(`</textarea> var topic_alt_34 []byte = []byte(`</textarea>
<div class="button_container"> <div class="button_container">
`) `)
var topic_alt_29 []byte = []byte(`<a href="#" class="action_button action_button_right ip_item">`) var topic_alt_35 []byte = []byte(`<a href="#" class="action_button action_button_right ip_item">`)
var topic_alt_30 []byte = []byte(`</a>`) var topic_alt_36 []byte = []byte(`</a>`)
var topic_alt_31 []byte = []byte(` var topic_alt_37 []byte = []byte(`
</div> </div>
</div><div style="clear:both;"></div> </div><div style="clear:both;"></div>
</div> </div>
`) `)
var topic_alt_32 []byte = []byte(` var topic_alt_38 []byte = []byte(`
<div class="rowitem passive deletable_block editable_parent post_item"> <div class="rowitem passive deletable_block editable_parent post_item">
<div class="userinfo"> <div class="userinfo">
<div class="avatar_item" style="background-image: url(`) <div class="avatar_item" style="background-image: url(`)
var topic_alt_33 []byte = []byte(`), url(/static/white-dot.jpg);background-position: 0px -10px;">&nbsp;</div> var topic_alt_39 []byte = []byte(`), url(/static/white-dot.jpg);background-position: 0px -10px;">&nbsp;</div>
<a href="/user/`) <a href="/user/`)
var topic_alt_34 []byte = []byte(`" class="the_name">`) var topic_alt_40 []byte = []byte(`" class="the_name">`)
var topic_alt_35 []byte = []byte(`</a> var topic_alt_41 []byte = []byte(`</a>
`) `)
var topic_alt_36 []byte = []byte(`<div class="tag_block"><div class="tag_pre"></div><div class="post_tag">`) var topic_alt_42 []byte = []byte(`<div class="tag_block"><div class="tag_pre"></div><div class="post_tag">`)
var topic_alt_37 []byte = []byte(`</div><div class="tag_post"></div></div>`) var topic_alt_43 []byte = []byte(`</div><div class="tag_post"></div></div>`)
var topic_alt_38 []byte = []byte(`<div class="tag_block"><div class="tag_pre"></div><div class="post_tag post_level">Level `) var topic_alt_44 []byte = []byte(`<div class="tag_block"><div class="tag_pre"></div><div class="post_tag post_level">Level `)
var topic_alt_39 []byte = []byte(`</div><div class="tag_post"></div></div>`) var topic_alt_45 []byte = []byte(`</div><div class="tag_post"></div></div>`)
var topic_alt_40 []byte = []byte(` var topic_alt_46 []byte = []byte(`
</div> </div>
<div class="content_container"> <div class="content_container">
<div class="editable_block user_content">`) <div class="editable_block user_content">`)
var topic_alt_41 []byte = []byte(`</div> var topic_alt_47 []byte = []byte(`</div>
<div class="button_container"> <div class="button_container">
`) `)
var topic_alt_42 []byte = []byte(`<a href="/reply/edit/submit/`) var topic_alt_48 []byte = []byte(`<a href="/reply/edit/submit/`)
var topic_alt_43 []byte = []byte(`" class="action_button edit_item">Edit</a>`) var topic_alt_49 []byte = []byte(`" class="action_button edit_item">Edit</a>`)
var topic_alt_44 []byte = []byte(`<a href="/reply/delete/submit/`) var topic_alt_50 []byte = []byte(`<a href="/reply/delete/submit/`)
var topic_alt_45 []byte = []byte(`" class="action_button delete_item">Delete</a>`) var topic_alt_51 []byte = []byte(`" class="action_button delete_item">Delete</a>`)
var topic_alt_46 []byte = []byte(` var topic_alt_52 []byte = []byte(`
<a href="/report/submit/`) <a href="/report/submit/`)
var topic_alt_47 []byte = []byte(`?session=`) var topic_alt_53 []byte = []byte(`?session=`)
var topic_alt_48 []byte = []byte(`&type=reply" class="action_button report_item">Report</a> var topic_alt_54 []byte = []byte(`&type=reply" class="action_button report_item">Report</a>
`) `)
var topic_alt_49 []byte = []byte(`<a href="#" class="action_button action_button_right ip_item">`) var topic_alt_55 []byte = []byte(`<a href="#" class="action_button action_button_right ip_item">`)
var topic_alt_50 []byte = []byte(`</a>`) var topic_alt_56 []byte = []byte(`</a>`)
var topic_alt_51 []byte = []byte(` var topic_alt_57 []byte = []byte(`
</div> </div>
</div> </div>
<div style="clear:both;"></div> <div style="clear:both;"></div>
</div> </div>
`) `)
var topic_alt_52 []byte = []byte(`</div> var topic_alt_58 []byte = []byte(`</div>
`) `)
var topic_alt_53 []byte = []byte(` var topic_alt_59 []byte = []byte(`
<div class="rowblock" style="border-top: none;"> <div class="rowblock" style="border-top: none;">
<form action="/reply/create/" method="post"> <form action="/reply/create/" method="post">
<input name="tid" value='`) <input name="tid" value='`)
var topic_alt_54 []byte = []byte(`' type="hidden" /> var topic_alt_60 []byte = []byte(`' type="hidden" />
<div class="formrow"> <div class="formrow">
<div class="formitem"><textarea name="reply-content" placeholder="Insert reply here"></textarea></div> <div class="formitem"><textarea name="reply-content" placeholder="Insert reply here"></textarea></div>
</div> </div>

View File

@ -41,123 +41,137 @@ w.Write([]byte(item))
w.Write(header_5) w.Write(header_5)
} }
} }
if tmpl_topic_vars.Page > 1 {
w.Write(topic_0) w.Write(topic_0)
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID))) w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
w.Write(topic_1) w.Write(topic_1)
if tmpl_topic_vars.Topic.Sticky { w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Page - 1)))
w.Write(topic_2) w.Write(topic_2)
}
if tmpl_topic_vars.LastPage != tmpl_topic_vars.Page {
w.Write(topic_3)
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
w.Write(topic_4)
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Page + 1)))
w.Write(topic_5)
}
w.Write(topic_6)
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
w.Write(topic_7)
if tmpl_topic_vars.Topic.Sticky {
w.Write(topic_8)
} else { } else {
if tmpl_topic_vars.Topic.Is_Closed { if tmpl_topic_vars.Topic.Is_Closed {
w.Write(topic_3) w.Write(topic_9)
} }
} }
w.Write(topic_4) w.Write(topic_10)
w.Write([]byte(tmpl_topic_vars.Topic.Title)) w.Write([]byte(tmpl_topic_vars.Topic.Title))
w.Write(topic_5) w.Write(topic_11)
if tmpl_topic_vars.Topic.Is_Closed { if tmpl_topic_vars.Topic.Is_Closed {
w.Write(topic_6) w.Write(topic_12)
} }
if tmpl_topic_vars.CurrentUser.Is_Mod { if tmpl_topic_vars.CurrentUser.Is_Mod {
w.Write(topic_7)
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
w.Write(topic_8)
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
w.Write(topic_9)
if tmpl_topic_vars.Topic.Sticky {
w.Write(topic_10)
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
w.Write(topic_11)
} else {
w.Write(topic_12)
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
w.Write(topic_13) w.Write(topic_13)
} w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
w.Write(topic_14) w.Write(topic_14)
w.Write([]byte(tmpl_topic_vars.Topic.Title)) w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
w.Write(topic_15) w.Write(topic_15)
} if tmpl_topic_vars.Topic.Sticky {
w.Write(topic_16) w.Write(topic_16)
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID))) w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
w.Write(topic_17) w.Write(topic_17)
w.Write([]byte(tmpl_topic_vars.CurrentUser.Session)) } else {
w.Write(topic_18) w.Write(topic_18)
if tmpl_topic_vars.Topic.Avatar != "" { w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
w.Write(topic_19) w.Write(topic_19)
w.Write([]byte(tmpl_topic_vars.Topic.Avatar)) }
w.Write(topic_20) w.Write(topic_20)
if tmpl_topic_vars.Topic.ContentLines <= 5 { w.Write([]byte(tmpl_topic_vars.Topic.Title))
w.Write(topic_21) w.Write(topic_21)
} }
w.Write(topic_22) w.Write(topic_22)
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
w.Write(topic_23)
w.Write([]byte(tmpl_topic_vars.CurrentUser.Session))
w.Write(topic_24)
if tmpl_topic_vars.Topic.Avatar != "" {
w.Write(topic_25)
w.Write([]byte(tmpl_topic_vars.Topic.Avatar))
w.Write(topic_26)
if tmpl_topic_vars.Topic.ContentLines <= 5 {
w.Write(topic_27)
}
w.Write(topic_28)
w.Write([]byte(string(tmpl_topic_vars.Topic.Css))) w.Write([]byte(string(tmpl_topic_vars.Topic.Css)))
} }
w.Write(topic_23) w.Write(topic_29)
w.Write([]byte(string(tmpl_topic_vars.Topic.Content.(template.HTML)))) w.Write([]byte(string(tmpl_topic_vars.Topic.Content.(template.HTML))))
w.Write(topic_24) w.Write(topic_30)
w.Write([]byte(string(tmpl_topic_vars.Topic.Content.(template.HTML)))) w.Write([]byte(string(tmpl_topic_vars.Topic.Content.(template.HTML))))
w.Write(topic_25) w.Write(topic_31)
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.CreatedBy))) w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.CreatedBy)))
w.Write(topic_26) w.Write(topic_32)
w.Write([]byte(tmpl_topic_vars.Topic.CreatedByName)) w.Write([]byte(tmpl_topic_vars.Topic.CreatedByName))
w.Write(topic_27) w.Write(topic_33)
if tmpl_topic_vars.Topic.Tag != "" { if tmpl_topic_vars.Topic.Tag != "" {
w.Write(topic_28) w.Write(topic_34)
w.Write([]byte(tmpl_topic_vars.Topic.Tag)) w.Write([]byte(tmpl_topic_vars.Topic.Tag))
} else { } else {
w.Write(topic_29) w.Write(topic_35)
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.Level))) w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.Level)))
} }
w.Write(topic_30) w.Write(topic_36)
if len(tmpl_topic_vars.ItemList) != 0 { if len(tmpl_topic_vars.ItemList) != 0 {
for _, item := range tmpl_topic_vars.ItemList { for _, item := range tmpl_topic_vars.ItemList {
w.Write(topic_31) w.Write(topic_37)
if item.Avatar != "" { if item.Avatar != "" {
w.Write(topic_32) w.Write(topic_38)
w.Write([]byte(item.Avatar)) w.Write([]byte(item.Avatar))
w.Write(topic_33) w.Write(topic_39)
if item.ContentLines <= 5 { if item.ContentLines <= 5 {
w.Write(topic_34) w.Write(topic_40)
} }
w.Write(topic_35) w.Write(topic_41)
w.Write([]byte(string(item.Css))) w.Write([]byte(string(item.Css)))
} }
w.Write(topic_36) w.Write(topic_42)
w.Write([]byte(string(item.ContentHtml))) w.Write([]byte(string(item.ContentHtml)))
w.Write(topic_37) w.Write(topic_43)
w.Write([]byte(strconv.Itoa(item.CreatedBy))) w.Write([]byte(strconv.Itoa(item.CreatedBy)))
w.Write(topic_38) w.Write(topic_44)
w.Write([]byte(item.CreatedByName)) w.Write([]byte(item.CreatedByName))
w.Write(topic_39) w.Write(topic_45)
if tmpl_topic_vars.CurrentUser.Perms.EditReply { if tmpl_topic_vars.CurrentUser.Perms.EditReply {
w.Write(topic_40) w.Write(topic_46)
w.Write([]byte(strconv.Itoa(item.ID))) w.Write([]byte(strconv.Itoa(item.ID)))
w.Write(topic_41) w.Write(topic_47)
} }
if tmpl_topic_vars.CurrentUser.Perms.DeleteReply { if tmpl_topic_vars.CurrentUser.Perms.DeleteReply {
w.Write(topic_42)
w.Write([]byte(strconv.Itoa(item.ID)))
w.Write(topic_43)
}
w.Write(topic_44)
w.Write([]byte(strconv.Itoa(item.ID)))
w.Write(topic_45)
w.Write([]byte(tmpl_topic_vars.CurrentUser.Session))
w.Write(topic_46)
if item.Tag != "" {
w.Write(topic_47)
w.Write([]byte(item.Tag))
} else {
w.Write(topic_48) w.Write(topic_48)
w.Write([]byte(strconv.Itoa(item.Level))) w.Write([]byte(strconv.Itoa(item.ID)))
}
w.Write(topic_49) w.Write(topic_49)
} }
}
w.Write(topic_50) w.Write(topic_50)
if tmpl_topic_vars.CurrentUser.Perms.CreateReply { w.Write([]byte(strconv.Itoa(item.ID)))
w.Write(topic_51) w.Write(topic_51)
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID))) w.Write([]byte(tmpl_topic_vars.CurrentUser.Session))
w.Write(topic_52) w.Write(topic_52)
if item.Tag != "" {
w.Write(topic_53)
w.Write([]byte(item.Tag))
} else {
w.Write(topic_54)
w.Write([]byte(strconv.Itoa(item.Level)))
}
w.Write(topic_55)
}
}
w.Write(topic_56)
if tmpl_topic_vars.CurrentUser.Perms.CreateReply {
w.Write(topic_57)
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
w.Write(topic_58)
} }
w.Write(footer_0) w.Write(footer_0)
} }

View File

@ -41,121 +41,135 @@ w.Write([]byte(item))
w.Write(header_5) w.Write(header_5)
} }
} }
if tmpl_topic_alt_vars.Page > 1 {
w.Write(topic_alt_0) w.Write(topic_alt_0)
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID))) w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
w.Write(topic_alt_1) w.Write(topic_alt_1)
if tmpl_topic_alt_vars.Topic.Sticky { w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Page - 1)))
w.Write(topic_alt_2) w.Write(topic_alt_2)
}
if tmpl_topic_alt_vars.LastPage != tmpl_topic_alt_vars.Page {
w.Write(topic_alt_3)
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
w.Write(topic_alt_4)
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Page + 1)))
w.Write(topic_alt_5)
}
w.Write(topic_alt_6)
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
w.Write(topic_alt_7)
if tmpl_topic_alt_vars.Topic.Sticky {
w.Write(topic_alt_8)
} else { } else {
if tmpl_topic_alt_vars.Topic.Is_Closed { if tmpl_topic_alt_vars.Topic.Is_Closed {
w.Write(topic_alt_3) w.Write(topic_alt_9)
} }
} }
w.Write(topic_alt_4) w.Write(topic_alt_10)
w.Write([]byte(tmpl_topic_alt_vars.Topic.Title)) w.Write([]byte(tmpl_topic_alt_vars.Topic.Title))
w.Write(topic_alt_5) w.Write(topic_alt_11)
if tmpl_topic_alt_vars.Topic.Is_Closed { if tmpl_topic_alt_vars.Topic.Is_Closed {
w.Write(topic_alt_6) w.Write(topic_alt_12)
} }
if tmpl_topic_alt_vars.CurrentUser.Is_Mod { if tmpl_topic_alt_vars.CurrentUser.Is_Mod {
w.Write(topic_alt_7)
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
w.Write(topic_alt_8)
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
w.Write(topic_alt_9)
if tmpl_topic_alt_vars.Topic.Sticky {
w.Write(topic_alt_10)
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
w.Write(topic_alt_11)
} else {
w.Write(topic_alt_12)
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
w.Write(topic_alt_13) w.Write(topic_alt_13)
} w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
w.Write(topic_alt_14) w.Write(topic_alt_14)
w.Write([]byte(tmpl_topic_alt_vars.Topic.Title)) w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
w.Write(topic_alt_15) w.Write(topic_alt_15)
} if tmpl_topic_alt_vars.Topic.Sticky {
w.Write(topic_alt_16) w.Write(topic_alt_16)
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID))) w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
w.Write(topic_alt_17) w.Write(topic_alt_17)
w.Write([]byte(tmpl_topic_alt_vars.CurrentUser.Session))
w.Write(topic_alt_18)
w.Write([]byte(tmpl_topic_alt_vars.Topic.Avatar))
w.Write(topic_alt_19)
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.CreatedBy)))
w.Write(topic_alt_20)
w.Write([]byte(tmpl_topic_alt_vars.Topic.CreatedByName))
w.Write(topic_alt_21)
if tmpl_topic_alt_vars.Topic.Tag != "" {
w.Write(topic_alt_22)
w.Write([]byte(tmpl_topic_alt_vars.Topic.Tag))
w.Write(topic_alt_23)
} else { } else {
w.Write(topic_alt_18)
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
w.Write(topic_alt_19)
}
w.Write(topic_alt_20)
w.Write([]byte(tmpl_topic_alt_vars.Topic.Title))
w.Write(topic_alt_21)
}
w.Write(topic_alt_22)
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
w.Write(topic_alt_23)
w.Write([]byte(tmpl_topic_alt_vars.CurrentUser.Session))
w.Write(topic_alt_24) w.Write(topic_alt_24)
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.Level))) w.Write([]byte(tmpl_topic_alt_vars.Topic.Avatar))
w.Write(topic_alt_25) w.Write(topic_alt_25)
} w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.CreatedBy)))
w.Write(topic_alt_26) w.Write(topic_alt_26)
w.Write([]byte(string(tmpl_topic_alt_vars.Topic.Content.(template.HTML)))) w.Write([]byte(tmpl_topic_alt_vars.Topic.CreatedByName))
w.Write(topic_alt_27) w.Write(topic_alt_27)
w.Write([]byte(string(tmpl_topic_alt_vars.Topic.Content.(template.HTML)))) if tmpl_topic_alt_vars.Topic.Tag != "" {
w.Write(topic_alt_28) w.Write(topic_alt_28)
if tmpl_topic_alt_vars.CurrentUser.Perms.ViewIPs { w.Write([]byte(tmpl_topic_alt_vars.Topic.Tag))
w.Write(topic_alt_29) w.Write(topic_alt_29)
w.Write([]byte(tmpl_topic_alt_vars.Topic.IpAddress)) } else {
w.Write(topic_alt_30) w.Write(topic_alt_30)
} w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.Level)))
w.Write(topic_alt_31) w.Write(topic_alt_31)
}
w.Write(topic_alt_32)
w.Write([]byte(string(tmpl_topic_alt_vars.Topic.Content.(template.HTML))))
w.Write(topic_alt_33)
w.Write([]byte(string(tmpl_topic_alt_vars.Topic.Content.(template.HTML))))
w.Write(topic_alt_34)
if tmpl_topic_alt_vars.CurrentUser.Perms.ViewIPs {
w.Write(topic_alt_35)
w.Write([]byte(tmpl_topic_alt_vars.Topic.IpAddress))
w.Write(topic_alt_36)
}
w.Write(topic_alt_37)
if len(tmpl_topic_alt_vars.ItemList) != 0 { if len(tmpl_topic_alt_vars.ItemList) != 0 {
for _, item := range tmpl_topic_alt_vars.ItemList { for _, item := range tmpl_topic_alt_vars.ItemList {
w.Write(topic_alt_32)
w.Write([]byte(item.Avatar))
w.Write(topic_alt_33)
w.Write([]byte(strconv.Itoa(item.CreatedBy)))
w.Write(topic_alt_34)
w.Write([]byte(item.CreatedByName))
w.Write(topic_alt_35)
if item.Tag != "" {
w.Write(topic_alt_36)
w.Write([]byte(item.Tag))
w.Write(topic_alt_37)
} else {
w.Write(topic_alt_38) w.Write(topic_alt_38)
w.Write([]byte(strconv.Itoa(item.Level))) w.Write([]byte(item.Avatar))
w.Write(topic_alt_39) w.Write(topic_alt_39)
} w.Write([]byte(strconv.Itoa(item.CreatedBy)))
w.Write(topic_alt_40) w.Write(topic_alt_40)
w.Write([]byte(string(item.ContentHtml))) w.Write([]byte(item.CreatedByName))
w.Write(topic_alt_41) w.Write(topic_alt_41)
if tmpl_topic_alt_vars.CurrentUser.Perms.EditReply { if item.Tag != "" {
w.Write(topic_alt_42) w.Write(topic_alt_42)
w.Write([]byte(strconv.Itoa(item.ID))) w.Write([]byte(item.Tag))
w.Write(topic_alt_43) w.Write(topic_alt_43)
} } else {
if tmpl_topic_alt_vars.CurrentUser.Perms.DeleteReply {
w.Write(topic_alt_44) w.Write(topic_alt_44)
w.Write([]byte(strconv.Itoa(item.ID))) w.Write([]byte(strconv.Itoa(item.Level)))
w.Write(topic_alt_45) w.Write(topic_alt_45)
} }
w.Write(topic_alt_46) w.Write(topic_alt_46)
w.Write([]byte(strconv.Itoa(item.ID))) w.Write([]byte(string(item.ContentHtml)))
w.Write(topic_alt_47) w.Write(topic_alt_47)
w.Write([]byte(tmpl_topic_alt_vars.CurrentUser.Session)) if tmpl_topic_alt_vars.CurrentUser.Perms.EditReply {
w.Write(topic_alt_48) w.Write(topic_alt_48)
if tmpl_topic_alt_vars.CurrentUser.Perms.ViewIPs { w.Write([]byte(strconv.Itoa(item.ID)))
w.Write(topic_alt_49) w.Write(topic_alt_49)
w.Write([]byte(item.IpAddress))
w.Write(topic_alt_50)
} }
if tmpl_topic_alt_vars.CurrentUser.Perms.DeleteReply {
w.Write(topic_alt_50)
w.Write([]byte(strconv.Itoa(item.ID)))
w.Write(topic_alt_51) w.Write(topic_alt_51)
} }
}
w.Write(topic_alt_52) w.Write(topic_alt_52)
if tmpl_topic_alt_vars.CurrentUser.Perms.CreateReply { w.Write([]byte(strconv.Itoa(item.ID)))
w.Write(topic_alt_53) w.Write(topic_alt_53)
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID))) w.Write([]byte(tmpl_topic_alt_vars.CurrentUser.Session))
w.Write(topic_alt_54) w.Write(topic_alt_54)
if tmpl_topic_alt_vars.CurrentUser.Perms.ViewIPs {
w.Write(topic_alt_55)
w.Write([]byte(item.IpAddress))
w.Write(topic_alt_56)
}
w.Write(topic_alt_57)
}
}
w.Write(topic_alt_58)
if tmpl_topic_alt_vars.CurrentUser.Perms.CreateReply {
w.Write(topic_alt_59)
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
w.Write(topic_alt_60)
} }
w.Write(footer_0) w.Write(footer_0)
} }

View File

@ -1,7 +1,7 @@
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */ /* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
package main package main
import "strconv"
import "io" import "io"
import "strconv"
func init() { func init() {
template_topics_handle = template_topics template_topics_handle = template_topics

View File

@ -62,6 +62,10 @@ func (c *CTemplateSet) compile_template(name string, dir string, expects string,
c.funcMap["le"] = true c.funcMap["le"] = true
c.funcMap["lt"] = true c.funcMap["lt"] = true
c.funcMap["ne"] = true c.funcMap["ne"] = true
c.funcMap["add"] = true
c.funcMap["subtract"] = true
c.funcMap["multiply"] = true
c.funcMap["divide"] = true
c.importMap = make(map[string]string) c.importMap = make(map[string]string)
c.importMap["io"] = "io" c.importMap["io"] = "io"
c.importMap["strconv"] = "strconv" c.importMap["strconv"] = "strconv"
@ -360,6 +364,13 @@ func (c *CTemplateSet) compile_subswitch(varholder string, holdreflect reflect.V
return c.compile_varsub(varname, reflectVal) return c.compile_varsub(varname, reflectVal)
case *parse.StringNode: case *parse.StringNode:
return n.Quoted return n.Quoted
case *parse.IdentifierNode:
if debug {
fmt.Println("Identifier Node: ")
fmt.Println(node)
fmt.Println(node.Args)
}
return c.compile_varsub(c.compile_identswitch(varholder, holdreflect, template_name, node))
default: default:
fmt.Println("Unknown Kind: ") fmt.Println("Unknown Kind: ")
fmt.Println(reflect.ValueOf(firstWord).Elem().Kind()) fmt.Println(reflect.ValueOf(firstWord).Elem().Kind())
@ -399,7 +410,7 @@ func (c *CTemplateSet) compile_varswitch(varholder string, holdreflect reflect.V
fmt.Println(node) fmt.Println(node)
fmt.Println(node.Args) fmt.Println(node.Args)
} }
return c.compile_identswitch(varholder, holdreflect, template_name, node) return c.compile_identswitch_n(varholder, holdreflect, template_name, node)
case *parse.DotNode: case *parse.DotNode:
return varholder return varholder
case *parse.VariableNode: case *parse.VariableNode:
@ -419,7 +430,7 @@ func (c *CTemplateSet) compile_varswitch(varholder string, holdreflect reflect.V
fmt.Println("Args: ") fmt.Println("Args: ")
fmt.Println(node.Args) fmt.Println(node.Args)
} }
out += c.compile_identswitch(varholder, holdreflect, template_name, node) out += c.compile_identswitch_n(varholder, holdreflect, template_name, node)
if debug { if debug {
fmt.Println("Out: ") fmt.Println("Out: ")
@ -436,7 +447,12 @@ func (c *CTemplateSet) compile_varswitch(varholder string, holdreflect reflect.V
return "" return ""
} }
func (c *CTemplateSet) compile_identswitch(varholder string, holdreflect reflect.Value, template_name string, node *parse.CommandNode) (out string) { func (c *CTemplateSet) compile_identswitch_n(varholder string, holdreflect reflect.Value, template_name string, node *parse.CommandNode) (out string) {
out, _ = c.compile_identswitch(varholder, holdreflect, template_name, node)
return out
}
func (c *CTemplateSet) compile_identswitch(varholder string, holdreflect reflect.Value, template_name string, node *parse.CommandNode) (out string, val reflect.Value) {
ArgLoop: ArgLoop:
for pos, id := range node.Args { for pos, id := range node.Args {
if debug { if debug {
@ -452,21 +468,125 @@ func (c *CTemplateSet) compile_identswitch(varholder string, holdreflect reflect
out += " && " out += " && "
case "le": case "le":
out += c.compile_if_varsub_n(node.Args[pos + 1].String(), varholder, template_name, holdreflect) + " <= " + c.compile_if_varsub_n(node.Args[pos + 2].String(), varholder, template_name, holdreflect) out += c.compile_if_varsub_n(node.Args[pos + 1].String(), varholder, template_name, holdreflect) + " <= " + c.compile_if_varsub_n(node.Args[pos + 2].String(), varholder, template_name, holdreflect)
if debug {
fmt.Println(node.Args[pos + 1])
fmt.Println(node.Args[pos + 2])
}
break ArgLoop break ArgLoop
case "lt": case "lt":
out += c.compile_if_varsub_n(node.Args[pos + 1].String(), varholder, template_name, holdreflect) + " < " + c.compile_if_varsub_n(node.Args[pos + 2].String(), varholder, template_name, holdreflect) out += c.compile_if_varsub_n(node.Args[pos + 1].String(), varholder, template_name, holdreflect) + " < " + c.compile_if_varsub_n(node.Args[pos + 2].String(), varholder, template_name, holdreflect)
if debug {
fmt.Println(node.Args[pos + 1])
fmt.Println(node.Args[pos + 2])
}
break ArgLoop break ArgLoop
case "gt": case "gt":
out += c.compile_if_varsub_n(node.Args[pos + 1].String(), varholder, template_name, holdreflect) + " > " + c.compile_if_varsub_n(node.Args[pos + 2].String(), varholder, template_name, holdreflect) out += c.compile_if_varsub_n(node.Args[pos + 1].String(), varholder, template_name, holdreflect) + " > " + c.compile_if_varsub_n(node.Args[pos + 2].String(), varholder, template_name, holdreflect)
if debug {
fmt.Println(node.Args[pos + 1])
fmt.Println(node.Args[pos + 2])
}
break ArgLoop break ArgLoop
case "ge": case "ge":
out += c.compile_if_varsub_n(node.Args[pos + 1].String(), varholder, template_name, holdreflect) + " >= " + c.compile_if_varsub_n(node.Args[pos + 2].String(), varholder, template_name, holdreflect) out += c.compile_if_varsub_n(node.Args[pos + 1].String(), varholder, template_name, holdreflect) + " >= " + c.compile_if_varsub_n(node.Args[pos + 2].String(), varholder, template_name, holdreflect)
if debug {
fmt.Println(node.Args[pos + 1])
fmt.Println(node.Args[pos + 2])
}
break ArgLoop break ArgLoop
case "eq": case "eq":
out += c.compile_if_varsub_n(node.Args[pos + 1].String(), varholder, template_name, holdreflect) + " == " + c.compile_if_varsub_n(node.Args[pos + 2].String(), varholder, template_name, holdreflect) out += c.compile_if_varsub_n(node.Args[pos + 1].String(), varholder, template_name, holdreflect) + " == " + c.compile_if_varsub_n(node.Args[pos + 2].String(), varholder, template_name, holdreflect)
if debug {
fmt.Println(node.Args[pos + 1])
fmt.Println(node.Args[pos + 2])
}
break ArgLoop break ArgLoop
case "ne": case "ne":
out += c.compile_if_varsub_n(node.Args[pos + 1].String(), varholder, template_name, holdreflect) + " != " + c.compile_if_varsub_n(node.Args[pos + 2].String(), varholder, template_name, holdreflect) out += c.compile_if_varsub_n(node.Args[pos + 1].String(), varholder, template_name, holdreflect) + " != " + c.compile_if_varsub_n(node.Args[pos + 2].String(), varholder, template_name, holdreflect)
if debug {
fmt.Println(node.Args[pos + 1])
fmt.Println(node.Args[pos + 2])
}
break ArgLoop
case "add":
param1, val2 := c.compile_if_varsub(node.Args[pos + 1].String(), varholder, template_name, holdreflect)
param2, val3 := c.compile_if_varsub(node.Args[pos + 2].String(), varholder, template_name, holdreflect)
if val2.IsValid() {
val = val2
} else if val3.IsValid() {
val = val3
} else {
numSample := 1
val = reflect.ValueOf(numSample)
}
out += param1 + " + " + param2
if debug {
fmt.Println("add")
fmt.Println(node.Args[pos + 1])
fmt.Println(node.Args[pos + 2])
}
break ArgLoop
case "subtract":
param1, val2 := c.compile_if_varsub(node.Args[pos + 1].String(), varholder, template_name, holdreflect)
param2, val3 := c.compile_if_varsub(node.Args[pos + 2].String(), varholder, template_name, holdreflect)
if val2.IsValid() {
val = val2
} else if val3.IsValid() {
val = val3
} else {
numSample := 1
val = reflect.ValueOf(numSample)
}
out += param1 + " - " + param2
if debug {
fmt.Println("subtract")
fmt.Println(node.Args[pos + 1])
fmt.Println(node.Args[pos + 2])
}
break ArgLoop
case "divide":
param1, val2 := c.compile_if_varsub(node.Args[pos + 1].String(), varholder, template_name, holdreflect)
param2, val3 := c.compile_if_varsub(node.Args[pos + 2].String(), varholder, template_name, holdreflect)
if val2.IsValid() {
val = val2
} else if val3.IsValid() {
val = val3
} else {
numSample := 1
val = reflect.ValueOf(numSample)
}
out += param1 + " / " + param2
if debug {
fmt.Println("divide")
fmt.Println(node.Args[pos + 1])
fmt.Println(node.Args[pos + 2])
}
break ArgLoop
case "multiply":
param1, val2 := c.compile_if_varsub(node.Args[pos + 1].String(), varholder, template_name, holdreflect)
param2, val3 := c.compile_if_varsub(node.Args[pos + 2].String(), varholder, template_name, holdreflect)
if val2.IsValid() {
val = val2
} else if val3.IsValid() {
val = val3
} else {
numSample := 1
val = reflect.ValueOf(numSample)
}
out += param1 + " * " + param2
if debug {
fmt.Println("multiply")
fmt.Println(node.Args[pos + 1])
fmt.Println(node.Args[pos + 2])
}
break ArgLoop break ArgLoop
default: default:
if debug { if debug {
@ -475,7 +595,7 @@ func (c *CTemplateSet) compile_identswitch(varholder string, holdreflect reflect
out += c.compile_if_varsub_n(id.String(), varholder, template_name, holdreflect) out += c.compile_if_varsub_n(id.String(), varholder, template_name, holdreflect)
} }
} }
return out return out, val
} }
func (c *CTemplateSet) compile_reflectswitch(varholder string, holdreflect reflect.Value, template_name string, node *parse.CommandNode) (out string, outVal reflect.Value) { func (c *CTemplateSet) compile_reflectswitch(varholder string, holdreflect reflect.Value, template_name string, node *parse.CommandNode) (out string, outVal reflect.Value) {
@ -577,12 +697,30 @@ func (c *CTemplateSet) compile_if_varsub(varname string, varholder string, templ
} }
} }
if debug {
fmt.Println("Out Value: ")
fmt.Println(out)
fmt.Println("Out Kind: ")
fmt.Println(cur.Kind())
fmt.Println("Out Type: ")
fmt.Println(cur.Type().Name())
}
for _, varItem := range c.varList { for _, varItem := range c.varList {
if strings.HasPrefix(out, varItem.Destination) { if strings.HasPrefix(out, varItem.Destination) {
out = strings.Replace(out, varItem.Destination, varItem.Name, 1) out = strings.Replace(out, varItem.Destination, varItem.Name, 1)
} }
} }
if debug {
fmt.Println("Out Value: ")
fmt.Println(out)
fmt.Println("Out Kind: ")
fmt.Println(cur.Kind())
fmt.Println("Out Type: ")
fmt.Println(cur.Type().Name())
}
_, ok := c.stats[out] _, ok := c.stats[out]
if ok { if ok {
c.stats[out]++ c.stats[out]++
@ -605,6 +743,9 @@ func (c *CTemplateSet) compile_boolsub(varname string, varholder string, templat
case reflect.Int64: case reflect.Int64:
out += " > 0" out += " > 0"
default: default:
fmt.Println(varname)
fmt.Println(varholder)
fmt.Println(val.Kind())
panic("I don't know what this variable's type is o.o\n") panic("I don't know what this variable's type is o.o\n")
} }
return out return out
@ -642,6 +783,8 @@ func (c *CTemplateSet) compile_varsub(varname string, val reflect.Value) string
case reflect.Int64: case reflect.Int64:
return "w.Write([]byte(strconv.FormatInt(" + varname + ", 10)))" return "w.Write([]byte(strconv.FormatInt(" + varname + ", 10)))"
default: default:
fmt.Println("Unknown Variable Name: ")
fmt.Println(varname)
fmt.Println("Unknown Kind: ") fmt.Println("Unknown Kind: ")
fmt.Println(val.Kind()) fmt.Println(val.Kind())
fmt.Println("Unknown Type: ") fmt.Println("Unknown Type: ")

View File

@ -13,6 +13,7 @@
</span> </span>
<span style="float: right;"> <span style="float: right;">
{{if .MobileFriendly}}<span class="username" title="Mobile Friendly">📱</span>{{end}} {{if .MobileFriendly}}<span class="username" title="Mobile Friendly">📱</span>{{end}}
{{if .Tag}}<span class="username">{{.Tag}}</span>{{end}}
{{if .Active}}<span class="username">Default</span>{{else}}<a href="/panel/themes/default/{{.Name}}?session={{$.CurrentUser.Session}}" class="username">Make Default</a>{{end}} {{if .Active}}<span class="username">Default</span>{{else}}<a href="/panel/themes/default/{{.Name}}?session={{$.CurrentUser.Session}}" class="username">Make Default</a>{{end}}
</span> </span>
</div> </div>

View File

@ -1,7 +1,9 @@
{{template "header.html" . }} {{template "header.html" . }}
{{if gt .Page 1}}<div class="prev_button"><a href="/topic/{{.Topic.ID}}?page={{subtract .Page 1}}">&lt;</a></div>{{end}}
{{if ne .LastPage .Page}}<div class="next_button"><a href="/topic/{{.Topic.ID}}?page={{add .Page 1}}">&gt;</a></div>{{end}}
<div class="rowblock"> <div class="rowblock">
<form action='/topic/edit/submit/{{.Topic.ID}}' method="post"> <form action='/topic/edit/submit/{{.Topic.ID}}' method="post">
<div class="rowitem"{{ if .Topic.Sticky }} style="background-color: #FFFFEA;"{{else if .Topic.Is_Closed}} style="background-color: #eaeaea;"{{end}}> <div class="rowitem"{{if .Topic.Sticky}} style="background-color: #FFFFEA;"{{else if .Topic.Is_Closed}} style="background-color: #eaeaea;"{{end}}>
<a class='topic_name hide_on_edit'>{{.Topic.Title}}</a> <a class='topic_name hide_on_edit'>{{.Topic.Title}}</a>
{{if .Topic.Is_Closed}}<span class='username hide_on_micro topic_status_e topic_status_closed hide_on_edit' title='Status: Closed' style="font-weight:normal;float: right;">&#x1F512;&#xFE0E</span>{{end}} {{if .Topic.Is_Closed}}<span class='username hide_on_micro topic_status_e topic_status_closed hide_on_edit' title='Status: Closed' style="font-weight:normal;float: right;">&#x1F512;&#xFE0E</span>{{end}}
{{if .CurrentUser.Is_Mod}} {{if .CurrentUser.Is_Mod}}
@ -21,7 +23,7 @@
</form> </form>
</div> </div>
<div class="rowblock post_container"> <div class="rowblock post_container">
<div class="rowitem passive editable_parent post_item" style="border-bottom: none;{{ if .Topic.Avatar }}background-image: url({{ .Topic.Avatar }}), url(/static/white-dot.jpg);background-position: 0px {{if le .Topic.ContentLines 5}}-1{{end}}0px;background-repeat: no-repeat, repeat-y;background-size: 128px;padding-left: 136px;{{.Topic.Css}}{{end}}"> <div class="rowitem passive editable_parent post_item" style="border-bottom: none;{{if .Topic.Avatar}}background-image: url({{.Topic.Avatar}}), url(/static/white-dot.jpg);background-position: 0px {{if le .Topic.ContentLines 5}}-1{{end}}0px;background-repeat: no-repeat, repeat-y;background-size: 128px;padding-left: 136px;{{.Topic.Css}}{{end}}">
<p class="hide_on_edit topic_content user_content" style="margin: 0;padding: 0;">{{.Topic.Content}}</p> <p class="hide_on_edit topic_content user_content" style="margin: 0;padding: 0;">{{.Topic.Content}}</p>
<textarea name="topic_content" class="show_on_edit topic_content_input">{{.Topic.Content}}</textarea><br /><br /> <textarea name="topic_content" class="show_on_edit topic_content_input">{{.Topic.Content}}</textarea><br /><br />
<a href="/user/{{.Topic.CreatedBy}}" class="username real_username">{{.Topic.CreatedByName}}</a> <a href="/user/{{.Topic.CreatedBy}}" class="username real_username">{{.Topic.CreatedByName}}</a>
@ -29,7 +31,7 @@
</div> </div>
</div><br /> </div><br />
<div class="rowblock post_container" style="overflow: hidden;">{{range .ItemList}} <div class="rowblock post_container" style="overflow: hidden;">{{range .ItemList}}
<div class="rowitem rowhead passive deletable_block editable_parent post_item" style="{{ if .Avatar }}background-image: url({{.Avatar}}), url(/static/white-dot.jpg);background-position: 0px {{if le .ContentLines 5}}-1{{end}}0px;background-repeat: no-repeat, repeat-y;background-size: 128px;padding-left: 136px;{{.Css}}{{end}}"> <div class="rowitem rowhead passive deletable_block editable_parent post_item" style="{{if .Avatar}}background-image: url({{.Avatar}}), url(/static/white-dot.jpg);background-position: 0px {{if le .ContentLines 5}}-1{{end}}0px;background-repeat: no-repeat, repeat-y;background-size: 128px;padding-left: 136px;{{.Css}}{{end}}">
<p class="editable_block user_content" style="margin: 0;padding: 0;">{{.ContentHtml}}</p><br /><br /> <p class="editable_block user_content" style="margin: 0;padding: 0;">{{.ContentHtml}}</p><br /><br />
<a href="/user/{{.CreatedBy}}" class="username real_username">{{.CreatedByName}}</a> <a href="/user/{{.CreatedBy}}" class="username real_username">{{.CreatedByName}}</a>
{{if $.CurrentUser.Perms.EditReply}}<a href="/reply/edit/submit/{{.ID}}" class="mod_button"><button class="username edit_item">Edit</button></a> {{end}} {{if $.CurrentUser.Perms.EditReply}}<a href="/reply/edit/submit/{{.ID}}" class="mod_button"><button class="username edit_item">Edit</button></a> {{end}}

View File

@ -1,4 +1,6 @@
{{template "header.html" . }} {{template "header.html" . }}
{{if gt .Page 1}}<div class="prev_button"><a href="/topic/{{.Topic.ID}}?page={{subtract .Page 1}}">&lt;</a></div>{{end}}
{{if ne .LastPage .Page}}<div class="next_button"><a href="/topic/{{.Topic.ID}}?page={{add .Page 1}}">&gt;</a></div>{{end}}
<div class="rowblock"> <div class="rowblock">
<form action='/topic/edit/submit/{{.Topic.ID}}' method="post"> <form action='/topic/edit/submit/{{.Topic.ID}}' method="post">
<div class="rowitem rowhead{{if .Topic.Sticky}} topic_sticky_head{{else if .Topic.Is_Closed}} topic_closed_head{{end}}"> <div class="rowitem rowhead{{if .Topic.Sticky}} topic_sticky_head{{else if .Topic.Is_Closed}} topic_closed_head{{end}}">

View File

@ -25,6 +25,8 @@ type Theme struct
Creator string Creator string
FullImage string FullImage string
MobileFriendly bool MobileFriendly bool
Disabled bool
Tag string
Settings map[string]ThemeSetting Settings map[string]ThemeSetting
Templates []TemplateMapping Templates []TemplateMapping

View File

@ -3,6 +3,8 @@
"FriendlyName": "Cosmo Classic", "FriendlyName": "Cosmo Classic",
"Version": "Coming Soon", "Version": "Coming Soon",
"Creator": "Azareal", "Creator": "Azareal",
"Disabled": true,
"Tag": "WIP",
"Templates": [ "Templates": [
{ {
"Name": "topic", "Name": "topic",

View File

@ -579,6 +579,30 @@ blockquote p
box-shadow:0 1px 2px rgba(0,0,0,.1); box-shadow:0 1px 2px rgba(0,0,0,.1);
} }
.prev_button, .next_button {
position: fixed;
top: 50%;
font-size: 30px;
border-width: 1px;
background-color: #FFFFFF;
border-style: dotted;
border-color: #505050;
padding: 0px;
padding-left: 5px;
padding-right: 5px;
}
.prev_button a, .next_button a {
line-height: 28px;
margin-top: 2px;
margin-bottom: 0px;
display: block;
text-decoration: none;
color: #505050;
}
.prev_button { left: 14px; }
.next_button { right: 14px; }
/* Responsive Layout */ /* Responsive Layout */
/* Anything that isn't a small mobile */ /* Anything that isn't a small mobile */
@media(min-width: 501px) @media(min-width: 501px)

View File

@ -623,6 +623,30 @@ blockquote p
border-radius: 4px; border-radius: 4px;
} }
.prev_button, .next_button {
position: fixed;
top: 50%;
font-size: 30px;
border-width: 1px;
background-color: #FFFFFF;
border-style: dotted;
border-color: #505050;
padding: 0px;
padding-left: 5px;
padding-right: 5px;
}
.prev_button a, .next_button a {
line-height: 28px;
margin-top: 2px;
margin-bottom: 0px;
display: block;
text-decoration: none;
color: #505050;
}
.prev_button { left: 14px; }
.next_button { right: 14px; }
/* Responsive Layout */ /* Responsive Layout */
/* Anything that isn't a small mobile */ /* Anything that isn't a small mobile */
@media(min-width: 501px) @media(min-width: 501px)

View File

@ -418,6 +418,29 @@ button.username
box-shadow:0 1px 2px rgba(0,0,0,.1); box-shadow:0 1px 2px rgba(0,0,0,.1);
} }
.prev_button, .next_button {
position: fixed;
top: 50%;
font-size: 30px;
border-width: 1px;
background-color: #FFFFFF;
border-style: dotted;
border-color: #505050;
padding: 0px;
padding-left: 5px;
padding-right: 5px;
}
.prev_button a, .next_button a {
line-height: 28px;
margin-top: 2px;
margin-bottom: 0px;
display: block;
text-decoration: none;
color: #505050;
}
.prev_button { left: 14px; }
.next_button { right: 14px; }
/* Media Queries from Simple. Probably useless in Conflux */ /* Media Queries from Simple. Probably useless in Conflux */
@media (max-width: 880px) { @media (max-width: 880px) {
li li

View File

@ -315,6 +315,29 @@ button.username
margin-bottom: 8px; margin-bottom: 8px;
background-color: #FEB7CC; background-color: #FEB7CC;
} }
.prev_button, .next_button {
position: fixed;
top: 50%;
font-size: 30px;
border-width: 1px;
background-color: #FFFFFF;
border-style: dotted;
border-color: #505050;
padding: 0px;
padding-left: 5px;
padding-right: 5px;
}
.prev_button a, .next_button a {
line-height: 28px;
margin-top: 2px;
margin-bottom: 0px;
display: block;
text-decoration: none;
color: #505050;
}
.prev_button { left: 14px; }
.next_button { right: 14px; }
@media (max-width: 880px) { @media (max-width: 880px) {
li li

Binary file not shown.

Before

Width:  |  Height:  |  Size: 188 KiB

After

Width:  |  Height:  |  Size: 246 KiB

View File

@ -12,6 +12,8 @@ type Topic struct
CreatedAt string CreatedAt string
ParentID int ParentID int
Status string // Deprecated. Marked for removal. Status string // Deprecated. Marked for removal.
IpAddress string
PostCount int
} }
type TopicUser struct type TopicUser struct
@ -25,6 +27,8 @@ type TopicUser struct
CreatedAt string CreatedAt string
ParentID int ParentID int
Status string // Deprecated. Marked for removal. Status string // Deprecated. Marked for removal.
IpAddress string
PostCount int
CreatedByName string CreatedByName string
Avatar string Avatar string
@ -35,6 +39,4 @@ type TopicUser struct
URLPrefix string URLPrefix string
URLName string URLName string
Level int Level int
IpAddress string
} }