diff --git a/README.md b/README.md
index 58504fab..7b671ad9 100644
--- a/README.md
+++ b/README.md
@@ -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.
diff --git a/experimental/module_lua.go b/experimental/module_lua.go
new file mode 100644
index 00000000..c85c9ba1
--- /dev/null
+++ b/experimental/module_lua.go
@@ -0,0 +1,3 @@
+/* Copyright Azareal 2016 - 2017 */
+package main
+
diff --git a/experimental/module_ottojs.go b/experimental/module_ottojs.go
new file mode 100644
index 00000000..126ff1c1
--- /dev/null
+++ b/experimental/module_ottojs.go
@@ -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")
+ }
+ }
+}
+
diff --git a/experimental/module_v8js.go b/experimental/module_v8js.go
new file mode 100644
index 00000000..c85c9ba1
--- /dev/null
+++ b/experimental/module_v8js.go
@@ -0,0 +1,3 @@
+/* Copyright Azareal 2016 - 2017 */
+package main
+
diff --git a/experimental/new-replybit.html b/experimental/new-replybit.html
new file mode 100644
index 00000000..94606f6e
--- /dev/null
+++ b/experimental/new-replybit.html
@@ -0,0 +1,14 @@
+
\ No newline at end of file
diff --git a/gosora.exe b/gosora.exe
index 2fd6216a..82e5dbbd 100644
Binary files a/gosora.exe and b/gosora.exe differ
diff --git a/images/layout2-test.PNG b/images/layout2-test.PNG
new file mode 100644
index 00000000..90b20efe
Binary files /dev/null and b/images/layout2-test.PNG differ
diff --git a/images/layout2-test_2.PNG b/images/layout2-test_2.PNG
new file mode 100644
index 00000000..1e15c290
Binary files /dev/null and b/images/layout2-test_2.PNG differ
diff --git a/main.go b/main.go
index 7f4985de..1c694290 100644
--- a/main.go
+++ b/main.go
@@ -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)
diff --git a/mod_routes.go b/mod_routes.go
index 0071c70f..a7855614 100644
--- a/mod_routes.go
+++ b/mod_routes.go
@@ -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)
+}
diff --git a/pages.go b/pages.go
index 2baa6a83..2399ea92 100644
--- a/pages.go
+++ b/pages.go
@@ -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
diff --git a/public/main.css b/public/main.css
index 6fbfc80f..e5039a61 100644
--- a/public/main.css
+++ b/public/main.css
@@ -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;
}
diff --git a/routes.go b/routes.go
index 8168190e..04c34962 100644
--- a/routes.go
+++ b/routes.go
@@ -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)
}
diff --git a/template_forum.go b/template_forum.go
index b698e62f..d734569d 100644
--- a/template_forum.go
+++ b/template_forum.go
@@ -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(`">
` + item.(TopicUser).Title + ` `))
diff --git a/template_profile.go b/template_profile.go
new file mode 100644
index 00000000..5fecd56e
--- /dev/null
+++ b/template_profile.go
@@ -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(`
+
+
+ ` + tmpl_profile_vars.Title + `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ `))
+if tmpl_profile_vars.CurrentUser.Loggedin {
+w.Write([]byte(`
+
+
+ `))
+if tmpl_profile_vars.CurrentUser.Is_Super_Mod {
+w.Write([]byte(``))
+}
+w.Write([]byte(`
+
+ `))
+} else {
+w.Write([]byte(`
+
+
+ `))
+}
+w.Write([]byte(`
+
+
+
+
+
+`))
+if len(tmpl_profile_vars.NoticeList) != 0 {
+for _, item := range tmpl_profile_vars.NoticeList {
+w.Write([]byte(`
` + item + `
`))
+}
+}
+w.Write([]byte(`
+
+
+
+ ` + tmpl_profile_vars.ProfileOwner.Name + ` `))
+if tmpl_profile_vars.ProfileOwner.Tag != "" {
+w.Write([]byte(`` + tmpl_profile_vars.ProfileOwner.Tag + ` `))
+}
+w.Write([]byte(`
+
+
+
Add Friend
+ `))
+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(`
Unban `))
+} else {
+w.Write([]byte(`
Ban `))
+}
+w.Write([]byte(`
+ `))
+}
+w.Write([]byte(`
+
Report
+
+
+
+
+ `))
+if len(tmpl_profile_vars.ItemList) != 0 {
+for _, item := range tmpl_profile_vars.ItemList {
+w.Write([]byte(`
+
`))
+}
+}
+w.Write([]byte(`
+
+`))
+if !tmpl_profile_vars.CurrentUser.Is_Banned {
+w.Write([]byte(`
+
+`))
+}
+w.Write([]byte(`
+
+
+
+`))
+}
diff --git a/template_topic.go b/template_topic.go
index ad5a2225..105852ef 100644
--- a/template_topic.go
+++ b/template_topic.go
@@ -66,6 +66,10 @@ w.Write([]byte(`
-
- `))
+
`))
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(`">
-
` + string(item.ContentHtml) + `
-
+
` + string(item.ContentHtml) + `
` + item.CreatedByName + `
`))
if tmpl_topic_vars.CurrentUser.Perms.EditReply {
@@ -161,11 +163,11 @@ w.Write([]byte(`
`))
+
+`))
}
}
-w.Write([]byte(`
-
+w.Write([]byte(`
`))
if tmpl_topic_vars.CurrentUser.Perms.CreateReply {
w.Write([]byte(`
diff --git a/template_topic_alt.go b/template_topic_alt.go
new file mode 100644
index 00000000..0f7f953a
--- /dev/null
+++ b/template_topic_alt.go
@@ -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(`
+
+
+ ` + tmpl_topic_alt_vars.Title + `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ `))
+if tmpl_topic_alt_vars.CurrentUser.Loggedin {
+w.Write([]byte(`
+
+
+ `))
+if tmpl_topic_alt_vars.CurrentUser.Is_Super_Mod {
+w.Write([]byte(``))
+}
+w.Write([]byte(`
+
+ `))
+} else {
+w.Write([]byte(`
+
+
+ `))
+}
+w.Write([]byte(`
+
+
+
+
+
+`))
+if len(tmpl_topic_alt_vars.NoticeList) != 0 {
+for _, item := range tmpl_topic_alt_vars.NoticeList {
+w.Write([]byte(`
` + item + `
`))
+}
+}
+w.Write([]byte(`
+
+
+
+
` + tmpl_topic_alt_vars.Topic.Title + `
+
` + tmpl_topic_alt_vars.Topic.Status + `
+
Status
+ `))
+if tmpl_topic_alt_vars.CurrentUser.Is_Mod {
+w.Write([]byte(`
+
Edit
+
Delete
+ `))
+if tmpl_topic_alt_vars.Topic.Sticky {
+w.Write([]byte(`
Unpin `))
+} else {
+w.Write([]byte(`
Pin `))
+}
+w.Write([]byte(`
+
+
+
+ open
+ closed
+
+
Update
+ `))
+}
+w.Write([]byte(`
+
Report
+
+
+
+
+
+
+
+
+
` + tmpl_topic_alt_vars.Topic.CreatedByName + `
+
+
+
` + string(tmpl_topic_alt_vars.Topic.Content.(template.HTML)) + `
+
` + string(tmpl_topic_alt_vars.Topic.Content.(template.HTML)) + `
+
+
+ `))
+if len(tmpl_topic_alt_vars.ItemList) != 0 {
+for _, item := range tmpl_topic_alt_vars.ItemList {
+w.Write([]byte(`
+
+
+
+
` + item.CreatedByName + `
+
+
+
` + string(item.ContentHtml) + `
+
+
+
+`))
+}
+}
+w.Write([]byte(`
+`))
+if tmpl_topic_alt_vars.CurrentUser.Perms.CreateReply {
+w.Write([]byte(`
+
+`))
+}
+w.Write([]byte(`
+
+
+
+`))
+}
diff --git a/template_topics.go b/template_topics.go
index 6803a52c..50bd7d88 100644
--- a/template_topics.go
+++ b/template_topics.go
@@ -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(`">
` + item.(TopicUser).Title + ` `))
diff --git a/templates/forum.html b/templates/forum.html
index c9a02e86..619641c3 100644
--- a/templates/forum.html
+++ b/templates/forum.html
@@ -3,7 +3,7 @@
- {{range .ItemList}}
+ {{range .ItemList}}
{{.Title}} {{if .Is_Closed}}
closed
{{else}}
open {{end}}
Status
diff --git a/templates/panel-groups.html b/templates/panel-groups.html
new file mode 100644
index 00000000..efa993ac
--- /dev/null
+++ b/templates/panel-groups.html
@@ -0,0 +1,13 @@
+{{template "header.html" . }}
+{{template "panel-menu.html" . }}
+
+
+ {{range .ItemList}}
+
+ {{end}}
+
+{{template "footer.html" . }}
\ No newline at end of file
diff --git a/templates/profile.html b/templates/profile.html
index c18e6d60..cc0df4d1 100644
--- a/templates/profile.html
+++ b/templates/profile.html
@@ -1,15 +1,15 @@
{{template "header.html" . }}
-
+
- {{.Something.Name}} {{if .Something.Tag}}{{.Something.Tag}} {{end}}
+ {{.ProfileOwner.Name}} {{if .ProfileOwner.Tag}}{{.ProfileOwner.Tag}} {{end}}
Add Friend
- {{if (.CurrentUser.Is_Super_Mod) and not (.Something.Is_Super_Mod) }}
- {{if .Something.Is_Banned }}
Unban {{else}}
Ban {{end}}
+ {{if (.CurrentUser.Is_Super_Mod) and not (.ProfileOwner.Is_Super_Mod) }}
+ {{if .ProfileOwner.Is_Banned }}
Unban {{else}}
Ban {{end}}
{{end}}
-
Report
+
Report
{{end}}
{{if not .CurrentUser.Is_Banned}}
-
+
diff --git a/templates/topic.html b/templates/topic.html
index 39a00e5f..562ed4e1 100644
--- a/templates/topic.html
+++ b/templates/topic.html
@@ -1,7 +1,7 @@
{{template "header.html" . }}
{{if .CurrentUser.Perms.CreateReply}}
diff --git a/templates/topic_alt.html b/templates/topic_alt.html
new file mode 100644
index 00000000..e099ae42
--- /dev/null
+++ b/templates/topic_alt.html
@@ -0,0 +1,65 @@
+{{template "header.html" . }}
+
+
+
+
+
+
+
{{.Topic.CreatedByName}}
+
+
+
{{.Topic.Content}}
+
{{.Topic.Content}}
+
+
+ {{range .ItemList}}
+
+{{end}}
+{{if .CurrentUser.Perms.CreateReply}}
+
+{{end}}
+{{template "footer.html" . }}
\ No newline at end of file
diff --git a/templates/topics.html b/templates/topics.html
index 96f69543..b5bdea20 100644
--- a/templates/topics.html
+++ b/templates/topics.html
@@ -3,7 +3,7 @@
- {{range .ItemList}}
+ {{range .ItemList}}
{{.Title}} {{if .Is_Closed}}
closed
{{else}}
open {{end}}
Status