The design is now responsive. It looks decent on mobile phones, tablets, laptops and desktop computers.

The router is now benchmarked. The custom router we'll use to replace it will also be benchmarked once it's completed.
Added a placeholder page for the Control Panel Dashboard.
Tightened some of the control panel route permission checks.
Moved the Control Panel menu into it's own template.
Added permission checks to the links on the Control Panel menu.
This commit is contained in:
Azareal 2016-12-24 13:14:40 +00:00
parent 544155849f
commit 9f2efce516
32 changed files with 352 additions and 154 deletions

View File

@ -18,7 +18,7 @@ In-memory static file, forum and group caches.
A profile system including profile comments and moderation tools for the profile owner.
A template engine which compiles templates down into machine code. Over ten times faster than html/templates.
A template engine which compiles templates down into machine code. Over ten times faster than html/templates. Compatible with templates written for html/templates, you don't need to learn any new templating language.
A plugin system. Under development.

View File

@ -2,6 +2,7 @@ package main
//import "fmt"
import "log"
import "bytes"
import "math/rand"
import "testing"
import "net/http"
import "net/http/httptest"
@ -216,17 +217,170 @@ func BenchmarkRoute(b *testing.B) {
forums_handler.ServeHTTP(forums_w,forums_req)
}
})
}
func addEmptyRoutesToMux(routes []string, serveMux *http.ServeMux) {
for _, route := range routes {
serveMux.HandleFunc(route, func(_ http.ResponseWriter,_ *http.Request){})
}
}
func BenchmarkRouter(b *testing.B) {
w := httptest.NewRecorder()
req := httptest.NewRequest("get","/topics/",bytes.NewReader(nil))
routes := make([]string, 0)
routes = append(routes,"/test/")
serveMux := http.NewServeMux()
serveMux.HandleFunc("/topics/", route_topics)
b.Run("topics_guest_plus_router", func(b *testing.B) {
serveMux.HandleFunc("/test/", func(_ http.ResponseWriter,_ *http.Request){})
b.Run("one-route", func(b *testing.B) {
for i := 0; i < b.N; i++ {
topics_w.Body.Reset()
serveMux.ServeHTTP(topics_w,topics_req)
req = httptest.NewRequest("get",routes[rand.Intn(len(routes))],bytes.NewReader(nil))
serveMux.ServeHTTP(w,req)
}
})
routes = append(routes,"/topic/")
routes = append(routes,"/forums/")
routes = append(routes,"/forum/")
routes = append(routes,"/panel/")
serveMux = http.NewServeMux()
addEmptyRoutesToMux(routes, serveMux)
b.Run("five-routes", func(b *testing.B) {
for i := 0; i < b.N; i++ {
req = httptest.NewRequest("get",routes[rand.Intn(len(routes))],bytes.NewReader(nil))
serveMux.ServeHTTP(w,req)
}
})
serveMux = http.NewServeMux()
routes = append(routes,"/panel/plugins/")
routes = append(routes,"/panel/groups/")
routes = append(routes,"/panel/settings/")
routes = append(routes,"/panel/users/")
routes = append(routes,"/panel/forums/")
addEmptyRoutesToMux(routes, serveMux)
b.Run("ten-routes", func(b *testing.B) {
for i := 0; i < b.N; i++ {
req = httptest.NewRequest("get",routes[rand.Intn(len(routes))],bytes.NewReader(nil))
serveMux.ServeHTTP(w,req)
}
})
serveMux = http.NewServeMux()
routes = append(routes,"/panel/forums/create/submit/")
routes = append(routes,"/panel/forums/delete/")
routes = append(routes,"/users/ban/")
routes = append(routes,"/panel/users/edit/")
routes = append(routes,"/panel/forums/create/")
routes = append(routes,"/users/unban/")
routes = append(routes,"/pages/")
routes = append(routes,"/users/activate/")
routes = append(routes,"/panel/forums/edit/submit/")
routes = append(routes,"/panel/plugins/activate/")
addEmptyRoutesToMux(routes, serveMux)
b.Run("twenty-routes", func(b *testing.B) {
for i := 0; i < b.N; i++ {
req = httptest.NewRequest("get",routes[rand.Intn(len(routes))],bytes.NewReader(nil))
serveMux.ServeHTTP(w,req)
}
})
serveMux = http.NewServeMux()
routes = append(routes,"/panel/plugins/deactivate/")
routes = append(routes,"/panel/plugins/install/")
routes = append(routes,"/panel/plugins/uninstall/")
routes = append(routes,"/panel/templates/")
routes = append(routes,"/panel/templates/edit/")
routes = append(routes,"/panel/templates/create/")
routes = append(routes,"/panel/templates/delete/")
routes = append(routes,"/panel/templates/edit/submit/")
routes = append(routes,"/panel/themes/")
routes = append(routes,"/panel/themes/edit/")
addEmptyRoutesToMux(routes, serveMux)
b.Run("thirty-routes", func(b *testing.B) {
for i := 0; i < b.N; i++ {
req = httptest.NewRequest("get",routes[rand.Intn(len(routes))],bytes.NewReader(nil))
serveMux.ServeHTTP(w,req)
}
})
serveMux = http.NewServeMux()
routes = append(routes,"/panel/themes/create/")
routes = append(routes,"/panel/themes/delete/")
routes = append(routes,"/panel/themes/delete/submit/")
routes = append(routes,"/panel/templates/create/submit/")
routes = append(routes,"/panel/templates/delete/submit/")
routes = append(routes,"/panel/widgets/")
routes = append(routes,"/panel/widgets/edit/")
routes = append(routes,"/panel/widgets/activate/")
routes = append(routes,"/panel/widgets/deactivate/")
routes = append(routes,"/panel/magical/wombat/path")
addEmptyRoutesToMux(routes, serveMux)
b.Run("forty-routes", func(b *testing.B) {
for i := 0; i < b.N; i++ {
req = httptest.NewRequest("get",routes[rand.Intn(len(routes))],bytes.NewReader(nil))
serveMux.ServeHTTP(w,req)
}
})
serveMux = http.NewServeMux()
routes = append(routes,"/report/")
routes = append(routes,"/report/submit/")
routes = append(routes,"/topic/create/submit/")
routes = append(routes,"/topics/create/")
routes = append(routes,"/overview/")
routes = append(routes,"/uploads/")
routes = append(routes,"/static/")
routes = append(routes,"/reply/edit/submit/")
routes = append(routes,"/reply/delete/submit/")
routes = append(routes,"/topic/edit/submit/")
addEmptyRoutesToMux(routes, serveMux)
b.Run("fifty-routes", func(b *testing.B) {
for i := 0; i < b.N; i++ {
req = httptest.NewRequest("get",routes[rand.Intn(len(routes))],bytes.NewReader(nil))
serveMux.ServeHTTP(w,req)
}
})
serveMux = http.NewServeMux()
routes = append(routes,"/topic/delete/submit/")
routes = append(routes,"/topic/stick/submit/")
routes = append(routes,"/topic/unstick/submit/")
routes = append(routes,"/accounts/login/")
routes = append(routes,"/accounts/create/")
routes = append(routes,"/accounts/logout/")
routes = append(routes,"/accounts/login/submit/")
routes = append(routes,"/accounts/create/submit/")
routes = append(routes,"/user/edit/critical/")
routes = append(routes,"/user/edit/critical/submit/")
addEmptyRoutesToMux(routes, serveMux)
b.Run("sixty-routes", func(b *testing.B) {
for i := 0; i < b.N; i++ {
req = httptest.NewRequest("get",routes[rand.Intn(len(routes))],bytes.NewReader(nil))
serveMux.ServeHTTP(w,req)
}
})
serveMux = http.NewServeMux()
routes = append(routes,"/user/edit/avatar/")
routes = append(routes,"/user/edit/avatar/submit/")
routes = append(routes,"/user/edit/username/")
routes = append(routes,"/user/edit/username/submit/")
routes = append(routes,"/profile/reply/create/")
routes = append(routes,"/profile/reply/edit/submit/")
routes = append(routes,"/profile/reply/delete/submit/")
routes = append(routes,"/arcane/tower/")
routes = append(routes,"/magical/kingdom/")
routes = append(routes,"/insert/name/here/")
addEmptyRoutesToMux(routes, serveMux)
b.Run("seventy-routes", func(b *testing.B) {
for i := 0; i < b.N; i++ {
req = httptest.NewRequest("get",routes[rand.Intn(len(routes))],bytes.NewReader(nil))
serveMux.ServeHTTP(w,req)
}
})
}
/*func TestRoute(b *testing.T) {
/*func TestRoute(t *testing.T) {
}*/

Binary file not shown.

BIN
images/bench_round2.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

BIN
images/laptop-1440px.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 KiB

BIN
images/mobile-320px.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

BIN
images/mobile-375px.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

BIN
images/mobile-425px.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

BIN
images/tablet-1024px.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

BIN
images/tablet-768px.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View File

@ -194,6 +194,7 @@ func main(){
http.HandleFunc("/users/activate/", route_activate)
// Admin
http.HandleFunc("/panel/", route_panel)
http.HandleFunc("/panel/forums/", route_panel_forums)
http.HandleFunc("/panel/forums/create/", route_panel_forums_create_submit)
http.HandleFunc("/panel/forums/delete/", route_panel_forums_delete)

View File

@ -532,12 +532,27 @@ func route_activate(w http.ResponseWriter, r *http.Request) {
http.Redirect(w,r,"/users/" + strconv.Itoa(uid),http.StatusSeeOther)
}
/* Control Panel*/
func route_panel(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
}
pi := Page{"Control Panel Dashboard","panel",user,noticeList,tList,0}
templates.ExecuteTemplate(w,"panel-dashboard.html", pi)
}
func route_panel_forums(w http.ResponseWriter, r *http.Request){
user, noticeList, ok := SessionCheck(w,r)
if !ok {
return
}
if !user.Perms.ManageForums {
if !user.Is_Super_Mod || !user.Perms.ManageForums {
NoPermissions(w,r,user)
return
}
@ -558,7 +573,7 @@ func route_panel_forums_create_submit(w http.ResponseWriter, r *http.Request){
if !ok {
return
}
if !user.Perms.ManageForums {
if !user.Is_Super_Mod || !user.Perms.ManageForums {
NoPermissions(w,r,user)
return
}
@ -595,7 +610,7 @@ func route_panel_forums_delete(w http.ResponseWriter, r *http.Request){
if !ok {
return
}
if !user.Perms.ManageForums {
if !user.Is_Super_Mod || !user.Perms.ManageForums {
NoPermissions(w,r,user)
return
}
@ -628,7 +643,7 @@ func route_panel_forums_delete_submit(w http.ResponseWriter, r *http.Request) {
if !ok {
return
}
if !user.Perms.ManageForums {
if !user.Is_Super_Mod || !user.Perms.ManageForums {
NoPermissions(w,r,user)
return
}
@ -666,7 +681,7 @@ func route_panel_forums_edit_submit(w http.ResponseWriter, r *http.Request) {
if !ok {
return
}
if !user.Perms.ManageForums {
if !user.Is_Super_Mod || !user.Perms.ManageForums {
NoPermissions(w,r,user)
return
}
@ -710,7 +725,7 @@ func route_panel_settings(w http.ResponseWriter, r *http.Request){
if !ok {
return
}
if !user.Perms.EditSettings {
if !user.Is_Super_Mod || !user.Perms.EditSettings {
NoPermissions(w,r,user)
return
}
@ -766,7 +781,7 @@ func route_panel_setting(w http.ResponseWriter, r *http.Request){
if !ok {
return
}
if !user.Perms.EditSettings {
if !user.Is_Super_Mod || !user.Perms.EditSettings {
NoPermissions(w,r,user)
return
}
@ -816,7 +831,7 @@ func route_panel_setting_edit(w http.ResponseWriter, r *http.Request) {
if !ok {
return
}
if !user.Perms.EditSettings {
if !user.Is_Super_Mod || !user.Perms.EditSettings {
NoPermissions(w,r,user)
return
}
@ -872,7 +887,7 @@ func route_panel_plugins(w http.ResponseWriter, r *http.Request){
if !ok {
return
}
if !user.Perms.ManagePlugins {
if !user.Is_Super_Mod || !user.Perms.ManagePlugins {
NoPermissions(w,r,user)
return
}
@ -891,7 +906,7 @@ func route_panel_plugins_activate(w http.ResponseWriter, r *http.Request){
if !ok {
return
}
if !user.Perms.ManagePlugins {
if !user.Is_Super_Mod || !user.Perms.ManagePlugins {
NoPermissions(w,r,user)
return
}
@ -954,7 +969,7 @@ func route_panel_plugins_deactivate(w http.ResponseWriter, r *http.Request){
if !ok {
return
}
if !user.Perms.ManagePlugins {
if !user.Is_Super_Mod || !user.Perms.ManagePlugins {
NoPermissions(w,r,user)
return
}

View File

@ -28,18 +28,8 @@ body
}
}
/*.move_left
{
float: left;
position: relative;
left: 50%;
}
.move_right
{
float: left;
position: relative;
left: -50%;
}*/
/*.move_left{float: left;position: relative;left: 50%;}
.move_right{float: left;position: relative;left: -50%;}*/
ul
{
padding-left: 0px;
@ -341,3 +331,81 @@ button.username
margin-bottom: 8px;
background-color: #FEB7CC;
}
@media (max-width: 880px) {
li
{
height: 25px;
font-size: 15px;
padding-left: 7px;
}
ul { height: 26px; margin-top: 8px; }
.menu_left { padding-right: 7px; }
.menu_right { padding-right: 7px; }
body { padding-left: 4px; padding-right: 4px; margin: 0px !important; width: 100% !important; height: 100% !important; overflow-x: hidden; }
.container { width: auto; }
}
@media (max-width: 810px) {
li
{
font-weight: normal;
text-transform: none;
}
.rowitem
{
text-transform: none;
}
}
@media (max-width: 620px) {
li
{
padding-left: 5px;
padding-top: 2px;
padding-bottom: 2px;
height: 23px;
}
ul { height: 24px; }
.menu_left { padding-right: 5px; }
.menu_right { padding-right: 5px; }
.menu_create_topic { display: none;}
.hide_on_mobile { display: none; }
}
@media (max-width: 470px) {
.menu_overview { display: none; }
.menu_profile { display: none; }
.hide_on_micro { display: none; }
.post_container {
overflow: visible !important;
}
.post_item {
background-position: 0px 2px !important;
background-size: 64px 64px !important;
padding-left: 2px !important;
min-height: 96px;
position: relative !important;
}
.post_item > .user_content {
margin-left: 75px !important;
width: 100% !important;
}
.post_item > .mod_button {
float: right !important;
margin-left: 2px !important;
position: relative;
top: -14px;
}
.post_item > .real_username {
position: absolute;
top: 70px;
float: left;
margin-top: 0px;
padding-top: 3px !important;
margin-right: 2px;
width: 60px;
font-size: 15px;
}
.container { width: 100% !important; }
}

View File

@ -17,6 +17,7 @@ w.Write([]byte(`<!doctype html>
var session = "` + tmpl_forum_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">
@ -32,10 +33,10 @@ w.Write([]byte(`<!doctype html>
if tmpl_forum_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_account"><a href="/user/` + strconv.Itoa(tmpl_forum_vars.CurrentUser.ID) + `">Profile</a></li>
<li class="menu_left menu_profile"><a href="/user/` + strconv.Itoa(tmpl_forum_vars.CurrentUser.ID) + `">Profile</a></li>
`))
if tmpl_forum_vars.CurrentUser.Is_Super_Mod {
w.Write([]byte(`<li class="menu_left menu_account"><a href="/panel/forums/">Panel</a></li>`))
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_forum_vars.CurrentUser.Session + `">Logout</a></li>
@ -79,10 +80,10 @@ if item.(TopicUser).Is_Closed {
w.Write([]byte(`<span class="username topic_status_e topic_status_closed" style="float: right;">closed</span>
`))
} else {
w.Write([]byte(`<span class="username topic_status_e topic_status_open" style="float: right;">open</span>`))
w.Write([]byte(`<span class="username hide_on_micro topic_status_e topic_status_open" style="float: right;">open</span>`))
}
w.Write([]byte(`
<span class="username" style="border-right: 0;float: right;">Status</span>
<span class="username hide_on_micro" style="border-right: 0;float: right;">Status</span>
</div>
`))
}

View File

@ -17,6 +17,7 @@ w.Write([]byte(`<!doctype html>
var session = "` + tmpl_forums_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">
@ -32,10 +33,10 @@ w.Write([]byte(`<!doctype html>
if tmpl_forums_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_account"><a href="/user/` + strconv.Itoa(tmpl_forums_vars.CurrentUser.ID) + `">Profile</a></li>
<li class="menu_left menu_profile"><a href="/user/` + strconv.Itoa(tmpl_forums_vars.CurrentUser.ID) + `">Profile</a></li>
`))
if tmpl_forums_vars.CurrentUser.Is_Super_Mod {
w.Write([]byte(`<li class="menu_left menu_account"><a href="/panel/forums/">Panel</a></li>`))
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_forums_vars.CurrentUser.Session + `">Logout</a></li>

View File

@ -18,6 +18,7 @@ w.Write([]byte(`<!doctype html>
var session = "` + tmpl_topic_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">
@ -33,10 +34,10 @@ w.Write([]byte(`<!doctype html>
if tmpl_topic_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_account"><a href="/user/` + strconv.Itoa(tmpl_topic_vars.CurrentUser.ID) + `">Profile</a></li>
<li class="menu_left menu_profile"><a href="/user/` + strconv.Itoa(tmpl_topic_vars.CurrentUser.ID) + `">Profile</a></li>
`))
if tmpl_topic_vars.CurrentUser.Is_Super_Mod {
w.Write([]byte(`<li class="menu_left menu_account"><a href="/panel/forums/">Panel</a></li>`))
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_vars.CurrentUser.Session + `">Logout</a></li>
@ -68,8 +69,8 @@ w.Write([]byte(` style="background-color: #FFFFEA;"`))
}
w.Write([]byte(`>
<a class='topic_name hide_on_edit'>` + tmpl_topic_vars.Topic.Title + `</a>
<span class='username topic_status_e topic_status_` + tmpl_topic_vars.Topic.Status + ` hide_on_edit' style="font-weight:normal;float: right;">` + tmpl_topic_vars.Topic.Status + `</span>
<span class="username" style="border-right: 0;font-weight: normal;float: right;">Status</span>
<span class='username hide_on_micro topic_status_e topic_status_` + tmpl_topic_vars.Topic.Status + ` hide_on_edit' style="font-weight:normal;float: right;">` + tmpl_topic_vars.Topic.Status + `</span>
<span class="username hide_on_micro" style="border-right: 0;font-weight: normal;float: right;">Status</span>
`))
if tmpl_topic_vars.CurrentUser.Is_Mod {
w.Write([]byte(`
@ -96,8 +97,8 @@ w.Write([]byte(`
</div>
</form>
</div>
<div class="rowblock">
<div class="rowitem passive editable_parent" style="border-bottom: none;`))
<div class="rowblock post_container">
<div class="rowitem passive editable_parent post_item" style="border-bottom: none;`))
if tmpl_topic_vars.Topic.Avatar != "" {
w.Write([]byte(`background-image: url(` + tmpl_topic_vars.Topic.Avatar + `), url(/static/white-dot.jpg);background-position: 0px `))
if tmpl_topic_vars.Topic.ContentLines <= 5 {
@ -106,13 +107,13 @@ w.Write([]byte(`-1`))
w.Write([]byte(`0px;background-repeat: no-repeat, repeat-y;background-size: 128px;padding-left: 136px;` + string(tmpl_topic_vars.Topic.Css)))
}
w.Write([]byte(`">
<span class="hide_on_edit topic_content user_content">` + string(tmpl_topic_vars.Topic.Content.(template.HTML)) + `</span>
<p class="hide_on_edit topic_content user_content" style="margin: 0;padding: 0;">` + string(tmpl_topic_vars.Topic.Content.(template.HTML)) + `</p>
<textarea name="topic_content" class="show_on_edit topic_content_input">` + string(tmpl_topic_vars.Topic.Content.(template.HTML)) + `</textarea>
<br /><br />
<a href="/user/` + strconv.Itoa(tmpl_topic_vars.Topic.CreatedBy) + `" class="username">` + tmpl_topic_vars.Topic.CreatedByName + `</a>
<a href="/user/` + strconv.Itoa(tmpl_topic_vars.Topic.CreatedBy) + `" class="username real_username">` + tmpl_topic_vars.Topic.CreatedByName + `</a>
`))
if tmpl_topic_vars.Topic.Tag != "" {
w.Write([]byte(`<a class="username" style="float: right;">` + tmpl_topic_vars.Topic.Tag + `</a>`))
w.Write([]byte(`<a class="username hide_on_micro" style="float: right;">` + tmpl_topic_vars.Topic.Tag + `</a>`))
} else {
if tmpl_topic_vars.Topic.URLName != "" {
w.Write([]byte(`<a href="` + tmpl_topic_vars.Topic.URL + `" class="username" style="color: #505050;float: right;">` + tmpl_topic_vars.Topic.URLName + `</a>
@ -122,12 +123,12 @@ w.Write([]byte(`<a href="` + tmpl_topic_vars.Topic.URL + `" class="username" sty
w.Write([]byte(`
</div>
</div><br />
<div class="rowblock" 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(`
<div class="rowitem passive deletable_block editable_parent" style="`))
<div class="rowitem passive deletable_block editable_parent post_item" style="`))
if item.Avatar != "" {
w.Write([]byte(`background-image: url(` + item.Avatar + `), url(/static/white-dot.jpg);background-position: 0px `))
if item.ContentLines <= 5 {
@ -136,27 +137,27 @@ 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>
<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">` + item.CreatedByName + `</a>
<a href="/user/` + strconv.Itoa(item.CreatedBy) + `" class="username real_username">` + item.CreatedByName + `</a>
`))
if tmpl_topic_vars.CurrentUser.Perms.EditReply {
w.Write([]byte(`<a href="/reply/edit/submit/` + strconv.Itoa(item.ID) + `"><button class="username edit_item">Edit</button></a>`))
w.Write([]byte(`<a href="/reply/edit/submit/` + strconv.Itoa(item.ID) + `" class="mod_button"><button class="username edit_item">Edit</button></a>`))
}
w.Write([]byte(`
`))
if tmpl_topic_vars.CurrentUser.Perms.DeleteReply {
w.Write([]byte(`<a href="/reply/delete/submit/` + strconv.Itoa(item.ID) + `"><button class="username delete_item">Delete</button></a>`))
w.Write([]byte(`<a href="/reply/delete/submit/` + strconv.Itoa(item.ID) + `" class="mod_button"><button class="username delete_item">Delete</button></a>`))
}
w.Write([]byte(`
<a href="/report/submit/` + strconv.Itoa(item.ID) + `?session=` + tmpl_topic_vars.CurrentUser.Session + `&type=reply"><button class="username report_item">Report</button></a>
<a href="/report/submit/` + strconv.Itoa(item.ID) + `?session=` + tmpl_topic_vars.CurrentUser.Session + `&type=reply" class="mod_button"><button class="username report_item">Report</button></a>
`))
if item.Tag != "" {
w.Write([]byte(`<a class="username" style="float: right;">` + item.Tag + `</a>`))
w.Write([]byte(`<a class="username hide_on_micro" style="float: right;">` + item.Tag + `</a>`))
} else {
if item.URLName != "" {
w.Write([]byte(`<a href="` + item.URL + `" class="username" style="color: #505050;float: right;" rel="nofollow">` + item.URLName + `</a>
<a class="username" style="color: #505050;float: right;border-right: 0;">` + item.URLPrefix + `</a>`))
w.Write([]byte(`<a href="` + item.URL + `" class="username hide_on_mobile" style="color: #505050;float: right;" rel="nofollow">` + item.URLName + `</a>
<a class="username hide_on_mobile" style="color: #505050;float: right;border-right: 0;">` + item.URLPrefix + `</a>`))
}
}
w.Write([]byte(`

View File

@ -17,6 +17,7 @@ w.Write([]byte(`<!doctype html>
var session = "` + tmpl_topics_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">
@ -32,10 +33,10 @@ w.Write([]byte(`<!doctype html>
if tmpl_topics_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_account"><a href="/user/` + strconv.Itoa(tmpl_topics_vars.CurrentUser.ID) + `">Profile</a></li>
<li class="menu_left menu_profile"><a href="/user/` + strconv.Itoa(tmpl_topics_vars.CurrentUser.ID) + `">Profile</a></li>
`))
if tmpl_topics_vars.CurrentUser.Is_Super_Mod {
w.Write([]byte(`<li class="menu_left menu_account"><a href="/panel/forums/">Panel</a></li>`))
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_topics_vars.CurrentUser.Session + `">Logout</a></li>
@ -79,10 +80,10 @@ if item.(TopicUser).Is_Closed {
w.Write([]byte(`<span class="username topic_status_e topic_status_closed" style="float: right;">closed</span>
`))
} else {
w.Write([]byte(`<span class="username topic_status_e topic_status_open" style="float: right;">open</span>`))
w.Write([]byte(`<span class="username hide_on_micro topic_status_e topic_status_open" style="float: right;">open</span>`))
}
w.Write([]byte(`
<span class="username" style="border-right: 0;float: right;">Status</span>
<span class="username hide_on_micro" style="border-right: 0;float: right;">Status</span>
</div>
`))
}

View File

@ -5,8 +5,8 @@
<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}}">
<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 topic_status_e topic_status_open" style="float: right;">open</span>{{end}}
<span class="username" style="border-right: 0;float: right;">Status</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>
</div>
{{else}}<div class="rowitem passive">There aren't any topics in this forum yet.</div>{{end}}
</div>

View File

@ -8,6 +8,7 @@
var session = "{{.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">

View File

@ -8,8 +8,8 @@
<li class="menu_left menu_create_topic"><a href="/topics/create/">Create Topic</a></li>
{{ if .CurrentUser.Loggedin }}
<li class="menu_left menu_account"><a href="/user/edit/critical/">Account</a></li>
<li class="menu_left menu_account"><a href="/user/{{.CurrentUser.ID}}">Profile</a></li>
{{ if .CurrentUser.Is_Super_Mod}}<li class="menu_left menu_account"><a href="/panel/forums/">Panel</a></li>{{end}}
<li class="menu_left menu_profile"><a href="/user/{{.CurrentUser.ID}}">Profile</a></li>
{{ if .CurrentUser.Is_Super_Mod}}<li class="menu_left menu_account"><a href="/panel/">Panel</a></li>{{end}}
<li class="menu_left menu_logout"><a href="/accounts/logout?session={{.CurrentUser.Session}}">Logout</a></li>
{{ else }}
<li class="menu_left menu_register"><a href="/accounts/create/">Register</a></li>

View File

@ -0,0 +1,9 @@
{{template "header.html" . }}
{{template "panel-menu.html" . }}
<div class="colblock_right">
<div class="rowitem"><a>Dashboard</a></div>
</div>
<div class="colblock_right">
<div class="rowitem passive">Coming Soon...</div>
</div>
{{template "footer.html" . }}

View File

@ -1,16 +1,5 @@
{{template "header.html" . }}
<div class="colblock_left">
<div class="rowitem"><a>Control Panel</a></div>
<div class="rowitem passive"><a href="/panel/forums/">Forums</a></div>
<div class="rowitem passive"><a href="/panel/settings/">Settings</a></div>
<div class="rowitem passive"><a href="/panel/plugins/">Plugins</a></div>
<div class="rowitem passive"><a href="/panel/users/">Users</a></div>
<div class="rowitem passive"><a href="/panel/groups/">Groups</a></div>
<div class="rowitem passive"><a>Coming Soon</a></div>
<div class="rowitem passive"><a>Coming Soon</a></div>
<div class="rowitem passive"><a>Coming Soon</a></div>
<div class="rowitem passive"><a href="/forum/-1">Reports</a></div>
</div>
{{template "panel-menu.html" . }}
<div class="colblock_right">
<div class="rowitem"><a>Forums</a></div>
</div>

12
templates/panel-menu.html Normal file
View File

@ -0,0 +1,12 @@
<div class="colblock_left">
<div class="rowitem"><a href="/panel/">Control Panel</a></div>
<div class="rowitem passive"><a href="/panel/users/">Users</a></div>
<div class="rowitem passive"><a href="/panel/groups/">Groups</a></div>
{{if .CurrentUser.Perms.ManageForums}}<div class="rowitem passive"><a href="/panel/forums/">Forums</a></div>{{end}}
{{if .CurrentUser.Perms.EditSettings}}<div class="rowitem passive"><a href="/panel/settings/">Settings</a></div>{{end}}
{{if .CurrentUser.Perms.ManagePlugins}}<div class="rowitem passive"><a href="/panel/plugins/">Plugins</a></div>{{end}}
<div class="rowitem passive"><a>Coming Soon</a></div>
<div class="rowitem passive"><a>Coming Soon</a></div>
<div class="rowitem passive"><a>Coming Soon</a></div>
<div class="rowitem passive"><a href="/forum/-1">Reported Content</a></div>
</div>

View File

@ -1,16 +1,5 @@
{{template "header.html" . }}
<div class="colblock_left">
<div class="rowitem"><a>Control Panel</a></div>
<div class="rowitem passive"><a href="/panel/forums/">Forums</a></div>
<div class="rowitem passive"><a href="/panel/settings/">Settings</a></div>
<div class="rowitem passive"><a href="/panel/plugins/">Plugins</a></div>
<div class="rowitem passive"><a href="/panel/users/">Users</a></div>
<div class="rowitem passive"><a href="/panel/groups/">Groups</a></div>
<div class="rowitem passive"><a>Coming Soon</a></div>
<div class="rowitem passive"><a>Coming Soon</a></div>
<div class="rowitem passive"><a>Coming Soon</a></div>
<div class="rowitem passive"><a href="/forum/-1">Reports</a></div>
</div>
{{template "panel-menu.html" . }}
<div class="colblock_right">
<div class="rowitem"><a>Plugins</a></div>
</div>

View File

@ -1,16 +1,5 @@
{{template "header.html" . }}
<div class="colblock_left">
<div class="rowitem"><a>Control Panel</a></div>
<div class="rowitem passive"><a href="/panel/forums/">Forums</a></div>
<div class="rowitem passive"><a href="/panel/settings/">Settings</a></div>
<div class="rowitem passive"><a href="/panel/plugins/">Plugins</a></div>
<div class="rowitem passive"><a href="/panel/users/">Users</a></div>
<div class="rowitem passive"><a href="/panel/groups/">Groups</a></div>
<div class="rowitem passive"><a>Coming Soon</a></div>
<div class="rowitem passive"><a>Coming Soon</a></div>
<div class="rowitem passive"><a>Coming Soon</a></div>
<div class="rowitem passive"><a href="/forum/-1">Reports</a></div>
</div>
{{template "panel-menu.html" . }}
<div class="colblock_right">
<div class="rowitem"><a>Edit Setting</a></div>
</div>

View File

@ -1,16 +1,5 @@
{{template "header.html" . }}
<div class="colblock_left">
<div class="rowitem"><a>Control Panel</a></div>
<div class="rowitem passive"><a href="/panel/forums/">Forums</a></div>
<div class="rowitem passive"><a href="/panel/settings/">Settings</a></div>
<div class="rowitem passive"><a href="/panel/plugins/">Plugins</a></div>
<div class="rowitem passive"><a href="/panel/users/">Users</a></div>
<div class="rowitem passive"><a href="/panel/groups/">Groups</a></div>
<div class="rowitem passive"><a>Coming Soon</a></div>
<div class="rowitem passive"><a>Coming Soon</a></div>
<div class="rowitem passive"><a>Coming Soon</a></div>
<div class="rowitem passive"><a href="/forum/-1">Reports</a></div>
</div>
{{template "panel-menu.html" . }}
<div class="colblock_right">
<div class="rowitem"><a>Settings</a></div>
</div>

View File

@ -1,16 +1,5 @@
{{template "header.html" . }}
<div class="colblock_left">
<div class="rowitem"><a>Control Panel</a></div>
<div class="rowitem passive"><a href="/panel/forums/">Forums</a></div>
<div class="rowitem passive"><a href="/panel/settings/">Settings</a></div>
<div class="rowitem passive"><a href="/panel/plugins/">Plugins</a></div>
<div class="rowitem passive"><a href="/panel/users/">Users</a></div>
<div class="rowitem passive"><a href="/panel/groups/">Groups</a></div>
<div class="rowitem passive"><a>Coming Soon</a></div>
<div class="rowitem passive"><a>Coming Soon</a></div>
<div class="rowitem passive"><a>Coming Soon</a></div>
<div class="rowitem passive"><a href="/forum/-1">Reports</a></div>
</div>
{{template "panel-menu.html" . }}
<div class="colblock_right">
<div class="rowitem"><a>User Editor</a></div>
</div>

View File

@ -1,16 +1,5 @@
{{template "header.html" . }}
<div class="colblock_left">
<div class="rowitem"><a>Control Panel</a></div>
<div class="rowitem passive"><a href="/panel/forums/">Forums</a></div>
<div class="rowitem passive"><a href="/panel/settings/">Settings</a></div>
<div class="rowitem passive"><a href="/panel/plugins/">Plugins</a></div>
<div class="rowitem passive"><a href="/panel/users/">Users</a></div>
<div class="rowitem passive"><a href="/panel/groups/">Groups</a></div>
<div class="rowitem passive"><a>Coming Soon</a></div>
<div class="rowitem passive"><a>Coming Soon</a></div>
<div class="rowitem passive"><a>Coming Soon</a></div>
<div class="rowitem passive"><a href="/forum/-1">Reports</a></div>
</div>
{{template "panel-menu.html" . }}
<div class="colblock_right">
<div class="rowitem"><a>Users</a></div>
</div>

View File

@ -3,8 +3,8 @@
<form action='/topic/edit/submit/{{.Topic.ID}}' method="post">
<div class="rowitem"{{ if .Topic.Sticky }} style="background-color: #FFFFEA;"{{end}}>
<a class='topic_name hide_on_edit'>{{.Topic.Title}}</a>
<span class='username topic_status_e topic_status_{{.Topic.Status}} hide_on_edit' style="font-weight:normal;float: right;">{{.Topic.Status}}</span>
<span class="username" style="border-right: 0;font-weight: normal;float: right;">Status</span>
<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>
@ -21,27 +21,27 @@
</div>
</form>
</div>
<div class="rowblock">
<div class="rowitem passive editable_parent" 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}}">
<span class="hide_on_edit topic_content user_content">{{.Topic.Content}}</span>
<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}}">
<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">{{.Topic.CreatedByName}}</a>
{{if .Topic.Tag}}<a class="username" style="float: right;">{{.Topic.Tag}}</a>{{else if .Topic.URLName}}<a href="{{.Topic.URL}}" class="username" style="color: #505050;float: right;">{{.Topic.URLName}}</a>
<a href="/user/{{.Topic.CreatedBy}}" class="username real_username">{{.Topic.CreatedByName}}</a>
{{if .Topic.Tag}}<a class="username hide_on_micro" style="float: right;">{{.Topic.Tag}}</a>{{else if .Topic.URLName}}<a href="{{.Topic.URL}}" class="username" style="color: #505050;float: right;">{{.Topic.URLName}}</a>
<a class="username" style="color: #505050;float: right;border-right: 0;">{{.Topic.URLPrefix}}</a>{{end}}
</div>
</div><br />
<div class="rowblock" style="overflow: hidden;">
<div class="rowblock post_container" style="overflow: hidden;">
{{range .ItemList}}
<div class="rowitem passive deletable_block editable_parent" 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}}">
<span class="editable_block user_content">{{.ContentHtml}}</span>
<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 />
<a href="/user/{{.CreatedBy}}" class="username">{{.CreatedByName}}</a>
{{if $.CurrentUser.Perms.EditReply}}<a href="/reply/edit/submit/{{.ID}}"><button class="username edit_item">Edit</button></a>{{end}}
{{if $.CurrentUser.Perms.DeleteReply}}<a href="/reply/delete/submit/{{.ID}}"><button class="username delete_item">Delete</button></a>{{end}}
<a href="/report/submit/{{.ID}}?session={{$.CurrentUser.Session}}&type=reply"><button class="username report_item">Report</button></a>
{{if .Tag}}<a class="username" style="float: right;">{{.Tag}}</a>{{else if .URLName}}<a href="{{.URL}}" class="username" style="color: #505050;float: right;" rel="nofollow">{{.URLName}}</a>
<a class="username" style="color: #505050;float: right;border-right: 0;">{{.URLPrefix}}</a>{{end}}
<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>
{{if .CurrentUser.Perms.CreateReply}}

View File

@ -5,8 +5,8 @@
<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}}">
<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 topic_status_e topic_status_open" style="float: right;">open</span>{{end}}
<span class="username" style="border-right: 0;float: right;">Status</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>
</div>
{{else}}<div class="rowitem passive">There aren't any topics yet.</div>{{end}}
</div>