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
install.exe
*.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)
# 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.
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.
* Markdown - An extremely simple plugin for converting Markdown into HTML.

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 noavatar = "https://api.adorable.io/avatars/{width}/{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 server_port = "8080"

View File

@ -67,6 +67,7 @@ CREATE TABLE `topics`(
`sticky` tinyint DEFAULT 0 not null,
`parentID` int DEFAULT 1 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,
primary key(`tid`)
) 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"})
tpage := TopicPage{"Topic Blah",user,noticeList,replyList,topic,false}
tpage2 := TopicPage{"Topic Blah",admin,noticeList,replyList,topic,false}
tpage := TopicPage{"Topic Blah",user,noticeList,replyList,topic,1,1,false}
tpage2 := TopicPage{"Topic Blah",admin,noticeList,replyList,topic,1,1,false}
w := ioutil.Discard
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
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 staff_css_tmpl = template.CSS(staff_css)
var settings map[string]interface{} = make(map[string]interface{})
@ -47,12 +47,12 @@ func compile_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
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)
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_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)
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_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)
}
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(){
//if profiling {
// f, err := os.Create("startup_cpu.prof")
@ -104,7 +128,7 @@ func main(){
init_themes()
var err error
init_database(err)
compile_templates()
init_templates()
db.SetMaxOpenConns(64)
err = init_errors()
@ -136,7 +160,7 @@ func main(){
external_sites["YT"] = "https://www.youtube.com/"
hooks["trow_assign"] = nil
hooks["rrow_assign"] = nil
templates.ParseGlob("pages/*")
init_plugins()
router := NewRouter()

View File

@ -250,6 +250,11 @@ func route_reply_delete_submit(w http.ResponseWriter, r *http.Request) {
InternalError(err,w,r,user)
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) {
@ -1265,7 +1270,7 @@ func route_panel_themes(w http.ResponseWriter, r *http.Request){
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)
if err != nil {
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)
return
}
if theme.Disabled {
LocalError("You must not enable this theme",w,r,user)
return
}
var isDefault bool
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 "log"
import "fmt"
import "strconv"
import "encoding/json"
var db *sql.DB
@ -12,10 +13,13 @@ var get_session_stmt *sql.Stmt
var get_topic_list_stmt *sql.Stmt
var get_topic_user_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 create_topic_stmt *sql.Stmt
var create_report_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 edit_topic_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.")
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 {
log.Fatal(err)
}
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 {
log.Fatal(err)
}
@ -121,6 +131,18 @@ func init_database(err error) {
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.")
update_forum_cache_stmt, err = db.Prepare("UPDATE forums SET lastTopic = ?, lastTopicID = ?, lastReplyer = ?, lastReplyerID = ?, lastTopicTime = NOW() WHERE fid = ?")
if err != nil {

View File

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

View File

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

View File

@ -244,11 +244,13 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
var(
err error
content string
is_super_admin bool
group int
page int
offset int
replyList []Reply
)
page, _ = strconv.Atoi(r.FormValue("page"))
topic := TopicUser{Css: no_css_tmpl}
topic.ID, err = strconv.Atoi(r.URL.Path[len("/topic/"):])
if err != nil {
@ -263,7 +265,7 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
}
// 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 {
NotFound(w,r,user)
return
@ -287,7 +289,7 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
} else {
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.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..
rows, err := get_topic_replies_stmt.Query(topic.ID)
if err != nil {
rows, err := get_topic_replies_offset_stmt.Query(topic.ID, offset)
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)
return
}
replyItem := Reply{Css: no_css_tmpl}
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 {
InternalError(err,w,r,user)
return
@ -323,7 +343,7 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
replyItem.ParentID = topic.ID
replyItem.ContentHtml = template.HTML(parse_message(replyItem.Content))
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.Level = -1
} else {
@ -362,7 +382,7 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
}
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 {
template_topic_handle(tpage,w)
} else {
@ -392,7 +412,6 @@ func route_profile(w http.ResponseWriter, r *http.Request){
replyCss template.CSS
replyLines int
replyTag string
is_super_admin bool
group int
replyList []Reply
@ -439,7 +458,7 @@ func route_profile(w http.ResponseWriter, r *http.Request){
}
// 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 {
InternalError(err,w,r,user)
return
@ -447,14 +466,14 @@ func route_profile(w http.ResponseWriter, r *http.Request){
defer rows.Close()
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 {
InternalError(err,w,r,user)
return
}
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
} else {
replyCss = no_css_tmpl
@ -600,6 +619,11 @@ func route_create_reply(w http.ResponseWriter, r *http.Request) {
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)
if err != nil {
InternalError(err,w,r,user)

View File

@ -50,100 +50,106 @@ var header_3 []byte = []byte(`
<div id="back"><div id="main">`)
var header_4 []byte = []byte(`<div class="alert">`)
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">
<form action='/topic/edit/submit/`)
var topic_1 []byte = []byte(`' method="post">
var topic_7 []byte = []byte(`' method="post">
<div class="rowitem"`)
var topic_2 []byte = []byte(` style="background-color: #FFFFEA;"`)
var topic_3 []byte = []byte(` style="background-color: #eaeaea;"`)
var topic_4 []byte = []byte(`>
var topic_8 []byte = []byte(` style="background-color: #FFFFEA;"`)
var topic_9 []byte = []byte(` style="background-color: #eaeaea;"`)
var topic_10 []byte = []byte(`>
<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_7 []byte = []byte(`
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_13 []byte = []byte(`
<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/`)
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_11 []byte = []byte(`' class="username" style="font-weight: normal;">Unpin</a>`)
var topic_12 []byte = []byte(`<a href='/topic/stick/submit/`)
var topic_13 []byte = []byte(`' class="username" style="font-weight: normal;">Pin</a>`)
var topic_14 []byte = []byte(`
var topic_16 []byte = []byte(`<a href='/topic/unstick/submit/`)
var topic_17 []byte = []byte(`' class="username" style="font-weight: normal;">Unpin</a>`)
var topic_18 []byte = []byte(`<a href='/topic/stick/submit/`)
var topic_19 []byte = []byte(`' class="username" style="font-weight: normal;">Pin</a>`)
var topic_20 []byte = []byte(`
<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;'>
<option>open</option>
<option>closed</option>
</select>
<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/`)
var topic_17 []byte = []byte(`?session=`)
var topic_18 []byte = []byte(`&type=topic" class="username report_item" style="font-weight: normal;">Report</a>
var topic_23 []byte = []byte(`?session=`)
var topic_24 []byte = []byte(`&type=topic" class="username report_item" style="font-weight: normal;">Report</a>
</div>
</form>
</div>
<div class="rowblock post_container">
<div class="rowitem passive editable_parent post_item" style="border-bottom: none;`)
var topic_19 []byte = []byte(`background-image: url(`)
var topic_20 []byte = []byte(`), url(/static/white-dot.jpg);background-position: 0px `)
var topic_21 []byte = []byte(`-1`)
var topic_22 []byte = []byte(`0px;background-repeat: no-repeat, repeat-y;background-size: 128px;padding-left: 136px;`)
var topic_23 []byte = []byte(`">
var topic_25 []byte = []byte(`background-image: url(`)
var topic_26 []byte = []byte(`), url(/static/white-dot.jpg);background-position: 0px `)
var topic_27 []byte = []byte(`-1`)
var topic_28 []byte = []byte(`0px;background-repeat: no-repeat, repeat-y;background-size: 128px;padding-left: 136px;`)
var topic_29 []byte = []byte(`">
<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">`)
var topic_25 []byte = []byte(`</textarea><br /><br />
var topic_31 []byte = []byte(`</textarea><br /><br />
<a href="/user/`)
var topic_26 []byte = []byte(`" class="username real_username">`)
var topic_27 []byte = []byte(`</a>
var topic_32 []byte = []byte(`" class="username real_username">`)
var topic_33 []byte = []byte(`</a>
<a class="username hide_on_micro" `)
var topic_28 []byte = []byte(`style="float: right;">`)
var topic_29 []byte = []byte(`style="color: #505050;float: right;">Level `)
var topic_30 []byte = []byte(`</a>
var topic_34 []byte = []byte(`style="float: right;">`)
var topic_35 []byte = []byte(`style="color: #505050;float: right;">Level `)
var topic_36 []byte = []byte(`</a>
</div>
</div><br />
<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="`)
var topic_32 []byte = []byte(`background-image: url(`)
var topic_33 []byte = []byte(`), url(/static/white-dot.jpg);background-position: 0px `)
var topic_34 []byte = []byte(`-1`)
var topic_35 []byte = []byte(`0px;background-repeat: no-repeat, repeat-y;background-size: 128px;padding-left: 136px;`)
var topic_36 []byte = []byte(`">
var topic_38 []byte = []byte(`background-image: url(`)
var topic_39 []byte = []byte(`), url(/static/white-dot.jpg);background-position: 0px `)
var topic_40 []byte = []byte(`-1`)
var topic_41 []byte = []byte(`0px;background-repeat: no-repeat, repeat-y;background-size: 128px;padding-left: 136px;`)
var topic_42 []byte = []byte(`">
<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/`)
var topic_38 []byte = []byte(`" class="username real_username">`)
var topic_39 []byte = []byte(`</a>
var topic_44 []byte = []byte(`" class="username real_username">`)
var topic_45 []byte = []byte(`</a>
`)
var topic_40 []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_42 []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_44 []byte = []byte(`
var topic_46 []byte = []byte(`<a href="/reply/edit/submit/`)
var topic_47 []byte = []byte(`" class="mod_button"><button class="username edit_item">Edit</button></a> `)
var topic_48 []byte = []byte(`<a href="/reply/delete/submit/`)
var topic_49 []byte = []byte(`" class="mod_button"><button class="username delete_item">Delete</button></a> `)
var topic_50 []byte = []byte(`
<a href="/report/submit/`)
var topic_45 []byte = []byte(`?session=`)
var topic_46 []byte = []byte(`&type=reply" class="mod_button"><button class="username report_item">Report</button></a>
var topic_51 []byte = []byte(`?session=`)
var topic_52 []byte = []byte(`&type=reply" class="mod_button"><button class="username report_item">Report</button></a>
<a class="username hide_on_micro" `)
var topic_47 []byte = []byte(`style="float: right;">`)
var topic_48 []byte = []byte(`style="color: #505050;float: right;">Level `)
var topic_49 []byte = []byte(`</a>
var topic_53 []byte = []byte(`style="float: right;">`)
var topic_54 []byte = []byte(`style="color: #505050;float: right;">Level `)
var topic_55 []byte = []byte(`</a>
</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">
<form action="/reply/create/" method="post">
<input name="tid" value='`)
var topic_52 []byte = []byte(`' type="hidden" />
var topic_58 []byte = []byte(`' type="hidden" />
<div class="formrow">
<div class="formitem"><textarea name="reply-content" placeholder="Insert reply here"></textarea></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>
</body>
</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">
<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`)
var topic_alt_2 []byte = []byte(` topic_sticky_head`)
var topic_alt_3 []byte = []byte(` topic_closed_head`)
var topic_alt_4 []byte = []byte(`">
var topic_alt_8 []byte = []byte(` topic_sticky_head`)
var topic_alt_9 []byte = []byte(` topic_closed_head`)
var topic_alt_10 []byte = []byte(`">
<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_7 []byte = []byte(`
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_13 []byte = []byte(`
<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/`)
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_11 []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_13 []byte = []byte(`' class="username topic_button" style="font-weight: normal;">Pin</a>`)
var topic_alt_14 []byte = []byte(`
var topic_alt_16 []byte = []byte(`<a href='/topic/unstick/submit/`)
var topic_alt_17 []byte = []byte(`' class="username topic_button" style="font-weight: normal;">Unpin</a>`)
var topic_alt_18 []byte = []byte(`<a href='/topic/stick/submit/`)
var topic_alt_19 []byte = []byte(`' class="username topic_button" style="font-weight: normal;">Pin</a>`)
var topic_alt_20 []byte = []byte(`
<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;'>
<option>open</option>
<option>closed</option>
</select>
<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/`)
var topic_alt_17 []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_23 []byte = []byte(`?session=`)
var topic_alt_24 []byte = []byte(`&type=topic" class="username report_item topic_button" style="font-weight: normal;">Report</a>
</div>
</form>
</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="userinfo">
<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/`)
var topic_alt_20 []byte = []byte(`" class="the_name">`)
var topic_alt_21 []byte = []byte(`</a>
var topic_alt_26 []byte = []byte(`" class="the_name">`)
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_23 []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_25 []byte = []byte(`</div><div class="tag_post"></div></div>`)
var topic_alt_26 []byte = []byte(`
var topic_alt_28 []byte = []byte(`<div class="tag_block"><div class="tag_pre"></div><div class="post_tag">`)
var topic_alt_29 []byte = []byte(`</div><div class="tag_post"></div></div>`)
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_31 []byte = []byte(`</div><div class="tag_post"></div></div>`)
var topic_alt_32 []byte = []byte(`
</div>
<div class="content_container">
<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">`)
var topic_alt_28 []byte = []byte(`</textarea>
var topic_alt_34 []byte = []byte(`</textarea>
<div class="button_container">
`)
var topic_alt_29 []byte = []byte(`<a href="#" class="action_button action_button_right ip_item">`)
var topic_alt_30 []byte = []byte(`</a>`)
var topic_alt_31 []byte = []byte(`
var topic_alt_35 []byte = []byte(`<a href="#" class="action_button action_button_right ip_item">`)
var topic_alt_36 []byte = []byte(`</a>`)
var topic_alt_37 []byte = []byte(`
</div>
</div><div style="clear:both;"></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="userinfo">
<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/`)
var topic_alt_34 []byte = []byte(`" class="the_name">`)
var topic_alt_35 []byte = []byte(`</a>
var topic_alt_40 []byte = []byte(`" class="the_name">`)
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_37 []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_39 []byte = []byte(`</div><div class="tag_post"></div></div>`)
var topic_alt_40 []byte = []byte(`
var topic_alt_42 []byte = []byte(`<div class="tag_block"><div class="tag_pre"></div><div class="post_tag">`)
var topic_alt_43 []byte = []byte(`</div><div class="tag_post"></div></div>`)
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_45 []byte = []byte(`</div><div class="tag_post"></div></div>`)
var topic_alt_46 []byte = []byte(`
</div>
<div class="content_container">
<div class="editable_block user_content">`)
var topic_alt_41 []byte = []byte(`</div>
var topic_alt_47 []byte = []byte(`</div>
<div class="button_container">
`)
var topic_alt_42 []byte = []byte(`<a href="/reply/edit/submit/`)
var topic_alt_43 []byte = []byte(`" class="action_button edit_item">Edit</a>`)
var topic_alt_44 []byte = []byte(`<a href="/reply/delete/submit/`)
var topic_alt_45 []byte = []byte(`" class="action_button delete_item">Delete</a>`)
var topic_alt_46 []byte = []byte(`
var topic_alt_48 []byte = []byte(`<a href="/reply/edit/submit/`)
var topic_alt_49 []byte = []byte(`" class="action_button edit_item">Edit</a>`)
var topic_alt_50 []byte = []byte(`<a href="/reply/delete/submit/`)
var topic_alt_51 []byte = []byte(`" class="action_button delete_item">Delete</a>`)
var topic_alt_52 []byte = []byte(`
<a href="/report/submit/`)
var topic_alt_47 []byte = []byte(`?session=`)
var topic_alt_48 []byte = []byte(`&type=reply" class="action_button report_item">Report</a>
var topic_alt_53 []byte = []byte(`?session=`)
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_50 []byte = []byte(`</a>`)
var topic_alt_51 []byte = []byte(`
var topic_alt_55 []byte = []byte(`<a href="#" class="action_button action_button_right ip_item">`)
var topic_alt_56 []byte = []byte(`</a>`)
var topic_alt_57 []byte = []byte(`
</div>
</div>
<div style="clear:both;"></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;">
<form action="/reply/create/" method="post">
<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="formitem"><textarea name="reply-content" placeholder="Insert reply here"></textarea></div>
</div>

View File

@ -41,123 +41,137 @@ w.Write([]byte(item))
w.Write(header_5)
}
}
if tmpl_topic_vars.Page > 1 {
w.Write(topic_0)
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
w.Write(topic_1)
if tmpl_topic_vars.Topic.Sticky {
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Page - 1)))
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 {
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(topic_5)
w.Write(topic_11)
if tmpl_topic_vars.Topic.Is_Closed {
w.Write(topic_6)
w.Write(topic_12)
}
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([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
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)
}
if tmpl_topic_vars.Topic.Sticky {
w.Write(topic_16)
w.Write([]byte(strconv.Itoa(tmpl_topic_vars.Topic.ID)))
w.Write(topic_17)
w.Write([]byte(tmpl_topic_vars.CurrentUser.Session))
} else {
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([]byte(tmpl_topic_vars.Topic.Avatar))
}
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_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(topic_23)
w.Write(topic_29)
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(topic_25)
w.Write(topic_31)
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(topic_27)
w.Write(topic_33)
if tmpl_topic_vars.Topic.Tag != "" {
w.Write(topic_28)
w.Write(topic_34)
w.Write([]byte(tmpl_topic_vars.Topic.Tag))
} else {
w.Write(topic_29)
w.Write(topic_35)
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 {
for _, item := range tmpl_topic_vars.ItemList {
w.Write(topic_31)
w.Write(topic_37)
if item.Avatar != "" {
w.Write(topic_32)
w.Write(topic_38)
w.Write([]byte(item.Avatar))
w.Write(topic_33)
w.Write(topic_39)
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(topic_36)
w.Write(topic_42)
w.Write([]byte(string(item.ContentHtml)))
w.Write(topic_37)
w.Write(topic_43)
w.Write([]byte(strconv.Itoa(item.CreatedBy)))
w.Write(topic_38)
w.Write(topic_44)
w.Write([]byte(item.CreatedByName))
w.Write(topic_39)
w.Write(topic_45)
if tmpl_topic_vars.CurrentUser.Perms.EditReply {
w.Write(topic_40)
w.Write(topic_46)
w.Write([]byte(strconv.Itoa(item.ID)))
w.Write(topic_41)
w.Write(topic_47)
}
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([]byte(strconv.Itoa(item.Level)))
}
w.Write([]byte(strconv.Itoa(item.ID)))
w.Write(topic_49)
}
}
w.Write(topic_50)
if tmpl_topic_vars.CurrentUser.Perms.CreateReply {
w.Write([]byte(strconv.Itoa(item.ID)))
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)
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)
}

View File

@ -41,121 +41,135 @@ w.Write([]byte(item))
w.Write(header_5)
}
}
if tmpl_topic_alt_vars.Page > 1 {
w.Write(topic_alt_0)
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
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)
}
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 {
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(topic_alt_5)
w.Write(topic_alt_11)
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 {
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([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
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)
}
if tmpl_topic_alt_vars.Topic.Sticky {
w.Write(topic_alt_16)
w.Write([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.ID)))
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 {
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([]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([]byte(strconv.Itoa(tmpl_topic_alt_vars.Topic.CreatedBy)))
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([]byte(string(tmpl_topic_alt_vars.Topic.Content.(template.HTML))))
if tmpl_topic_alt_vars.Topic.Tag != "" {
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([]byte(tmpl_topic_alt_vars.Topic.IpAddress))
} else {
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_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 {
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([]byte(strconv.Itoa(item.Level)))
w.Write([]byte(item.Avatar))
w.Write(topic_alt_39)
}
w.Write([]byte(strconv.Itoa(item.CreatedBy)))
w.Write(topic_alt_40)
w.Write([]byte(string(item.ContentHtml)))
w.Write([]byte(item.CreatedByName))
w.Write(topic_alt_41)
if tmpl_topic_alt_vars.CurrentUser.Perms.EditReply {
if item.Tag != "" {
w.Write(topic_alt_42)
w.Write([]byte(strconv.Itoa(item.ID)))
w.Write([]byte(item.Tag))
w.Write(topic_alt_43)
}
if tmpl_topic_alt_vars.CurrentUser.Perms.DeleteReply {
} else {
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_46)
w.Write([]byte(strconv.Itoa(item.ID)))
w.Write([]byte(string(item.ContentHtml)))
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)
if tmpl_topic_alt_vars.CurrentUser.Perms.ViewIPs {
w.Write([]byte(strconv.Itoa(item.ID)))
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_52)
if tmpl_topic_alt_vars.CurrentUser.Perms.CreateReply {
w.Write([]byte(strconv.Itoa(item.ID)))
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)
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)
}

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. */
package main
import "strconv"
import "io"
import "strconv"
func init() {
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["lt"] = 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["io"] = "io"
c.importMap["strconv"] = "strconv"
@ -360,6 +364,13 @@ func (c *CTemplateSet) compile_subswitch(varholder string, holdreflect reflect.V
return c.compile_varsub(varname, reflectVal)
case *parse.StringNode:
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:
fmt.Println("Unknown 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.Args)
}
return c.compile_identswitch(varholder, holdreflect, template_name, node)
return c.compile_identswitch_n(varholder, holdreflect, template_name, node)
case *parse.DotNode:
return varholder
case *parse.VariableNode:
@ -419,7 +430,7 @@ func (c *CTemplateSet) compile_varswitch(varholder string, holdreflect reflect.V
fmt.Println("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 {
fmt.Println("Out: ")
@ -436,7 +447,12 @@ func (c *CTemplateSet) compile_varswitch(varholder string, holdreflect reflect.V
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:
for pos, id := range node.Args {
if debug {
@ -452,21 +468,125 @@ func (c *CTemplateSet) compile_identswitch(varholder string, holdreflect reflect
out += " && "
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)
if debug {
fmt.Println(node.Args[pos + 1])
fmt.Println(node.Args[pos + 2])
}
break ArgLoop
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)
if debug {
fmt.Println(node.Args[pos + 1])
fmt.Println(node.Args[pos + 2])
}
break ArgLoop
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)
if debug {
fmt.Println(node.Args[pos + 1])
fmt.Println(node.Args[pos + 2])
}
break ArgLoop
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)
if debug {
fmt.Println(node.Args[pos + 1])
fmt.Println(node.Args[pos + 2])
}
break ArgLoop
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)
if debug {
fmt.Println(node.Args[pos + 1])
fmt.Println(node.Args[pos + 2])
}
break ArgLoop
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)
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
default:
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)
}
}
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) {
@ -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 {
if strings.HasPrefix(out, varItem.Destination) {
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]
if ok {
c.stats[out]++
@ -605,6 +743,9 @@ func (c *CTemplateSet) compile_boolsub(varname string, varholder string, templat
case reflect.Int64:
out += " > 0"
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")
}
return out
@ -642,6 +783,8 @@ func (c *CTemplateSet) compile_varsub(varname string, val reflect.Value) string
case reflect.Int64:
return "w.Write([]byte(strconv.FormatInt(" + varname + ", 10)))"
default:
fmt.Println("Unknown Variable Name: ")
fmt.Println(varname)
fmt.Println("Unknown Kind: ")
fmt.Println(val.Kind())
fmt.Println("Unknown Type: ")

View File

@ -13,6 +13,7 @@
</span>
<span style="float: right;">
{{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}}
</span>
</div>

View File

@ -1,7 +1,9 @@
{{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">
<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>
{{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}}
@ -21,7 +23,7 @@
</form>
</div>
<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>
<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>
@ -29,7 +31,7 @@
</div>
</div><br />
<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 />
<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}}

View File

@ -1,4 +1,6 @@
{{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">
<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}}">

View File

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

View File

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

View File

@ -579,6 +579,30 @@ blockquote p
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 */
/* Anything that isn't a small mobile */
@media(min-width: 501px)

View File

@ -623,6 +623,30 @@ blockquote p
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 */
/* Anything that isn't a small mobile */
@media(min-width: 501px)

View File

@ -418,6 +418,29 @@ button.username
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 (max-width: 880px) {
li

View File

@ -315,6 +315,29 @@ button.username
margin-bottom: 8px;
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) {
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
ParentID int
Status string // Deprecated. Marked for removal.
IpAddress string
PostCount int
}
type TopicUser struct
@ -25,6 +27,8 @@ type TopicUser struct
CreatedAt string
ParentID int
Status string // Deprecated. Marked for removal.
IpAddress string
PostCount int
CreatedByName string
Avatar string
@ -35,6 +39,4 @@ type TopicUser struct
URLPrefix string
URLName string
Level int
IpAddress string
}