Added an alternate topic layout. This might serve as the foundation of a second theme. You'll be able to switch between the two with ease once the theme system is in.

The profile route is now compiled again. A custom struct is now used for it instead of the generic Page struct.
Added the group list to the Control Panel.
Tweaked the navbar CSS.
Non-mods can no longer post in locked topics.
Locked topics now have a gray background on the topic view header, the forum view, and the topiclist,
The reply content box no longer shows up on topics which don't have any replies.
This commit is contained in:
Azareal 2016-12-26 04:44:07 +00:00
parent 9f2efce516
commit bcaa646f68
24 changed files with 559 additions and 43 deletions

View File

@ -22,6 +22,8 @@ A template engine which compiles templates down into machine code. Over ten time
A plugin system. Under development.
A responsive design. Looks good on mobile phones, tablets, laptops, desktops and more!
# Dependencies
@ -83,6 +85,17 @@ You might have to go build, run the executable, and then go build and then run t
Several important features for saving memory in the templates system may have to be implemented before the new compiled template system is rolled out to every route. These features are coming fairly soon, but not before the other more high priority items.
# How do I install plugins?
For the default plugins like Markdown and Helloworld, you can find them in the Plugin Manager of your Control Panel. For ones which aren't included by default, you will need to drag them from your /extend/ directory and into the / directory (the root directory of your Gosora installation, where the executable and most of the main Go files are).
You will then need to recompile Gosora in order to link the plugin code with Gosora's code. For plugins not written in Gosora (e.g. JavaScript), you do not need to move them from the /extend/ directory, they will automatically show up in your Control Panel ready to be installed.
Experimental plugins aka the ones in the /experimental/ folder (e.g. plugin_sendmail) are similar but different. You will have to move native plugins (ones written in Go) to the root directory of your installation and will have to move experimental plugins written in other languages into the /extend/ directory.
We're looking for ways to clean-up the plugin system so that all of them (except the experimental ones) are housed in /extend/, however we've encountered some problems with Go's packaging system. We plan to fix this issue in the future.
# 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!
@ -96,9 +109,7 @@ Add an alert system.
Add per-forum permissions to finish up the foundations of the permissions system.
Add a *better* plugin system.
Tweak the CSS to make it responsive.
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.
Implement a faster router.
@ -107,3 +118,5 @@ Add a friend system.
Add more administration features.
Add more features for improving user engagement.
Add a widget system.

View File

@ -0,0 +1,3 @@
/* Copyright Azareal 2016 - 2017 */
package main

View File

@ -0,0 +1,47 @@
/* Copyright Azareal 2016 - 2017 */
package main
import "github.com/robertkrimen/otto"
var vm *Otto
var js_plugins map[string]*otto.Script = make(map[string]*otto.Script)
var js_vars map[string]*otto.Object = make(map[string]*otto.Object)
func init()
{
var err error
vm = otto.New()
js_vars["current_page"], err = vm.Object(`current_page = {}`)
if err != nil {
log.Fatal(err)
}
}
func js_add_plugin(plugin string) error
{
script, err := otto.Compile("./extend/" + plugin + ".js")
if err != nil {
return err
}
vm.Run(script)
return nil
}
func js_add_hook(hook string, plugin string)
{
hooks[hook] = func(data interface{}) interface{} {
switch d := data.(type) {
case Page:
current_page := js_vars["current_page"]
current_page.Set("Title", d.Title)
case TopicPage:
case ProfilePage:
case Reply:
default:
log.Print("Not a valid JS datatype")
}
}
}

View File

@ -0,0 +1,3 @@
/* Copyright Azareal 2016 - 2017 */
package main

View File

@ -0,0 +1,14 @@
<div class="rowitem passive deletable_block editable_parent post_item" style="background-color: #eaeaea;padding-top: 3px;padding-left: 4px;clear: both;border-bottom: solid 1px #ccc;padding-right: 3px;padding-bottom: 6px;">
<div class="userinfo" style="background: white;width: 132px;padding: 2px;margin-top: 2px;float: left;">
<div class="avatar_item" style="background-image: url(/uploads/avatar_1.jpg), url(/static/white-dot.jpg);background-position: 0px -10px;background-repeat: no-repeat, repeat-y;background-size: 128px;width: 128px;height: 100%;min-height: 128px;border-style: solid;border-color: #eaeaea;border-width: 1px;">&nbsp;</div>
<div class="the_name" style="margin-top: 3px;text-align: center;color: #505050;">Azareal</div>
</div>
<div class="content_container" style="background: white;margin-left: 137px;min-height: 128px;margin-bottom: 0;margin-right: 3px;">
<div class="editable_block user_content" style="padding: 5px;margin-top: 3px;margin-bottom: 0;background: white;min-height: 133px;padding-bottom: 0;width: 100%;">boo</div>
<div class="button_container" style="border-top: solid 1px #eaeaea;border-spacing: 0px;border-collapse: collapse;padding: 0;margin: 0;display: block;">
<a style="border-right: solid 1px #eaeaea;color: #505050;font-size: 13px;padding-left: 5px;padding-right: 5px;">Edit</a>
<a style="border-right: solid 1px #eaeaea;color: #505050;font-size: 13px;padding-left: 0;padding-right: 5px;">Delete</a>
<a style="border: none;border-right: solid 1px #eaeaea;padding-right: 6px;color: #505050;font-size: 13px;">Report</a>
</div>
</div>
</div>

Binary file not shown.

BIN
images/layout2-test.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

BIN
images/layout2-test_2.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 287 KiB

13
main.go
View File

@ -33,10 +33,11 @@ var forums map[int]Forum = make(map[int]Forum)
var static_files map[string]SFile = make(map[string]SFile)
var ctemplates []string
var template_topic_handle func(TopicPage,io.Writer) = nil
var template_topic_alt_handle func(TopicPage,io.Writer) = nil
var template_topics_handle func(Page,io.Writer) = nil
var template_forum_handle func(Page,io.Writer) = nil
var template_forums_handle func(Page,io.Writer) = nil
var template_profile_handle func(Page,io.Writer) = nil
var template_profile_handle func(ProfilePage,io.Writer) = nil
func compile_templates() {
var c CTemplateSet
@ -53,11 +54,11 @@ func compile_templates() {
var varList map[string]VarItem = make(map[string]VarItem)
tpage := TopicPage{"Title","name",user,noticeList,replyList,topic,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)
varList = make(map[string]VarItem)
varList["extra_data"] = VarItem{"extra_data","tmpl_profile_vars.Something.(User)","User"}
//pi := Page{"Title","name",user,noticeList,replyList,user}
//profile_tmpl := c.compile_template("profile.html","templates/","Page", pi, varList)
ppage := ProfilePage{"Title",user,noticeList,replyList,user,false}
profile_tmpl := c.compile_template("profile.html","templates/","ProfilePage", ppage, varList)
var forumList []interface{}
for _, forum := range forums {
@ -79,7 +80,8 @@ func compile_templates() {
log.Print("Writing the templates")
write_template("topic", topic_id_tmpl)
//write_template("profile", profile_tmpl)
write_template("topic_alt", topic_id_alt_tmpl)
write_template("profile", profile_tmpl)
write_template("forums", forums_tmpl)
write_template("topics", topics_tmpl)
write_template("forum", forum_tmpl)
@ -209,6 +211,7 @@ func main(){
http.HandleFunc("/panel/users/", route_panel_users)
http.HandleFunc("/panel/users/edit/", route_panel_users_edit)
http.HandleFunc("/panel/users/edit/submit/", route_panel_users_edit_submit)
http.HandleFunc("/panel/groups/", route_panel_groups)
http.HandleFunc("/", default_route)

View File

@ -1224,3 +1224,22 @@ func route_panel_users_edit_submit(w http.ResponseWriter, r *http.Request){
http.Redirect(w,r,"/panel/users/edit/" + strconv.Itoa(targetUser.ID),http.StatusSeeOther)
}
func route_panel_groups(w http.ResponseWriter, r *http.Request){
user, noticeList, ok := SessionCheck(w,r)
if !ok {
return
}
if !user.Is_Super_Mod {
NoPermissions(w,r,user)
return
}
var groupList []interface{}
for _, group := range groups {
groupList = append(groupList, group)
}
pi := Page{"Group Manager","panel-groups",user,noticeList,groupList,0}
templates.ExecuteTemplate(w,"panel-groups.html", pi)
}

View File

@ -5,7 +5,7 @@ import "strings"
type Page struct
{
Title string
Name string
Name string // What's the point of this field? If we're not going to use it, remove it.
CurrentUser User
NoticeList map[int]string
ItemList []interface{}
@ -23,6 +23,16 @@ type TopicPage struct
ExtData interface{}
}
type ProfilePage struct
{
Title string
CurrentUser User
NoticeList map[int]string
ItemList []Reply
ProfileOwner User
ExtData interface{}
}
type PageSimple struct
{
Title string

View File

@ -47,15 +47,13 @@ li
font-weight: bold;
text-transform: uppercase;
}
li:hover { background: rgb(250,250,250); }
li a
{
text-decoration: none;
color: #515151;
}
li a:hover
{
color: #7a7a7a;
}
/*li a:hover { color: #7a7a7a; }*/
.menu_left
{
float: left;
@ -131,7 +129,7 @@ li a:hover
font-weight: normal;
text-transform: none;
}
.rowitem:not(:last-child)/*:not(:only-child)*/
.rowitem:not(:last-child)
{
border-bottom: 1px dotted #ccc;
}

View File

@ -316,6 +316,11 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
if topic.Is_Closed {
topic.Status = "closed"
// We don't want users posting in locked topics...
if !user.Is_Mod {
user.Perms.CreateReply = false
}
} else {
topic.Status = "open"
}
@ -403,8 +408,8 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
}
tpage := TopicPage{topic.Title,"topic",user,noticeList,replyList,topic,0}
if template_topic_handle != nil {
template_topic_handle(tpage,w)
if template_topic_handle != nil { //if template_topic_alt_handle != nil {
template_topic_handle(tpage,w) //template_topic_alt_handle(tpage,w)
} else {
err = templates.ExecuteTemplate(w,"topic.html", tpage)
if err != nil {
@ -435,7 +440,7 @@ func route_profile(w http.ResponseWriter, r *http.Request){
is_super_admin bool
group int
replyList []interface{}
replyList []Reply
)
puser := User{ID: 0,}
@ -526,11 +531,11 @@ func route_profile(w http.ResponseWriter, r *http.Request){
return
}
pi := Page{puser.Name + "'s Profile","profile",user,noticeList,replyList,puser}
ppage := ProfilePage{puser.Name + "'s Profile",user,noticeList,replyList,puser,false}
if template_profile_handle != nil {
template_profile_handle(pi,w)
template_profile_handle(ppage,w)
} else {
err = templates.ExecuteTemplate(w,"profile.html", pi)
err = templates.ExecuteTemplate(w,"profile.html", ppage)
if err != nil {
InternalError(err, w, r, user)
}

View File

@ -73,6 +73,10 @@ w.Write([]byte(`background-image: url(` + item.(TopicUser).Avatar + `);backgroun
}
if item.(TopicUser).Sticky {
w.Write([]byte(`background-color: #FFFFCC;`))
} else {
if item.(TopicUser).Is_Closed {
w.Write([]byte(`background-color: #eaeaea;`))
}
}
w.Write([]byte(`">
<a href="/topic/` + strconv.Itoa(item.(TopicUser).ID) + `">` + item.(TopicUser).Title + `</a> `))

148
template_profile.go Normal file
View File

@ -0,0 +1,148 @@
package main
import "strconv"
import "io"
func init() {
template_profile_handle = template_profile
}
func template_profile(tmpl_profile_vars ProfilePage, w io.Writer) {
w.Write([]byte(`<!doctype html>
<html lang="en">
<head>
<title>` + tmpl_profile_vars.Title + `</title>
<link href="/static/main.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="/static/jquery-1.12.3.min.js"></script>
<script type="text/javascript">
var session = "` + tmpl_profile_vars.CurrentUser.Session + `";
</script>
<script type="text/javascript" src="/static/global.js"></script>
<meta name="viewport" content="width=device-width,initial-scale = 1.0, maximum-scale=1.0,user-scalable=no" />
</head>
<body>
<div class="container">
<div class="nav">
<div class="move_left">
<div class="move_right">
<ul>
<li class="menu_left menu_overview"><a href="/">Overview</a></li>
<li class="menu_left menu_forums"><a href="/forums/">Forums</a></li>
<li class="menu_left menu_topics"><a href="/">Topics</a></li>
<li class="menu_left menu_create_topic"><a href="/topics/create/">Create Topic</a></li>
`))
if tmpl_profile_vars.CurrentUser.Loggedin {
w.Write([]byte(`
<li class="menu_left menu_account"><a href="/user/edit/critical/">Account</a></li>
<li class="menu_left menu_profile"><a href="/user/` + strconv.Itoa(tmpl_profile_vars.CurrentUser.ID) + `">Profile</a></li>
`))
if tmpl_profile_vars.CurrentUser.Is_Super_Mod {
w.Write([]byte(`<li class="menu_left menu_account"><a href="/panel/">Panel</a></li>`))
}
w.Write([]byte(`
<li class="menu_left menu_logout"><a href="/accounts/logout?session=` + tmpl_profile_vars.CurrentUser.Session + `">Logout</a></li>
`))
} else {
w.Write([]byte(`
<li class="menu_left menu_register"><a href="/accounts/create/">Register</a></li>
<li class="menu_left menu_login"><a href="/accounts/login/">Login</a></li>
`))
}
w.Write([]byte(`
</ul>
</div>
</div>
<div style="clear: both;"></div>
</div>
`))
if len(tmpl_profile_vars.NoticeList) != 0 {
for _, item := range tmpl_profile_vars.NoticeList {
w.Write([]byte(`<div class="alert">` + item + `</div>`))
}
}
w.Write([]byte(`
<div class="colblock_left" style="max-width: 220px;">
<div class="rowitem" style="padding: 0;"><img src="` + tmpl_profile_vars.ProfileOwner.Avatar + `" style="max-width: 100%;margin: 0;"/></div>
<div class="rowitem" style="text-transform: capitalize;">
<span style="font-size: 18px;">` + tmpl_profile_vars.ProfileOwner.Name + `</span>`))
if tmpl_profile_vars.ProfileOwner.Tag != "" {
w.Write([]byte(`<span class="username" style="float: right;font-weight: normal;">` + tmpl_profile_vars.ProfileOwner.Tag + `</span>`))
}
w.Write([]byte(`
</div>
<div class="rowitem passive">
<a class="username">Add Friend</a>
`))
if tmpl_profile_vars.CurrentUser.Is_Super_Mod && !tmpl_profile_vars.ProfileOwner.Is_Super_Mod {
w.Write([]byte(`
`))
if tmpl_profile_vars.ProfileOwner.Is_Banned {
w.Write([]byte(`<a href="/users/unban/` + strconv.Itoa(tmpl_profile_vars.ProfileOwner.ID) + `?session=` + tmpl_profile_vars.CurrentUser.Session + `" class="username">Unban</a>`))
} else {
w.Write([]byte(`<a href="/users/ban/` + strconv.Itoa(tmpl_profile_vars.ProfileOwner.ID) + `?session=` + tmpl_profile_vars.CurrentUser.Session + `" class="username">Ban</a>`))
}
w.Write([]byte(`
`))
}
w.Write([]byte(`
<a href="/report/submit/` + strconv.Itoa(tmpl_profile_vars.ProfileOwner.ID) + `?session=` + tmpl_profile_vars.CurrentUser.Session + `&type=user" class="username report_item">Report</a>
</div>
</div>
<div class="colblock_right">
<div class="rowitem"><a>Comments</a></div>
</div>
<div class="colblock_right" style="overflow: hidden;">
`))
if len(tmpl_profile_vars.ItemList) != 0 {
for _, item := range tmpl_profile_vars.ItemList {
w.Write([]byte(`
<div class="rowitem passive deletable_block editable_parent" style="`))
if item.Avatar != "" {
w.Write([]byte(`background-image: url(` + item.Avatar + `), url(/static/white-dot.jpg);background-position: 0px `))
if item.ContentLines <= 5 {
w.Write([]byte(`-1`))
}
w.Write([]byte(`0px;background-repeat: no-repeat, repeat-y;background-size: 128px;padding-left: 136px;` + string(item.Css)))
}
w.Write([]byte(`">
<span class="editable_block user_content">` + string(item.ContentHtml) + `</span>
<br /><br />
<a href="/user/` + strconv.Itoa(item.CreatedBy) + `" class="username">` + item.CreatedByName + `</a>
`))
if tmpl_profile_vars.CurrentUser.Is_Mod {
w.Write([]byte(`<a href="/profile/reply/edit/submit/` + strconv.Itoa(item.ID) + `"><button class="username edit_item">Edit</button></a>
<a href="/profile/reply/delete/submit/` + strconv.Itoa(item.ID) + `"><button class="username delete_item">Delete</button></a>`))
}
w.Write([]byte(`
<a href="/report/submit/` + strconv.Itoa(item.ID) + `?session=` + tmpl_profile_vars.CurrentUser.Session + `&type=user-reply"><button class="username report_item">Report</button></a>
`))
if item.Tag != "" {
w.Write([]byte(`<a class="username hide_on_mobile" style="float: right;">` + item.Tag + `</a>`))
}
w.Write([]byte(`
</div>`))
}
}
w.Write([]byte(`
</div>
`))
if !tmpl_profile_vars.CurrentUser.Is_Banned {
w.Write([]byte(`
<div class="colblock_right">
<form action="/profile/reply/create/" method="post">
<input name="uid" value='` + strconv.Itoa(tmpl_profile_vars.ProfileOwner.ID) + `' type="hidden" />
<div class="formrow">
<div class="formitem"><textarea name="reply-content" placeholder="Insert reply here"></textarea></div>
</div>
<div class="formrow">
<div class="formitem"><button name="reply-button" class="formbutton">Create Reply</button></div>
</div>
</form>
</div>
`))
}
w.Write([]byte(`
<!--<link rel="stylesheet" href="https://use.fontawesome.com/8670aa03ca.css">-->
</div>
</body>
</html>`))
}

View File

@ -66,6 +66,10 @@ w.Write([]byte(`
<div class="rowitem"`))
if tmpl_topic_vars.Topic.Sticky {
w.Write([]byte(` style="background-color: #FFFFEA;"`))
} else {
if tmpl_topic_vars.Topic.Is_Closed {
w.Write([]byte(` style="background-color: #eaeaea;"`))
}
}
w.Write([]byte(`>
<a class='topic_name hide_on_edit'>` + tmpl_topic_vars.Topic.Title + `</a>
@ -123,8 +127,7 @@ w.Write([]byte(`<a href="` + tmpl_topic_vars.Topic.URL + `" class="username" sty
w.Write([]byte(`
</div>
</div><br />
<div class="rowblock post_container" style="overflow: hidden;">
`))
<div class="rowblock post_container" style="overflow: hidden;">`))
if len(tmpl_topic_vars.ItemList) != 0 {
for _, item := range tmpl_topic_vars.ItemList {
w.Write([]byte(`
@ -137,8 +140,7 @@ w.Write([]byte(`-1`))
w.Write([]byte(`0px;background-repeat: no-repeat, repeat-y;background-size: 128px;padding-left: 136px;` + string(item.Css)))
}
w.Write([]byte(`">
<p class="editable_block user_content" style="margin: 0;padding: 0;">` + string(item.ContentHtml) + `</p>
<br /><br />
<p class="editable_block user_content" style="margin: 0;padding: 0;">` + string(item.ContentHtml) + `</p><br /><br />
<a href="/user/` + strconv.Itoa(item.CreatedBy) + `" class="username real_username">` + item.CreatedByName + `</a>
`))
if tmpl_topic_vars.CurrentUser.Perms.EditReply {
@ -161,11 +163,11 @@ w.Write([]byte(`<a href="` + item.URL + `" class="username hide_on_mobile" style
}
}
w.Write([]byte(`
</div>`))
</div>
`))
}
}
w.Write([]byte(`
</div>
w.Write([]byte(`</div>
`))
if tmpl_topic_vars.CurrentUser.Perms.CreateReply {
w.Write([]byte(`

167
template_topic_alt.go Normal file
View File

@ -0,0 +1,167 @@
package main
import "strconv"
import "html/template"
import "io"
func init() {
template_topic_alt_handle = template_topic_alt
}
func template_topic_alt(tmpl_topic_alt_vars TopicPage, w io.Writer) {
w.Write([]byte(`<!doctype html>
<html lang="en">
<head>
<title>` + tmpl_topic_alt_vars.Title + `</title>
<link href="/static/main.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="/static/jquery-1.12.3.min.js"></script>
<script type="text/javascript">
var session = "` + tmpl_topic_alt_vars.CurrentUser.Session + `";
</script>
<script type="text/javascript" src="/static/global.js"></script>
<meta name="viewport" content="width=device-width,initial-scale = 1.0, maximum-scale=1.0,user-scalable=no" />
</head>
<body>
<div class="container">
<div class="nav">
<div class="move_left">
<div class="move_right">
<ul>
<li class="menu_left menu_overview"><a href="/">Overview</a></li>
<li class="menu_left menu_forums"><a href="/forums/">Forums</a></li>
<li class="menu_left menu_topics"><a href="/">Topics</a></li>
<li class="menu_left menu_create_topic"><a href="/topics/create/">Create Topic</a></li>
`))
if tmpl_topic_alt_vars.CurrentUser.Loggedin {
w.Write([]byte(`
<li class="menu_left menu_account"><a href="/user/edit/critical/">Account</a></li>
<li class="menu_left menu_profile"><a href="/user/` + strconv.Itoa(tmpl_topic_alt_vars.CurrentUser.ID) + `">Profile</a></li>
`))
if tmpl_topic_alt_vars.CurrentUser.Is_Super_Mod {
w.Write([]byte(`<li class="menu_left menu_account"><a href="/panel/">Panel</a></li>`))
}
w.Write([]byte(`
<li class="menu_left menu_logout"><a href="/accounts/logout?session=` + tmpl_topic_alt_vars.CurrentUser.Session + `">Logout</a></li>
`))
} else {
w.Write([]byte(`
<li class="menu_left menu_register"><a href="/accounts/create/">Register</a></li>
<li class="menu_left menu_login"><a href="/accounts/login/">Login</a></li>
`))
}
w.Write([]byte(`
</ul>
</div>
</div>
<div style="clear: both;"></div>
</div>
`))
if len(tmpl_topic_alt_vars.NoticeList) != 0 {
for _, item := range tmpl_topic_alt_vars.NoticeList {
w.Write([]byte(`<div class="alert">` + item + `</div>`))
}
}
w.Write([]byte(`
<div class="rowblock">
<form action='/topic/edit/submit/` + strconv.Itoa(tmpl_topic_alt_vars.Topic.ID) + `' method="post">
<div class="rowitem"`))
if tmpl_topic_alt_vars.Topic.Sticky {
w.Write([]byte(` style="background-color: #FFFFEA;"`))
} else {
if tmpl_topic_alt_vars.Topic.Is_Closed {
w.Write([]byte(` style="background-color: #eaeaea;"`))
}
}
w.Write([]byte(`>
<a class='topic_name hide_on_edit'>` + tmpl_topic_alt_vars.Topic.Title + `</a>
<span class='username hide_on_micro topic_status_e topic_status_` + tmpl_topic_alt_vars.Topic.Status + ` hide_on_edit' style="font-weight:normal;float: right;">` + tmpl_topic_alt_vars.Topic.Status + `</span>
<span class="username hide_on_micro" style="border-right: 0;font-weight: normal;float: right;">Status</span>
`))
if tmpl_topic_alt_vars.CurrentUser.Is_Mod {
w.Write([]byte(`
<a href='/topic/edit/` + strconv.Itoa(tmpl_topic_alt_vars.Topic.ID) + `' class="username hide_on_edit open_edit" style="font-weight: normal;margin-left: 6px;">Edit</a>
<a href='/topic/delete/submit/` + strconv.Itoa(tmpl_topic_alt_vars.Topic.ID) + `' class="username" style="font-weight: normal;">Delete</a>
`))
if tmpl_topic_alt_vars.Topic.Sticky {
w.Write([]byte(`<a href='/topic/unstick/submit/` + strconv.Itoa(tmpl_topic_alt_vars.Topic.ID) + `' class="username" style="font-weight: normal;">Unpin</a>`))
} else {
w.Write([]byte(`<a href='/topic/stick/submit/` + strconv.Itoa(tmpl_topic_alt_vars.Topic.ID) + `' class="username" style="font-weight: normal;">Pin</a>`))
}
w.Write([]byte(`
<input class='show_on_edit topic_name_input' name="topic_name" value='` + tmpl_topic_alt_vars.Topic.Title + `' 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>
`))
}
w.Write([]byte(`
<a href="/report/submit/` + strconv.Itoa(tmpl_topic_alt_vars.Topic.ID) + `?session=` + tmpl_topic_alt_vars.CurrentUser.Session + `&type=topic" class="username report_item" style="font-weight: normal;">Report</a>
</div>
</form>
</div>
<style type="text/css">.rowitem:last-child .content_container { margin-bottom: 5px !important; }</style>
<div class="rowblock post_container" style="border-top: none;">
<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" style="background: white;width: 132px;padding: 2px;margin-top: 2px;float: left;box-shadow:0 1px 2px rgba(0,0,0,.1);">
<div class="avatar_item" style="background-image: url(` + tmpl_topic_alt_vars.Topic.Avatar + `), url(/static/white-dot.jpg);background-position: 0px -10px;background-repeat: no-repeat, repeat-y;background-size: 128px;width: 128px;height: 100%;min-height: 128px;border-style: solid;border-color: #eaeaea;border-width: 1px;">&nbsp;</div>
<div class="the_name" style="margin-top: 3px;text-align: center;color: #505050;">` + tmpl_topic_alt_vars.Topic.CreatedByName + `</div>
</div>
<div class="content_container" style="background: white;margin-left: 137px;min-height: 128px;margin-bottom: 0;margin-right: 3px;box-shadow:0 1px 2px rgba(0,0,0,.1);">
<div class="hide_on_edit topic_content user_content" style="padding: 5px;margin-top: 3px;margin-bottom: 0;background: white;min-height: 153px;padding-bottom: 0;width: 100%;">` + string(tmpl_topic_alt_vars.Topic.Content.(template.HTML)) + `</div>
<textarea name="topic_content" class="show_on_edit topic_content_input">` + string(tmpl_topic_alt_vars.Topic.Content.(template.HTML)) + `</textarea>
</div>
</div>
`))
if len(tmpl_topic_alt_vars.ItemList) != 0 {
for _, item := range tmpl_topic_alt_vars.ItemList {
w.Write([]byte(`
<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" style="background: white;width: 132px;padding: 2px;margin-top: 2px;float: left;box-shadow:0 1px 2px rgba(0,0,0,.1);">
<div class="avatar_item" style="background-image: url(` + item.Avatar + `), url(/static/white-dot.jpg);background-position: 0px -10px;background-repeat: no-repeat, repeat-y;background-size: 128px;width: 128px;height: 100%;min-height: 128px;border-style: solid;border-color: #eaeaea;border-width: 1px;">&nbsp;</div>
<div class="the_name" style="margin-top: 3px;text-align: center;color: #505050;">` + item.CreatedByName + `</div>
</div>
<div class="content_container" style="background: white;margin-left: 137px;min-height: 128px;margin-bottom: 0;margin-right: 3px;box-shadow:0 1px 2px rgba(0,0,0,.1);">
<div class="editable_block user_content" style="padding: 5px;margin-top: 3px;margin-bottom: 0;background: white;min-height: 133px;padding-bottom: 0;width: 100%;">` + string(item.ContentHtml) + `</div>
<div class="button_container" style="border-top: solid 1px #eaeaea;border-spacing: 0px;border-collapse: collapse;padding: 0;margin: 0;display: block;">
`))
if tmpl_topic_alt_vars.CurrentUser.Perms.EditReply {
w.Write([]byte(`<a href="/reply/edit/submit/` + strconv.Itoa(item.ID) + `" style="border-right: solid 1px #eaeaea;color: #505050;font-size: 13px;padding-left: 5px;padding-right: 5px;">Edit</a>`))
}
w.Write([]byte(`
`))
if tmpl_topic_alt_vars.CurrentUser.Perms.DeleteReply {
w.Write([]byte(`<a href="/reply/delete/submit/` + strconv.Itoa(item.ID) + `" style="border-right: solid 1px #eaeaea;color: #505050;font-size: 13px;padding-left: 0;padding-right: 5px;">Delete</a>`))
}
w.Write([]byte(`
<a href="/report/submit/` + strconv.Itoa(item.ID) + `?session=` + tmpl_topic_alt_vars.CurrentUser.Session + `&type=reply" style="border: none;border-right: solid 1px #eaeaea;padding-right: 6px;color: #505050;font-size: 13px;">Report</a>
</div>
</div>
</div>
`))
}
}
w.Write([]byte(`</div>
`))
if tmpl_topic_alt_vars.CurrentUser.Perms.CreateReply {
w.Write([]byte(`
<div class="rowblock">
<form action="/reply/create/" method="post">
<input name="tid" value='` + strconv.Itoa(tmpl_topic_alt_vars.Topic.ID) + `' type="hidden" />
<div class="formrow">
<div class="formitem"><textarea name="reply-content" placeholder="Insert reply here"></textarea></div>
</div>
<div class="formrow">
<div class="formitem"><button name="reply-button" class="formbutton">Create Reply</button></div>
</div>
</form>
</div>
`))
}
w.Write([]byte(`
<!--<link rel="stylesheet" href="https://use.fontawesome.com/8670aa03ca.css">-->
</div>
</body>
</html>`))
}

View File

@ -73,6 +73,10 @@ w.Write([]byte(`background-image: url(` + item.(TopicUser).Avatar + `);backgroun
}
if item.(TopicUser).Sticky {
w.Write([]byte(`background-color: #FFFFCC;`))
} else {
if item.(TopicUser).Is_Closed {
w.Write([]byte(`background-color: #eaeaea;`))
}
}
w.Write([]byte(`">
<a href="/topic/` + strconv.Itoa(item.(TopicUser).ID) + `">` + item.(TopicUser).Title + `</a> `))

View File

@ -3,7 +3,7 @@
<div class="rowitem"><a>{{ .Title }}</a></div>
</div>
<div class="rowblock">
{{range .ItemList}}<div class="rowitem passive" style="{{ if .Avatar }}background-image: url({{ .Avatar }});background-position: left;background-repeat: no-repeat;background-size: 64px;padding-left: 72px;{{end}}{{ if .Sticky }}background-color: #FFFFCC;{{end}}">
{{range .ItemList}}<div class="rowitem passive" style="{{ if .Avatar }}background-image: url({{ .Avatar }});background-position: left;background-repeat: no-repeat;background-size: 64px;padding-left: 72px;{{end}}{{ if .Sticky }}background-color: #FFFFCC;{{else if .Is_Closed}}background-color: #eaeaea;{{end}}">
<a href="/topic/{{.ID}}">{{.Title}}</a> {{if .Is_Closed}}<span class="username topic_status_e topic_status_closed" style="float: right;">closed</span>
{{else}}<span class="username hide_on_micro topic_status_e topic_status_open" style="float: right;">open</span>{{end}}
<span class="username hide_on_micro" style="border-right: 0;float: right;">Status</span>

View File

@ -0,0 +1,13 @@
{{template "header.html" . }}
{{template "panel-menu.html" . }}
<div class="colblock_right">
<div class="rowitem"><a>Groups</a></div>
</div>
<div class="colblock_right">
{{range .ItemList}}
<div class="rowitem editable_parent" style="font-weight: normal;text-transform: none;">
<a class="editable_block" style="font-size: 20px;">{{.Name}}</a>
</div>
{{end}}
</div>
{{template "footer.html" . }}

View File

@ -1,15 +1,15 @@
{{template "header.html" . }}
<div class="colblock_left" style="max-width: 220px;">
<div class="rowitem" style="padding: 0;"><img src="{{.Something.Avatar}}" style="max-width: 100%;margin: 0;"/></div>
<div class="rowitem" style="padding: 0;"><img src="{{.ProfileOwner.Avatar}}" style="max-width: 100%;margin: 0;"/></div>
<div class="rowitem" style="text-transform: capitalize;">
<span style="font-size: 18px;">{{.Something.Name}}</span>{{if .Something.Tag}}<span class="username" style="float: right;font-weight: normal;">{{.Something.Tag}}</span>{{end}}
<span style="font-size: 18px;">{{.ProfileOwner.Name}}</span>{{if .ProfileOwner.Tag}}<span class="username" style="float: right;font-weight: normal;">{{.ProfileOwner.Tag}}</span>{{end}}
</div>
<div class="rowitem passive">
<a class="username">Add Friend</a>
{{if (.CurrentUser.Is_Super_Mod) and not (.Something.Is_Super_Mod) }}
{{if .Something.Is_Banned }}<a href="/users/unban/{{.Something.ID}}?session={{.CurrentUser.Session}}" class="username">Unban</a>{{else}}<a href="/users/ban/{{.Something.ID}}?session={{.CurrentUser.Session}}" class="username">Ban</a>{{end}}
{{if (.CurrentUser.Is_Super_Mod) and not (.ProfileOwner.Is_Super_Mod) }}
{{if .ProfileOwner.Is_Banned }}<a href="/users/unban/{{.ProfileOwner.ID}}?session={{.CurrentUser.Session}}" class="username">Unban</a>{{else}}<a href="/users/ban/{{.ProfileOwner.ID}}?session={{.CurrentUser.Session}}" class="username">Ban</a>{{end}}
{{end}}
<a href="/report/submit/{{.Something.ID}}?session={{.CurrentUser.Session}}&type=user" class="username report_item">Report</a>
<a href="/report/submit/{{.ProfileOwner.ID}}?session={{.CurrentUser.Session}}&type=user" class="username report_item">Report</a>
</div>
</div>
<div class="colblock_right">
@ -24,13 +24,13 @@
{{if $.CurrentUser.Is_Mod}}<a href="/profile/reply/edit/submit/{{.ID}}"><button class="username edit_item">Edit</button></a>
<a href="/profile/reply/delete/submit/{{.ID}}"><button class="username delete_item">Delete</button></a>{{end}}
<a href="/report/submit/{{.ID}}?session={{$.CurrentUser.Session}}&type=user-reply"><button class="username report_item">Report</button></a>
{{ if .Tag }}<a class="username" style="float: right;">{{.Tag}}</a>{{end}}
{{ if .Tag }}<a class="username hide_on_mobile" style="float: right;">{{.Tag}}</a>{{end}}
</div>{{end}}
</div>
{{if not .CurrentUser.Is_Banned}}
<div class="colblock_right">
<form action="/profile/reply/create/" method="post">
<input name="uid" value='{{.Something.ID}}' type="hidden" />
<input name="uid" value='{{.ProfileOwner.ID}}' type="hidden" />
<div class="formrow">
<div class="formitem"><textarea name="reply-content" placeholder="Insert reply here"></textarea></div>
</div>

View File

@ -1,7 +1,7 @@
{{template "header.html" . }}
<div class="rowblock">
<form action='/topic/edit/submit/{{.Topic.ID}}' method="post">
<div class="rowitem"{{ if .Topic.Sticky }} style="background-color: #FFFFEA;"{{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>
<span class='username hide_on_micro topic_status_e topic_status_{{.Topic.Status}} hide_on_edit' style="font-weight:normal;float: right;">{{.Topic.Status}}</span>
<span class="username hide_on_micro" style="border-right: 0;font-weight: normal;float: right;">Status</span>
@ -31,19 +31,17 @@
<a class="username" style="color: #505050;float: right;border-right: 0;">{{.Topic.URLPrefix}}</a>{{end}}
</div>
</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 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>
{{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.DeleteReply}}<a href="/reply/delete/submit/{{.ID}}" class="mod_button"><button class="username delete_item">Delete</button></a>{{end}}
<a href="/report/submit/{{.ID}}?session={{$.CurrentUser.Session}}&type=reply" class="mod_button"><button class="username report_item">Report</button></a>
{{if .Tag}}<a class="username hide_on_micro" style="float: right;">{{.Tag}}</a>{{else if .URLName}}<a href="{{.URL}}" class="username hide_on_mobile" style="color: #505050;float: right;" rel="nofollow">{{.URLName}}</a>
<a class="username hide_on_mobile" style="color: #505050;float: right;border-right: 0;">{{.URLPrefix}}</a>{{end}}
</div>{{end}}
</div>
</div>
{{end}}</div>
{{if .CurrentUser.Perms.CreateReply}}
<div class="rowblock">
<form action="/reply/create/" method="post">

65
templates/topic_alt.html Normal file
View File

@ -0,0 +1,65 @@
{{template "header.html" . }}
<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}}>
<a class='topic_name hide_on_edit'>{{.Topic.Title}}</a>
<span class='username hide_on_micro topic_status_e topic_status_{{.Topic.Status}} hide_on_edit' style="font-weight:normal;float: right;">{{.Topic.Status}}</span>
<span class="username hide_on_micro" style="border-right: 0;font-weight: normal;float: right;">Status</span>
{{if .CurrentUser.Is_Mod}}
<a href='/topic/edit/{{.Topic.ID}}' class="username hide_on_edit open_edit" style="font-weight: normal;margin-left: 6px;">Edit</a>
<a href='/topic/delete/submit/{{.Topic.ID}}' class="username" style="font-weight: normal;">Delete</a>
{{ if .Topic.Sticky }}<a href='/topic/unstick/submit/{{.Topic.ID}}' class="username" style="font-weight: normal;">Unpin</a>{{else}}<a href='/topic/stick/submit/{{.Topic.ID}}' class="username" style="font-weight: normal;">Pin</a>{{end}}
<input class='show_on_edit topic_name_input' name="topic_name" value='{{.Topic.Title}}' 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>
{{end}}
<a href="/report/submit/{{.Topic.ID}}?session={{.CurrentUser.Session}}&type=topic" class="username report_item" style="font-weight: normal;">Report</a>
</div>
</form>
</div>
<style type="text/css">.rowitem:last-child .content_container { margin-bottom: 5px !important; }</style>
<div class="rowblock post_container" style="border-top: none;">
<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" style="background: white;width: 132px;padding: 2px;margin-top: 2px;float: left;box-shadow:0 1px 2px rgba(0,0,0,.1);">
<div class="avatar_item" style="background-image: url({{.Topic.Avatar}}), url(/static/white-dot.jpg);background-position: 0px -10px;background-repeat: no-repeat, repeat-y;background-size: 128px;width: 128px;height: 100%;min-height: 128px;border-style: solid;border-color: #eaeaea;border-width: 1px;">&nbsp;</div>
<div class="the_name" style="margin-top: 3px;text-align: center;color: #505050;">{{.Topic.CreatedByName}}</div>
</div>
<div class="content_container" style="background: white;margin-left: 137px;min-height: 128px;margin-bottom: 0;margin-right: 3px;box-shadow:0 1px 2px rgba(0,0,0,.1);">
<div class="hide_on_edit topic_content user_content" style="padding: 5px;margin-top: 3px;margin-bottom: 0;background: white;min-height: 153px;padding-bottom: 0;width: 100%;">{{.Topic.Content}}</div>
<textarea name="topic_content" class="show_on_edit topic_content_input">{{.Topic.Content}}</textarea>
</div>
</div>
{{range .ItemList}}
<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" style="background: white;width: 132px;padding: 2px;margin-top: 2px;float: left;box-shadow:0 1px 2px rgba(0,0,0,.1);">
<div class="avatar_item" style="background-image: url({{.Avatar}}), url(/static/white-dot.jpg);background-position: 0px -10px;background-repeat: no-repeat, repeat-y;background-size: 128px;width: 128px;height: 100%;min-height: 128px;border-style: solid;border-color: #eaeaea;border-width: 1px;">&nbsp;</div>
<div class="the_name" style="margin-top: 3px;text-align: center;color: #505050;">{{.CreatedByName}}</div>
</div>
<div class="content_container" style="background: white;margin-left: 137px;min-height: 128px;margin-bottom: 0;margin-right: 3px;box-shadow:0 1px 2px rgba(0,0,0,.1);">
<div class="editable_block user_content" style="padding: 5px;margin-top: 3px;margin-bottom: 0;background: white;min-height: 133px;padding-bottom: 0;width: 100%;">{{.ContentHtml}}</div>
<div class="button_container" style="border-top: solid 1px #eaeaea;border-spacing: 0px;border-collapse: collapse;padding: 0;margin: 0;display: block;">
{{if $.CurrentUser.Perms.EditReply}}<a href="/reply/edit/submit/{{.ID}}" style="border-right: solid 1px #eaeaea;color: #505050;font-size: 13px;padding-left: 5px;padding-right: 5px;">Edit</a>{{end}}
{{if $.CurrentUser.Perms.DeleteReply}}<a href="/reply/delete/submit/{{.ID}}" style="border-right: solid 1px #eaeaea;color: #505050;font-size: 13px;padding-left: 0;padding-right: 5px;">Delete</a>{{end}}
<a href="/report/submit/{{.ID}}?session={{$.CurrentUser.Session}}&type=reply" style="border: none;border-right: solid 1px #eaeaea;padding-right: 6px;color: #505050;font-size: 13px;">Report</a>
</div>
</div>
</div>
{{end}}</div>
{{if .CurrentUser.Perms.CreateReply}}
<div class="rowblock">
<form action="/reply/create/" method="post">
<input name="tid" value='{{.Topic.ID}}' type="hidden" />
<div class="formrow">
<div class="formitem"><textarea name="reply-content" placeholder="Insert reply here"></textarea></div>
</div>
<div class="formrow">
<div class="formitem"><button name="reply-button" class="formbutton">Create Reply</button></div>
</div>
</form>
</div>
{{end}}
{{template "footer.html" . }}

View File

@ -3,7 +3,7 @@
<div class="rowitem"><a>Topic List</a></div>
</div>
<div class="rowblock">
{{range .ItemList}}<div class="rowitem passive" style="{{ if .Avatar }}background-image: url({{ .Avatar }});background-position: left;background-repeat: no-repeat;background-size: 64px;padding-left: 72px;{{end}}{{ if .Sticky }}background-color: #FFFFCC;{{end}}">
{{range .ItemList}}<div class="rowitem passive" style="{{if .Avatar}}background-image: url({{.Avatar}});background-position: left;background-repeat: no-repeat;background-size: 64px;padding-left: 72px;{{end}}{{if .Sticky}}background-color: #FFFFCC;{{else if .Is_Closed}}background-color: #eaeaea;{{end}}">
<a href="/topic/{{.ID}}">{{.Title}}</a> {{if .Is_Closed}}<span class="username topic_status_e topic_status_closed" style="float: right;">closed</span>
{{else}}<span class="username hide_on_micro topic_status_e topic_status_open" style="float: right;">open</span>{{end}}
<span class="username hide_on_micro" style="border-right: 0;float: right;">Status</span>