Changed the defaultest default theme to Cosora... For now.

You need the ViewIPs permission to view IPs on logs now.
Added the leftOfNav and rightOfNav docks, more on this soon.
Added a max length for topic titles.
Added a max length for usernames.
Added none as a possible language for the language view counter.
We began adding the notice phrases.
Fixed a misnamed phrase which was spitting out placeholder text.
Localised unknown for the human language phrases.
Moved routeForums to routes.ForumList.
Moved routeRobotsTxt to routes.RobotsTxt.
Started tracking the views for routes.RobotsTxt.
Moved routeSitemapXml to routes.SitemapXml.
Started tracking the views for routes.SitemapXml.
Changed the fallback theme to Cosora.
Fixed changing the default theme to Cosora or Tempra Conflux.
Removed some redundant type definitions in template init.
Return ErrNoTitle instead of ErrNoBody when trying to create a topic with no title.
Moved some in-progress routes and helper functions for handling search engine crawlers to routes/api.go
This commit is contained in:
Azareal 2018-03-17 08:16:43 +00:00
parent 84dbe71bfc
commit b20e295375
38 changed files with 637 additions and 460 deletions

View File

@ -8,6 +8,7 @@ var LangViewCounter *DefaultLangViewCounter
var langCodes = []string{ var langCodes = []string{
"unknown", "unknown",
"none",
"af", "af",
"ar", "ar",
"az", "az",

View File

@ -46,6 +46,7 @@ type LanguagePack struct {
OperatingSystems map[string]string OperatingSystems map[string]string
HumanLanguages map[string]string HumanLanguages map[string]string
Errors map[string]map[string]string // map[category]map[name]value Errors map[string]map[string]string // map[category]map[name]value
NoticePhrases map[string]string
PageTitles map[string]string PageTitles map[string]string
TmplPhrases map[string]string TmplPhrases map[string]string
CSSPhrases map[string]string CSSPhrases map[string]string
@ -206,6 +207,14 @@ func GetErrorPhrase(category string, name string) string {
return res return res
} }
func GetNoticePhrase(name string) string {
res, ok := currentLangPack.Load().(*LanguagePack).NoticePhrases[name]
if !ok {
return getPhrasePlaceholder("notices", name)
}
return res
}
func GetTitlePhrase(name string) string { func GetTitlePhrase(name string) string {
res, ok := currentLangPack.Load().(*LanguagePack).PageTitles[name] res, ok := currentLangPack.Load().(*LanguagePack).PageTitles[name]
if !ok { if !ok {

View File

@ -215,10 +215,10 @@ func userCheck(w http.ResponseWriter, r *http.Request, user *User) (headerVars *
} }
if user.IsBanned { if user.IsBanned {
headerVars.NoticeList = append(headerVars.NoticeList, "Your account has been suspended. Some of your permissions may have been revoked.") headerVars.NoticeList = append(headerVars.NoticeList, GetNoticePhrase("account_banned"))
} }
if user.Loggedin && !user.Active { if user.Loggedin && !user.Active {
headerVars.NoticeList = append(headerVars.NoticeList, "Your account hasn't been activated yet. Some features may remain unavailable until it is.") headerVars.NoticeList = append(headerVars.NoticeList, GetNoticePhrase("account_inactive"))
} }
if len(theme.Resources) > 0 { if len(theme.Resources) > 0 {

View File

@ -69,8 +69,10 @@ type config struct {
MinifyTemplates bool MinifyTemplates bool
ServerCount int ServerCount int
Noavatar string // ? - Move this into the settings table? Noavatar string // ? - Move this into the settings table?
ItemsPerPage int // ? - Move this into the settings table? ItemsPerPage int // ? - Move this into the settings table?
MaxTopicTitleLength int
MaxUsernameLength int
} }
type devConfig struct { type devConfig struct {
@ -90,6 +92,15 @@ func ProcessConfig() error {
Site.URL = strings.TrimSuffix(Site.URL, ":") Site.URL = strings.TrimSuffix(Site.URL, ":")
Site.URL = Site.URL + ":" + Site.Port Site.URL = Site.URL + ":" + Site.Port
} }
// ? Find a way of making these unlimited if zero? It might rule out some optimisations, waste memory, and break layouts
if Config.MaxTopicTitleLength == 0 {
Config.MaxTopicTitleLength = 100
}
if Config.MaxUsernameLength == 0 {
Config.MaxUsernameLength = 100
}
// We need this in here rather than verifyConfig as switchToTestDB() currently overwrites the values it verifies // We need this in here rather than verifyConfig as switchToTestDB() currently overwrites the values it verifies
if DbConfig.TestDbname == DbConfig.Dbname { if DbConfig.TestDbname == DbConfig.Dbname {
return errors.New("Your test database can't have the same name as your production database") return errors.New("Your test database can't have the same name as your production database")
@ -107,6 +118,12 @@ func VerifyConfig() error {
if Config.ServerCount < 1 { if Config.ServerCount < 1 {
return errors.New("You can't have less than one server") return errors.New("You can't have less than one server")
} }
if Config.MaxTopicTitleLength > 100 {
return errors.New("The max topic title length cannot be over 100 as that's unable to fit in the database row")
}
if Config.MaxUsernameLength > 100 {
return errors.New("The max username length cannot be over 100 as that's unable to fit in the database row")
}
return nil return nil
} }

View File

@ -34,11 +34,11 @@ func interpreted_topic_template(pi TopicPage, w http.ResponseWriter) error {
} }
// nolint // nolint
var Template_topic_handle func(TopicPage, http.ResponseWriter) error = interpreted_topic_template var Template_topic_handle = interpreted_topic_template
var Template_topic_alt_handle func(TopicPage, http.ResponseWriter) error = interpreted_topic_template var Template_topic_alt_handle = interpreted_topic_template
// nolint // nolint
var Template_topics_handle func(TopicsPage, http.ResponseWriter) error = func(pi TopicsPage, w http.ResponseWriter) error { var Template_topics_handle = func(pi TopicsPage, w http.ResponseWriter) error {
mapping, ok := Themes[DefaultThemeBox.Load().(string)].TemplatesMap["topics"] mapping, ok := Themes[DefaultThemeBox.Load().(string)].TemplatesMap["topics"]
if !ok { if !ok {
mapping = "topics" mapping = "topics"
@ -47,7 +47,7 @@ var Template_topics_handle func(TopicsPage, http.ResponseWriter) error = func(pi
} }
// nolint // nolint
var Template_forum_handle func(ForumPage, http.ResponseWriter) error = func(pi ForumPage, w http.ResponseWriter) error { var Template_forum_handle = func(pi ForumPage, w http.ResponseWriter) error {
mapping, ok := Themes[DefaultThemeBox.Load().(string)].TemplatesMap["forum"] mapping, ok := Themes[DefaultThemeBox.Load().(string)].TemplatesMap["forum"]
if !ok { if !ok {
mapping = "forum" mapping = "forum"
@ -56,7 +56,7 @@ var Template_forum_handle func(ForumPage, http.ResponseWriter) error = func(pi F
} }
// nolint // nolint
var Template_forums_handle func(ForumsPage, http.ResponseWriter) error = func(pi ForumsPage, w http.ResponseWriter) error { var Template_forums_handle = func(pi ForumsPage, w http.ResponseWriter) error {
mapping, ok := Themes[DefaultThemeBox.Load().(string)].TemplatesMap["forums"] mapping, ok := Themes[DefaultThemeBox.Load().(string)].TemplatesMap["forums"]
if !ok { if !ok {
mapping = "forums" mapping = "forums"
@ -65,7 +65,7 @@ var Template_forums_handle func(ForumsPage, http.ResponseWriter) error = func(pi
} }
// nolint // nolint
var Template_profile_handle func(ProfilePage, http.ResponseWriter) error = func(pi ProfilePage, w http.ResponseWriter) error { var Template_profile_handle = func(pi ProfilePage, w http.ResponseWriter) error {
mapping, ok := Themes[DefaultThemeBox.Load().(string)].TemplatesMap["profile"] mapping, ok := Themes[DefaultThemeBox.Load().(string)].TemplatesMap["profile"]
if !ok { if !ok {
mapping = "profile" mapping = "profile"
@ -74,7 +74,7 @@ var Template_profile_handle func(ProfilePage, http.ResponseWriter) error = func(
} }
// nolint // nolint
var Template_create_topic_handle func(CreateTopicPage, http.ResponseWriter) error = func(pi CreateTopicPage, w http.ResponseWriter) error { var Template_create_topic_handle = func(pi CreateTopicPage, w http.ResponseWriter) error {
mapping, ok := Themes[DefaultThemeBox.Load().(string)].TemplatesMap["create_topic"] mapping, ok := Themes[DefaultThemeBox.Load().(string)].TemplatesMap["create_topic"]
if !ok { if !ok {
mapping = "create_topic" mapping = "create_topic"
@ -83,7 +83,7 @@ var Template_create_topic_handle func(CreateTopicPage, http.ResponseWriter) erro
} }
// nolint // nolint
var Template_login_handle func(Page, http.ResponseWriter) error = func(pi Page, w http.ResponseWriter) error { var Template_login_handle = func(pi Page, w http.ResponseWriter) error {
mapping, ok := Themes[DefaultThemeBox.Load().(string)].TemplatesMap["login"] mapping, ok := Themes[DefaultThemeBox.Load().(string)].TemplatesMap["login"]
if !ok { if !ok {
mapping = "login" mapping = "login"
@ -92,7 +92,7 @@ var Template_login_handle func(Page, http.ResponseWriter) error = func(pi Page,
} }
// nolint // nolint
var Template_register_handle func(Page, http.ResponseWriter) error = func(pi Page, w http.ResponseWriter) error { var Template_register_handle = func(pi Page, w http.ResponseWriter) error {
mapping, ok := Themes[DefaultThemeBox.Load().(string)].TemplatesMap["register"] mapping, ok := Themes[DefaultThemeBox.Load().(string)].TemplatesMap["register"]
if !ok { if !ok {
mapping = "register" mapping = "register"
@ -101,7 +101,7 @@ var Template_register_handle func(Page, http.ResponseWriter) error = func(pi Pag
} }
// nolint // nolint
var Template_error_handle func(Page, http.ResponseWriter) error = func(pi Page, w http.ResponseWriter) error { var Template_error_handle = func(pi Page, w http.ResponseWriter) error {
mapping, ok := Themes[DefaultThemeBox.Load().(string)].TemplatesMap["error"] mapping, ok := Themes[DefaultThemeBox.Load().(string)].TemplatesMap["error"]
if !ok { if !ok {
mapping = "error" mapping = "error"
@ -110,7 +110,7 @@ var Template_error_handle func(Page, http.ResponseWriter) error = func(pi Page,
} }
// nolint // nolint
var Template_ip_search_handle func(IPSearchPage, http.ResponseWriter) error = func(pi IPSearchPage, w http.ResponseWriter) error { var Template_ip_search_handle = func(pi IPSearchPage, w http.ResponseWriter) error {
mapping, ok := Themes[DefaultThemeBox.Load().(string)].TemplatesMap["ip_search"] mapping, ok := Themes[DefaultThemeBox.Load().(string)].TemplatesMap["ip_search"]
if !ok { if !ok {
mapping = "ip_search" mapping = "ip_search"

View File

@ -29,7 +29,7 @@ var DefaultThemeBox atomic.Value
var ChangeDefaultThemeMutex sync.Mutex var ChangeDefaultThemeMutex sync.Mutex
// TODO: Use this when the default theme doesn't exist // TODO: Use this when the default theme doesn't exist
var fallbackTheme = "shadow" var fallbackTheme = "cosora"
var overridenTemplates = make(map[string]bool) var overridenTemplates = make(map[string]bool)
type Theme struct { type Theme struct {
@ -270,72 +270,72 @@ func (theme *Theme) MapTemplates() {
} }
switch dTmplPtr := destTmplPtr.(type) { switch dTmplPtr := destTmplPtr.(type) {
case *func(TopicPage, http.ResponseWriter): case *func(TopicPage, http.ResponseWriter) error:
switch sTmplPtr := sourceTmplPtr.(type) { switch sTmplPtr := sourceTmplPtr.(type) {
case *func(TopicPage, http.ResponseWriter): case *func(TopicPage, http.ResponseWriter) error:
//overridenTemplates[themeTmpl.Name] = d_tmpl_ptr //overridenTemplates[themeTmpl.Name] = d_tmpl_ptr
overridenTemplates[themeTmpl.Name] = true overridenTemplates[themeTmpl.Name] = true
*dTmplPtr = *sTmplPtr *dTmplPtr = *sTmplPtr
default: default:
LogError(errors.New("The source and destination templates are incompatible")) LogError(errors.New("The source and destination templates are incompatible"))
} }
case *func(TopicsPage, http.ResponseWriter): case *func(TopicsPage, http.ResponseWriter) error:
switch sTmplPtr := sourceTmplPtr.(type) { switch sTmplPtr := sourceTmplPtr.(type) {
case *func(TopicsPage, http.ResponseWriter): case *func(TopicsPage, http.ResponseWriter) error:
//overridenTemplates[themeTmpl.Name] = d_tmpl_ptr //overridenTemplates[themeTmpl.Name] = d_tmpl_ptr
overridenTemplates[themeTmpl.Name] = true overridenTemplates[themeTmpl.Name] = true
*dTmplPtr = *sTmplPtr *dTmplPtr = *sTmplPtr
default: default:
LogError(errors.New("The source and destination templates are incompatible")) LogError(errors.New("The source and destination templates are incompatible"))
} }
case *func(ForumPage, http.ResponseWriter): case *func(ForumPage, http.ResponseWriter) error:
switch sTmplPtr := sourceTmplPtr.(type) { switch sTmplPtr := sourceTmplPtr.(type) {
case *func(ForumPage, http.ResponseWriter): case *func(ForumPage, http.ResponseWriter) error:
//overridenTemplates[themeTmpl.Name] = d_tmpl_ptr //overridenTemplates[themeTmpl.Name] = d_tmpl_ptr
overridenTemplates[themeTmpl.Name] = true overridenTemplates[themeTmpl.Name] = true
*dTmplPtr = *sTmplPtr *dTmplPtr = *sTmplPtr
default: default:
LogError(errors.New("The source and destination templates are incompatible")) LogError(errors.New("The source and destination templates are incompatible"))
} }
case *func(ForumsPage, http.ResponseWriter): case *func(ForumsPage, http.ResponseWriter) error:
switch sTmplPtr := sourceTmplPtr.(type) { switch sTmplPtr := sourceTmplPtr.(type) {
case *func(ForumsPage, http.ResponseWriter): case *func(ForumsPage, http.ResponseWriter) error:
//overridenTemplates[themeTmpl.Name] = d_tmpl_ptr //overridenTemplates[themeTmpl.Name] = d_tmpl_ptr
overridenTemplates[themeTmpl.Name] = true overridenTemplates[themeTmpl.Name] = true
*dTmplPtr = *sTmplPtr *dTmplPtr = *sTmplPtr
default: default:
LogError(errors.New("The source and destination templates are incompatible")) LogError(errors.New("The source and destination templates are incompatible"))
} }
case *func(ProfilePage, http.ResponseWriter): case *func(ProfilePage, http.ResponseWriter) error:
switch sTmplPtr := sourceTmplPtr.(type) { switch sTmplPtr := sourceTmplPtr.(type) {
case *func(ProfilePage, http.ResponseWriter): case *func(ProfilePage, http.ResponseWriter) error:
//overridenTemplates[themeTmpl.Name] = d_tmpl_ptr //overridenTemplates[themeTmpl.Name] = d_tmpl_ptr
overridenTemplates[themeTmpl.Name] = true overridenTemplates[themeTmpl.Name] = true
*dTmplPtr = *sTmplPtr *dTmplPtr = *sTmplPtr
default: default:
LogError(errors.New("The source and destination templates are incompatible")) LogError(errors.New("The source and destination templates are incompatible"))
} }
case *func(CreateTopicPage, http.ResponseWriter): case *func(CreateTopicPage, http.ResponseWriter) error:
switch sTmplPtr := sourceTmplPtr.(type) { switch sTmplPtr := sourceTmplPtr.(type) {
case *func(CreateTopicPage, http.ResponseWriter): case *func(CreateTopicPage, http.ResponseWriter) error:
//overridenTemplates[themeTmpl.Name] = d_tmpl_ptr //overridenTemplates[themeTmpl.Name] = d_tmpl_ptr
overridenTemplates[themeTmpl.Name] = true overridenTemplates[themeTmpl.Name] = true
*dTmplPtr = *sTmplPtr *dTmplPtr = *sTmplPtr
default: default:
LogError(errors.New("The source and destination templates are incompatible")) LogError(errors.New("The source and destination templates are incompatible"))
} }
case *func(IPSearchPage, http.ResponseWriter): case *func(IPSearchPage, http.ResponseWriter) error:
switch sTmplPtr := sourceTmplPtr.(type) { switch sTmplPtr := sourceTmplPtr.(type) {
case *func(IPSearchPage, http.ResponseWriter): case *func(IPSearchPage, http.ResponseWriter) error:
//overridenTemplates[themeTmpl.Name] = d_tmpl_ptr //overridenTemplates[themeTmpl.Name] = d_tmpl_ptr
overridenTemplates[themeTmpl.Name] = true overridenTemplates[themeTmpl.Name] = true
*dTmplPtr = *sTmplPtr *dTmplPtr = *sTmplPtr
default: default:
LogError(errors.New("The source and destination templates are incompatible")) LogError(errors.New("The source and destination templates are incompatible"))
} }
case *func(Page, http.ResponseWriter): case *func(Page, http.ResponseWriter) error:
switch sTmplPtr := sourceTmplPtr.(type) { switch sTmplPtr := sourceTmplPtr.(type) {
case *func(Page, http.ResponseWriter): case *func(Page, http.ResponseWriter) error:
//overridenTemplates[themeTmpl.Name] = d_tmpl_ptr //overridenTemplates[themeTmpl.Name] = d_tmpl_ptr
overridenTemplates[themeTmpl.Name] = true overridenTemplates[themeTmpl.Name] = true
*dTmplPtr = *sTmplPtr *dTmplPtr = *sTmplPtr
@ -343,6 +343,8 @@ func (theme *Theme) MapTemplates() {
LogError(errors.New("The source and destination templates are incompatible")) LogError(errors.New("The source and destination templates are incompatible"))
} }
default: default:
log.Print("themeTmpl.Name: ", themeTmpl.Name)
log.Print("themeTmpl.Source: ", themeTmpl.Source)
LogError(errors.New("Unknown destination template type!")) LogError(errors.New("Unknown destination template type!"))
} }
} }
@ -369,63 +371,64 @@ func ResetTemplateOverrides() {
// Not really a pointer, more of a function handle, an artifact from one of the earlier versions of themes.go // Not really a pointer, more of a function handle, an artifact from one of the earlier versions of themes.go
switch oPtr := originPointer.(type) { switch oPtr := originPointer.(type) {
case func(TopicPage, http.ResponseWriter): case func(TopicPage, http.ResponseWriter) error:
switch dPtr := destTmplPtr.(type) { switch dPtr := destTmplPtr.(type) {
case *func(TopicPage, http.ResponseWriter): case *func(TopicPage, http.ResponseWriter) error:
*dPtr = oPtr *dPtr = oPtr
default: default:
LogError(errors.New("The source and destination templates are incompatible")) LogError(errors.New("The source and destination templates are incompatible"))
} }
case func(TopicsPage, http.ResponseWriter): case func(TopicsPage, http.ResponseWriter) error:
switch dPtr := destTmplPtr.(type) { switch dPtr := destTmplPtr.(type) {
case *func(TopicsPage, http.ResponseWriter): case *func(TopicsPage, http.ResponseWriter) error:
*dPtr = oPtr *dPtr = oPtr
default: default:
LogError(errors.New("The source and destination templates are incompatible")) LogError(errors.New("The source and destination templates are incompatible"))
} }
case func(ForumPage, http.ResponseWriter): case func(ForumPage, http.ResponseWriter) error:
switch dPtr := destTmplPtr.(type) { switch dPtr := destTmplPtr.(type) {
case *func(ForumPage, http.ResponseWriter): case *func(ForumPage, http.ResponseWriter) error:
*dPtr = oPtr *dPtr = oPtr
default: default:
LogError(errors.New("The source and destination templates are incompatible")) LogError(errors.New("The source and destination templates are incompatible"))
} }
case func(ForumsPage, http.ResponseWriter): case func(ForumsPage, http.ResponseWriter) error:
switch dPtr := destTmplPtr.(type) { switch dPtr := destTmplPtr.(type) {
case *func(ForumsPage, http.ResponseWriter): case *func(ForumsPage, http.ResponseWriter) error:
*dPtr = oPtr *dPtr = oPtr
default: default:
LogError(errors.New("The source and destination templates are incompatible")) LogError(errors.New("The source and destination templates are incompatible"))
} }
case func(ProfilePage, http.ResponseWriter): case func(ProfilePage, http.ResponseWriter) error:
switch dPtr := destTmplPtr.(type) { switch dPtr := destTmplPtr.(type) {
case *func(ProfilePage, http.ResponseWriter): case *func(ProfilePage, http.ResponseWriter) error:
*dPtr = oPtr *dPtr = oPtr
default: default:
LogError(errors.New("The source and destination templates are incompatible")) LogError(errors.New("The source and destination templates are incompatible"))
} }
case func(CreateTopicPage, http.ResponseWriter): case func(CreateTopicPage, http.ResponseWriter) error:
switch dPtr := destTmplPtr.(type) { switch dPtr := destTmplPtr.(type) {
case *func(CreateTopicPage, http.ResponseWriter): case *func(CreateTopicPage, http.ResponseWriter) error:
*dPtr = oPtr *dPtr = oPtr
default: default:
LogError(errors.New("The source and destination templates are incompatible")) LogError(errors.New("The source and destination templates are incompatible"))
} }
case func(IPSearchPage, http.ResponseWriter): case func(IPSearchPage, http.ResponseWriter) error:
switch dPtr := destTmplPtr.(type) { switch dPtr := destTmplPtr.(type) {
case *func(IPSearchPage, http.ResponseWriter): case *func(IPSearchPage, http.ResponseWriter) error:
*dPtr = oPtr *dPtr = oPtr
default: default:
LogError(errors.New("The source and destination templates are incompatible")) LogError(errors.New("The source and destination templates are incompatible"))
} }
case func(Page, http.ResponseWriter): case func(Page, http.ResponseWriter) error:
switch dPtr := destTmplPtr.(type) { switch dPtr := destTmplPtr.(type) {
case *func(Page, http.ResponseWriter): case *func(Page, http.ResponseWriter) error:
*dPtr = oPtr *dPtr = oPtr
default: default:
LogError(errors.New("The source and destination templates are incompatible")) LogError(errors.New("The source and destination templates are incompatible"))
} }
default: default:
log.Print("name: ", name)
LogError(errors.New("Unknown destination template type!")) LogError(errors.New("Unknown destination template type!"))
} }
log.Print("The template override was reset") log.Print("The template override was reset")
@ -546,3 +549,8 @@ func (theme Theme) HasDock(name string) bool {
} }
return false return false
} }
// TODO: Implement this
func (theme Theme) BuildDock(dock string) (sbody string) {
return ""
}

View File

@ -254,6 +254,17 @@ func (topic *Topic) Delete() error {
// TODO: Write tests for this // TODO: Write tests for this
func (topic *Topic) Update(name string, content string) error { func (topic *Topic) Update(name string, content string) error {
name = html.EscapeString(strings.Replace(html.UnescapeString(name), "\n", "", -1)) name = html.EscapeString(strings.Replace(html.UnescapeString(name), "\n", "", -1))
// TODO: Stop duplicating this logic?
name = strings.TrimSpace(name)
if name == "" {
return ErrNoTitle
}
// ? This number might be a little screwy with Unicode, but it's the only consistent thing we have, as Unicode characters can be any number of bytes in theory?
if len(name) > Config.MaxTopicTitleLength {
return ErrLongTitle
}
content = PreparseMessage(html.UnescapeString(content)) content = PreparseMessage(html.UnescapeString(content))
parsedContent := ParseMessage(content, topic.ParentID, "forums") parsedContent := ParseMessage(content, topic.ParentID, "forums")
_, err := topicStmts.edit.Exec(name, content, parsedContent, topic.ID) _, err := topicStmts.edit.Exec(name, content, parsedContent, topic.ID)

View File

@ -20,6 +20,7 @@ import (
// ? - Should we add stick, lock, unstick, and unlock methods? These might be better on the Topics not the TopicStore // ? - Should we add stick, lock, unstick, and unlock methods? These might be better on the Topics not the TopicStore
var Topics TopicStore var Topics TopicStore
var ErrNoTitle = errors.New("This message is missing a title") var ErrNoTitle = errors.New("This message is missing a title")
var ErrLongTitle = errors.New("The title is too long")
var ErrNoBody = errors.New("This message is missing a body") var ErrNoBody = errors.New("This message is missing a body")
type TopicStore interface { type TopicStore interface {
@ -122,7 +123,11 @@ func (mts *DefaultTopicStore) Exists(id int) bool {
func (mts *DefaultTopicStore) Create(fid int, topicName string, content string, uid int, ipaddress string) (tid int, err error) { func (mts *DefaultTopicStore) Create(fid int, topicName string, content string, uid int, ipaddress string) (tid int, err error) {
topicName = strings.TrimSpace(topicName) topicName = strings.TrimSpace(topicName)
if topicName == "" { if topicName == "" {
return 0, ErrNoBody return 0, ErrNoTitle
}
// ? This number might be a little screwy with Unicode, but it's the only consistent thing we have, as Unicode characters can be any number of bytes in theory?
if len(topicName) > Config.MaxTopicTitleLength {
return 0, ErrLongTitle
} }
content = strings.TrimSpace(content) content = strings.TrimSpace(content)

View File

@ -14,6 +14,7 @@ import (
// TODO: Add some sort of update method // TODO: Add some sort of update method
var Users UserStore var Users UserStore
var ErrAccountExists = errors.New("this username is already in use") var ErrAccountExists = errors.New("this username is already in use")
var ErrLongUsername = errors.New("this username is too long")
type UserStore interface { type UserStore interface {
DirtyGet(id int) *User DirtyGet(id int) *User
@ -203,6 +204,13 @@ func (mus *DefaultUserStore) Exists(id int) bool {
// TODO: Change active to a bool? // TODO: Change active to a bool?
func (mus *DefaultUserStore) Create(username string, password string, email string, group int, active bool) (int, error) { func (mus *DefaultUserStore) Create(username string, password string, email string, group int, active bool) (int, error) {
// TODO: Strip spaces?
// ? This number might be a little screwy with Unicode, but it's the only consistent thing we have, as Unicode characters can be any number of bytes in theory?
if len(username) > Config.MaxUsernameLength {
return 0, ErrLongUsername
}
// Is this username already taken..? // Is this username already taken..?
err := mus.usernameExists.QueryRow(username).Scan(&username) err := mus.usernameExists.QueryRow(username).Scan(&username)
if err != ErrNoRows { if err != ErrNoRows {

View File

@ -16,6 +16,8 @@ var Docks WidgetDocks
var widgetUpdateMutex sync.RWMutex var widgetUpdateMutex sync.RWMutex
type WidgetDocks struct { type WidgetDocks struct {
LeftOfNav []*Widget
RightOfNav []*Widget
LeftSidebar []*Widget LeftSidebar []*Widget
RightSidebar []*Widget RightSidebar []*Widget
//PanelLeft []Menus //PanelLeft []Menus
@ -120,7 +122,18 @@ func BuildWidget(dock string, headerVars *HeaderVars) (sbody string) {
if !headerVars.Theme.HasDock(dock) { if !headerVars.Theme.HasDock(dock) {
return "" return ""
} }
// Let themes forcibly override this slot
sbody = headerVars.Theme.BuildDock(dock)
if sbody != "" {
return sbody
}
switch dock { switch dock {
case "leftOfNav":
widgets = Docks.LeftOfNav
case "rightOfNav":
widgets = Docks.RightOfNav
case "rightSidebar": case "rightSidebar":
widgets = Docks.RightSidebar widgets = Docks.RightSidebar
case "footer": case "footer":
@ -178,8 +191,10 @@ func InitWidgets() error {
defer rows.Close() defer rows.Close()
var data string var data string
var leftWidgets []*Widget var leftOfNavWidgets []*Widget
var rightWidgets []*Widget var rightOfNavWidgets []*Widget
var leftSidebarWidgets []*Widget
var rightSidebarWidgets []*Widget
var footerWidgets []*Widget var footerWidgets []*Widget
for rows.Next() { for rows.Next() {
@ -195,10 +210,14 @@ func InitWidgets() error {
} }
switch widget.Side { switch widget.Side {
case "leftOfNav":
leftOfNavWidgets = append(leftOfNavWidgets, widget)
case "rightOfNav":
rightOfNavWidgets = append(rightOfNavWidgets, widget)
case "left": case "left":
leftWidgets = append(leftWidgets, widget) leftSidebarWidgets = append(leftSidebarWidgets, widget)
case "right": case "right":
rightWidgets = append(rightWidgets, widget) rightSidebarWidgets = append(rightSidebarWidgets, widget)
case "footer": case "footer":
footerWidgets = append(footerWidgets, widget) footerWidgets = append(footerWidgets, widget)
} }
@ -208,12 +227,18 @@ func InitWidgets() error {
return err return err
} }
// TODO: Let themes set default values for widget docks, and let them lock in particular places with their stuff, e.g. leftOfNav and rightOfNav
widgetUpdateMutex.Lock() widgetUpdateMutex.Lock()
Docks.LeftSidebar = leftWidgets Docks.LeftOfNav = leftOfNavWidgets
Docks.RightSidebar = rightWidgets Docks.RightOfNav = rightOfNavWidgets
Docks.LeftSidebar = leftSidebarWidgets
Docks.RightSidebar = rightSidebarWidgets
Docks.Footer = footerWidgets Docks.Footer = footerWidgets
widgetUpdateMutex.Unlock() widgetUpdateMutex.Unlock()
DebugLog("Docks.LeftOfNav", Docks.LeftOfNav)
DebugLog("Docks.RightOfNav", Docks.RightOfNav)
DebugLog("Docks.LeftSidebar", Docks.LeftSidebar) DebugLog("Docks.LeftSidebar", Docks.LeftSidebar)
DebugLog("Docks.RightSidebar", Docks.RightSidebar) DebugLog("Docks.RightSidebar", Docks.RightSidebar)
DebugLog("Docks.Footer", Docks.Footer) DebugLog("Docks.Footer", Docks.Footer)

View File

@ -21,7 +21,7 @@ var RouteMap = map[string]interface{}{
"routeAPI": routeAPI, "routeAPI": routeAPI,
"routes.Overview": routes.Overview, "routes.Overview": routes.Overview,
"routes.CustomPage": routes.CustomPage, "routes.CustomPage": routes.CustomPage,
"routeForums": routeForums, "routes.ForumList": routes.ForumList,
"routes.ViewForum": routes.ViewForum, "routes.ViewForum": routes.ViewForum,
"routeChangeTheme": routeChangeTheme, "routeChangeTheme": routeChangeTheme,
"routeShowAttachment": routeShowAttachment, "routeShowAttachment": routeShowAttachment,
@ -120,6 +120,8 @@ var RouteMap = map[string]interface{}{
"routeDynamic": routeDynamic, "routeDynamic": routeDynamic,
"routeUploads": routeUploads, "routeUploads": routeUploads,
"routes.StaticFile": routes.StaticFile, "routes.StaticFile": routes.StaticFile,
"routes.RobotsTxt": routes.RobotsTxt,
"routes.SitemapXml": routes.SitemapXml,
"BadRoute": BadRoute, "BadRoute": BadRoute,
} }
@ -128,7 +130,7 @@ var routeMapEnum = map[string]int{
"routeAPI": 0, "routeAPI": 0,
"routes.Overview": 1, "routes.Overview": 1,
"routes.CustomPage": 2, "routes.CustomPage": 2,
"routeForums": 3, "routes.ForumList": 3,
"routes.ViewForum": 4, "routes.ViewForum": 4,
"routeChangeTheme": 5, "routeChangeTheme": 5,
"routeShowAttachment": 6, "routeShowAttachment": 6,
@ -227,13 +229,15 @@ var routeMapEnum = map[string]int{
"routeDynamic": 99, "routeDynamic": 99,
"routeUploads": 100, "routeUploads": 100,
"routes.StaticFile": 101, "routes.StaticFile": 101,
"BadRoute": 102, "routes.RobotsTxt": 102,
"routes.SitemapXml": 103,
"BadRoute": 104,
} }
var reverseRouteMapEnum = map[int]string{ var reverseRouteMapEnum = map[int]string{
0: "routeAPI", 0: "routeAPI",
1: "routes.Overview", 1: "routes.Overview",
2: "routes.CustomPage", 2: "routes.CustomPage",
3: "routeForums", 3: "routes.ForumList",
4: "routes.ViewForum", 4: "routes.ViewForum",
5: "routeChangeTheme", 5: "routeChangeTheme",
6: "routeShowAttachment", 6: "routeShowAttachment",
@ -332,7 +336,9 @@ var reverseRouteMapEnum = map[int]string{
99: "routeDynamic", 99: "routeDynamic",
100: "routeUploads", 100: "routeUploads",
101: "routes.StaticFile", 101: "routes.StaticFile",
102: "BadRoute", 102: "routes.RobotsTxt",
103: "routes.SitemapXml",
104: "BadRoute",
} }
var osMapEnum = map[string]int{ var osMapEnum = map[string]int{
"unknown": 0, "unknown": 0,
@ -723,6 +729,8 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
lLang := strings.Split(lang,"-") lLang := strings.Split(lang,"-")
common.DebugDetail("lLang:", lLang) common.DebugDetail("lLang:", lLang)
counters.LangViewCounter.Bump(lLang[0]) counters.LangViewCounter.Bump(lLang[0])
} else {
counters.LangViewCounter.Bump("none")
} }
referrer := req.Header.Get("Referer") // Check the 'referrer' header too? :P referrer := req.Header.Get("Referer") // Check the 'referrer' header too? :P
@ -768,7 +776,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
} }
case "/forums": case "/forums":
counters.RouteViewCounter.Bump(3) counters.RouteViewCounter.Bump(3)
err = routeForums(w,req,user) err = routes.ForumList(w,req,user)
if err != nil { if err != nil {
router.handleError(err,w,req,user) router.handleError(err,w,req,user)
} }
@ -1726,13 +1734,15 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
// TODO: Add support for favicons and robots.txt files // TODO: Add support for favicons and robots.txt files
switch(extraData) { switch(extraData) {
case "robots.txt": case "robots.txt":
err = routeRobotsTxt(w,req) // TODO: Count these views counters.RouteViewCounter.Bump(102)
err = routes.RobotsTxt(w,req)
if err != nil { if err != nil {
router.handleError(err,w,req,user) router.handleError(err,w,req,user)
} }
return return
/*case "sitemap.xml": /*case "sitemap.xml":
err = routeSitemapXml(w,req) // TODO: Count these views counters.RouteViewCounter.Bump(103)
err = routes.SitemapXml(w,req)
if err != nil { if err != nil {
router.handleError(err,w,req,user) router.handleError(err,w,req,user)
} }
@ -1774,7 +1784,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
if strings.Contains(lowerPath,"admin") || strings.Contains(lowerPath,"sql") || strings.Contains(lowerPath,"manage") || strings.Contains(lowerPath,"//") || strings.Contains(lowerPath,"\\\\") || strings.Contains(lowerPath,"wp") || strings.Contains(lowerPath,"wordpress") || strings.Contains(lowerPath,"config") || strings.Contains(lowerPath,"setup") || strings.Contains(lowerPath,"install") || strings.Contains(lowerPath,"update") || strings.Contains(lowerPath,"php") { if strings.Contains(lowerPath,"admin") || strings.Contains(lowerPath,"sql") || strings.Contains(lowerPath,"manage") || strings.Contains(lowerPath,"//") || strings.Contains(lowerPath,"\\\\") || strings.Contains(lowerPath,"wp") || strings.Contains(lowerPath,"wordpress") || strings.Contains(lowerPath,"config") || strings.Contains(lowerPath,"setup") || strings.Contains(lowerPath,"install") || strings.Contains(lowerPath,"update") || strings.Contains(lowerPath,"php") {
router.SuspiciousRequest(req) router.SuspiciousRequest(req)
} }
counters.RouteViewCounter.Bump(102) counters.RouteViewCounter.Bump(104)
common.NotFound(w,req,nil) common.NotFound(w,req,nil)
} }
} }

View File

@ -143,6 +143,8 @@
}, },
"HumanLanguages": { "HumanLanguages": {
"unknown":"Unknown",
"none":"None",
"af":"Afrikaans", "af":"Afrikaans",
"ar":"Arabic", "ar":"Arabic",
"az":"Azeri (Latin)", "az":"Azeri (Latin)",
@ -227,6 +229,11 @@
"zu":"Zulu" "zu":"Zulu"
}, },
"NoticePhrases": {
"account_banned":"Your account has been suspended. Some of your permissions may have been revoked.",
"account_inactive":"Your account hasn't been activated yet. Some features may remain unavailable until it is."
},
"TmplPhrases": { "TmplPhrases": {
"menu_forums_tooltip":"Forum List", "menu_forums_tooltip":"Forum List",
"menu_forums_aria":"The Forum list", "menu_forums_aria":"The Forum list",
@ -304,7 +311,7 @@
"quick_topic_avatar_tooltip":"Your Avatar", "quick_topic_avatar_tooltip":"Your Avatar",
"quick_topic_avatar_alt":"Your Avatar", "quick_topic_avatar_alt":"Your Avatar",
"quick_topic_whatsup":"What's up?", "quick_topic_whatsup":"What's up?",
"quick_topic_placeholder":"Insert post here", "quick_topic_content_placeholder":"Insert post here",
"quick_topic_add_poll_option":"Add new poll option", "quick_topic_add_poll_option":"Add new poll option",
"quick_topic_create_topic_button":"Create Topic", "quick_topic_create_topic_button":"Create Topic",
"quick_topic_add_poll_button":"Add Poll", "quick_topic_add_poll_button":"Add Poll",

View File

@ -116,7 +116,7 @@ func seedTables(adapter qgen.Adapter) error {
qgen.Install.SimpleInsert("settings", "name, content, type", "'bigpost_min_words','250','int'") qgen.Install.SimpleInsert("settings", "name, content, type", "'bigpost_min_words','250','int'")
qgen.Install.SimpleInsert("settings", "name, content, type", "'megapost_min_words','1000','int'") qgen.Install.SimpleInsert("settings", "name, content, type", "'megapost_min_words','1000','int'")
qgen.Install.SimpleInsert("settings", "name, content, type", "'meta_desc','','html-attribute'") qgen.Install.SimpleInsert("settings", "name, content, type", "'meta_desc','','html-attribute'")
qgen.Install.SimpleInsert("themes", "uname, default", "'tempra-simple',1") qgen.Install.SimpleInsert("themes", "uname, default", "'cosora',1")
qgen.Install.SimpleInsert("emails", "email, uid, validated", "'admin@localhost',1,1") // ? - Use a different default email or let the admin input it during installation? qgen.Install.SimpleInsert("emails", "email, uid, validated", "'admin@localhost',1,1") // ? - Use a different default email or let the admin input it during installation?
/* /*

View File

@ -147,7 +147,7 @@ func createTables(adapter qgen.Adapter) error {
qgen.Install.CreateTable("topics", "utf8mb4", "utf8mb4_general_ci", qgen.Install.CreateTable("topics", "utf8mb4", "utf8mb4_general_ci",
[]qgen.DBTableColumn{ []qgen.DBTableColumn{
qgen.DBTableColumn{"tid", "int", 0, false, true, ""}, qgen.DBTableColumn{"tid", "int", 0, false, true, ""},
qgen.DBTableColumn{"title", "varchar", 100, false, false, ""}, qgen.DBTableColumn{"title", "varchar", 100, false, false, ""}, // TODO: Increase the max length to 200?
qgen.DBTableColumn{"content", "text", 0, false, false, ""}, qgen.DBTableColumn{"content", "text", 0, false, false, ""},
qgen.DBTableColumn{"parsed_content", "text", 0, false, false, ""}, qgen.DBTableColumn{"parsed_content", "text", 0, false, false, ""},
qgen.DBTableColumn{"createdAt", "createdAt", 0, false, false, ""}, qgen.DBTableColumn{"createdAt", "createdAt", 0, false, false, ""},

View File

@ -158,6 +158,8 @@ func main() {
mapIt("routeDynamic") mapIt("routeDynamic")
mapIt("routeUploads") mapIt("routeUploads")
mapIt("routes.StaticFile") mapIt("routes.StaticFile")
mapIt("routes.RobotsTxt")
mapIt("routes.SitemapXml")
mapIt("BadRoute") mapIt("BadRoute")
tmplVars.AllRouteNames = allRouteNames tmplVars.AllRouteNames = allRouteNames
tmplVars.AllRouteMap = allRouteMap tmplVars.AllRouteMap = allRouteMap
@ -567,6 +569,8 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
lLang := strings.Split(lang,"-") lLang := strings.Split(lang,"-")
common.DebugDetail("lLang:", lLang) common.DebugDetail("lLang:", lLang)
counters.LangViewCounter.Bump(lLang[0]) counters.LangViewCounter.Bump(lLang[0])
} else {
counters.LangViewCounter.Bump("none")
} }
referrer := req.Header.Get("Referer") // Check the 'referrer' header too? :P referrer := req.Header.Get("Referer") // Check the 'referrer' header too? :P
@ -612,13 +616,15 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
// TODO: Add support for favicons and robots.txt files // TODO: Add support for favicons and robots.txt files
switch(extraData) { switch(extraData) {
case "robots.txt": case "robots.txt":
err = routeRobotsTxt(w,req) // TODO: Count these views counters.RouteViewCounter.Bump({{index .AllRouteMap "routes.RobotsTxt"}})
err = routes.RobotsTxt(w,req)
if err != nil { if err != nil {
router.handleError(err,w,req,user) router.handleError(err,w,req,user)
} }
return return
/*case "sitemap.xml": /*case "sitemap.xml":
err = routeSitemapXml(w,req) // TODO: Count these views counters.RouteViewCounter.Bump({{index .AllRouteMap "routes.SitemapXml"}})
err = routes.SitemapXml(w,req)
if err != nil { if err != nil {
router.handleError(err,w,req,user) router.handleError(err,w,req,user)
} }

View File

@ -5,7 +5,7 @@ func routes() {
addRoute(View("routeAPI", "/api/")) addRoute(View("routeAPI", "/api/"))
addRoute(View("routes.Overview", "/overview/")) addRoute(View("routes.Overview", "/overview/"))
addRoute(View("routes.CustomPage", "/pages/", "extraData")) addRoute(View("routes.CustomPage", "/pages/", "extraData"))
addRoute(View("routeForums", "/forums/" /*,"&forums"*/)) addRoute(View("routes.ForumList", "/forums/" /*,"&forums"*/))
addRoute(View("routes.ViewForum", "/forum/", "extraData")) addRoute(View("routes.ViewForum", "/forum/", "extraData"))
addRoute(AnonAction("routeChangeTheme", "/theme/")) addRoute(AnonAction("routeChangeTheme", "/theme/"))
addRoute( addRoute(

View File

@ -8,7 +8,6 @@ package main
import ( import (
"html" "html"
"log"
"net/http" "net/http"
"strconv" "strconv"
@ -42,60 +41,6 @@ func routeUploads() {
func BadRoute() { func BadRoute() {
} }
func routeForums(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
headerVars, ferr := common.UserCheck(w, r, &user)
if ferr != nil {
return ferr
}
headerVars.Zone = "forums"
headerVars.MetaDesc = headerVars.Settings["meta_desc"].(string)
var err error
var forumList []common.Forum
var canSee []int
if user.IsSuperAdmin {
canSee, err = common.Forums.GetAllVisibleIDs()
if err != nil {
return common.InternalError(err, w, r)
}
} else {
group, err := common.Groups.Get(user.Group)
if err != nil {
log.Printf("Group #%d doesn't exist despite being used by common.User #%d", user.Group, user.ID)
return common.LocalError("Something weird happened", w, r, user)
}
canSee = group.CanSee
}
for _, fid := range canSee {
// Avoid data races by copying the struct into something we can freely mold without worrying about breaking something somewhere else
var forum = common.Forums.DirtyGet(fid).Copy()
if forum.ParentID == 0 && forum.Name != "" && forum.Active {
if forum.LastTopicID != 0 {
if forum.LastTopic.ID != 0 && forum.LastReplyer.ID != 0 {
forum.LastTopicTime = common.RelativeTime(forum.LastTopic.LastReplyAt)
} else {
forum.LastTopicTime = ""
}
} else {
forum.LastTopicTime = ""
}
common.RunHook("forums_frow_assign", &forum)
forumList = append(forumList, forum)
}
}
pi := common.ForumsPage{common.GetTitlePhrase("forums"), user, headerVars, forumList}
if common.RunPreRenderHook("pre_render_forum_list", w, r, &user, &pi) {
return nil
}
err = common.RunThemeTemplate(headerVars.Theme.Name, "forums", pi, w)
if err != nil {
return common.InternalError(err, w, r)
}
return nil
}
// TODO: Set the cookie domain // TODO: Set the cookie domain
func routeChangeTheme(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError { func routeChangeTheme(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
//headerLite, _ := SimpleUserCheck(w, r, &user) //headerLite, _ := SimpleUserCheck(w, r, &user)

View File

@ -4,6 +4,7 @@ import (
"html" "html"
"log" "log"
"net/http" "net/http"
"strconv"
"strings" "strings"
"../common" "../common"
@ -140,6 +141,8 @@ func AccountRegisterSubmit(w http.ResponseWriter, r *http.Request, user common.U
uid, err := common.Users.Create(username, password, email, group, active) uid, err := common.Users.Create(username, password, email, group, active)
if err == common.ErrAccountExists { if err == common.ErrAccountExists {
return common.LocalError("This username isn't available. Try another.", w, r, user) return common.LocalError("This username isn't available. Try another.", w, r, user)
} else if err == common.ErrLongUsername {
return common.LocalError("The username is too long, max: "+strconv.Itoa(common.Config.MaxUsernameLength), w, r, user)
} else if err != nil { } else if err != nil {
return common.InternalError(err, w, r) return common.InternalError(err, w, r)
} }

View File

@ -1,4 +1,4 @@
package main package routes
import ( import (
"errors" "errors"
@ -6,12 +6,12 @@ import (
"strconv" "strconv"
"strings" "strings"
"./common" "../common"
) )
// TODO: Make this a static file somehow? Is it possible for us to put this file somewhere else? // TODO: Make this a static file somehow? Is it possible for us to put this file somewhere else?
// TODO: Add an API so that plugins can register disallowed areas. E.g. /guilds/join for plugin_guilds // TODO: Add an API so that plugins can register disallowed areas. E.g. /guilds/join for plugin_guilds
func routeRobotsTxt(w http.ResponseWriter, r *http.Request) common.RouteError { func RobotsTxt(w http.ResponseWriter, r *http.Request) common.RouteError {
// TODO: Do we have to put * or something at the end of the paths? // TODO: Do we have to put * or something at the end of the paths?
_, _ = w.Write([]byte(`User-agent: * _, _ = w.Write([]byte(`User-agent: *
Disallow: /panel/* Disallow: /panel/*
@ -31,7 +31,7 @@ func writeXMLHeader(w http.ResponseWriter, r *http.Request) {
} }
// TODO: Keep track of when a sitemap was last modifed and add a lastmod element for it // TODO: Keep track of when a sitemap was last modifed and add a lastmod element for it
func routeSitemapXml(w http.ResponseWriter, r *http.Request) common.RouteError { func SitemapXml(w http.ResponseWriter, r *http.Request) common.RouteError {
var sslBit string var sslBit string
if common.Site.EnableSsl { if common.Site.EnableSsl {
sslBit = "s" sslBit = "s"
@ -61,13 +61,13 @@ type FuzzyRoute struct {
// TODO: ^-- Make sure that the API is concurrent // TODO: ^-- Make sure that the API is concurrent
// TODO: Add a social group sitemap // TODO: Add a social group sitemap
var sitemapRoutes = map[string]func(http.ResponseWriter, *http.Request) common.RouteError{ var sitemapRoutes = map[string]func(http.ResponseWriter, *http.Request) common.RouteError{
"forums.xml": routeSitemapForums, "forums.xml": SitemapForums,
"topics.xml": routeSitemapTopics, "topics.xml": SitemapTopics,
} }
// TODO: Use a router capable of parsing this rather than hard-coding the logic in // TODO: Use a router capable of parsing this rather than hard-coding the logic in
var fuzzySitemapRoutes = map[string]FuzzyRoute{ var fuzzySitemapRoutes = map[string]FuzzyRoute{
"topics_page_": FuzzyRoute{"topics_page_(%d).xml", routeSitemapTopic}, "topics_page_": FuzzyRoute{"topics_page_(%d).xml", SitemapTopic},
} }
func sitemapSwitch(w http.ResponseWriter, r *http.Request) common.RouteError { func sitemapSwitch(w http.ResponseWriter, r *http.Request) common.RouteError {
@ -93,7 +93,7 @@ func sitemapSwitch(w http.ResponseWriter, r *http.Request) common.RouteError {
return route(w, r) return route(w, r)
} }
func routeSitemapForums(w http.ResponseWriter, r *http.Request) common.RouteError { func SitemapForums(w http.ResponseWriter, r *http.Request) common.RouteError {
var sslBit string var sslBit string
if common.Site.EnableSsl { if common.Site.EnableSsl {
sslBit = "s" sslBit = "s"
@ -127,7 +127,7 @@ func routeSitemapForums(w http.ResponseWriter, r *http.Request) common.RouteErro
// TODO: Add a global ratelimit. 10 50MB files (smaller if compressed better) per minute? // TODO: Add a global ratelimit. 10 50MB files (smaller if compressed better) per minute?
// ? We might have problems with banned users, if they have fewer ViewTopic permissions than guests as they'll be able to see this list. Then again, a banned user could just logout to see it // ? We might have problems with banned users, if they have fewer ViewTopic permissions than guests as they'll be able to see this list. Then again, a banned user could just logout to see it
func routeSitemapTopics(w http.ResponseWriter, r *http.Request) common.RouteError { func SitemapTopics(w http.ResponseWriter, r *http.Request) common.RouteError {
var sslBit string var sslBit string
if common.Site.EnableSsl { if common.Site.EnableSsl {
sslBit = "s" sslBit = "s"
@ -169,7 +169,7 @@ func routeSitemapTopics(w http.ResponseWriter, r *http.Request) common.RouteErro
return nil return nil
} }
func routeSitemapTopic(w http.ResponseWriter, r *http.Request, page int) common.RouteError { func SitemapTopic(w http.ResponseWriter, r *http.Request, page int) common.RouteError {
/*var sslBit string /*var sslBit string
if common.Site.EnableSsl { if common.Site.EnableSsl {
sslBit = "s" sslBit = "s"
@ -215,7 +215,7 @@ func routeSitemapTopic(w http.ResponseWriter, r *http.Request, page int) common.
return nil return nil
} }
func routeSitemapUsers(w http.ResponseWriter, r *http.Request) common.RouteError { func SitemapUsers(w http.ResponseWriter, r *http.Request) common.RouteError {
writeXMLHeader(w, r) writeXMLHeader(w, r)
w.Write([]byte("<sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n")) w.Write([]byte("<sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n"))
return nil return nil

62
routes/forum_list.go Normal file
View File

@ -0,0 +1,62 @@
package routes
import (
"log"
"net/http"
"../common"
)
func ForumList(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
headerVars, ferr := common.UserCheck(w, r, &user)
if ferr != nil {
return ferr
}
headerVars.Zone = "forums"
headerVars.MetaDesc = headerVars.Settings["meta_desc"].(string)
var err error
var forumList []common.Forum
var canSee []int
if user.IsSuperAdmin {
canSee, err = common.Forums.GetAllVisibleIDs()
if err != nil {
return common.InternalError(err, w, r)
}
} else {
group, err := common.Groups.Get(user.Group)
if err != nil {
log.Printf("Group #%d doesn't exist despite being used by common.User #%d", user.Group, user.ID)
return common.LocalError("Something weird happened", w, r, user)
}
canSee = group.CanSee
}
for _, fid := range canSee {
// Avoid data races by copying the struct into something we can freely mold without worrying about breaking something somewhere else
var forum = common.Forums.DirtyGet(fid).Copy()
if forum.ParentID == 0 && forum.Name != "" && forum.Active {
if forum.LastTopicID != 0 {
if forum.LastTopic.ID != 0 && forum.LastReplyer.ID != 0 {
forum.LastTopicTime = common.RelativeTime(forum.LastTopic.LastReplyAt)
} else {
forum.LastTopicTime = ""
}
} else {
forum.LastTopicTime = ""
}
common.RunHook("forums_frow_assign", &forum)
forumList = append(forumList, forum)
}
}
pi := common.ForumsPage{common.GetTitlePhrase("forums"), user, headerVars, forumList}
if common.RunPreRenderHook("pre_render_forum_list", w, r, &user, &pi) {
return nil
}
err = common.RunThemeTemplate(headerVars.Theme.Name, "forums", pi, w)
if err != nil {
return common.InternalError(err, w, r)
}
return nil
}

View File

@ -304,6 +304,8 @@ func CreateTopicSubmit(w http.ResponseWriter, r *http.Request, user common.User)
return common.LocalError("Something went wrong, perhaps the forum got deleted?", w, r, user) return common.LocalError("Something went wrong, perhaps the forum got deleted?", w, r, user)
case common.ErrNoTitle: case common.ErrNoTitle:
return common.LocalError("This topic doesn't have a title", w, r, user) return common.LocalError("This topic doesn't have a title", w, r, user)
case common.ErrLongTitle:
return common.LocalError("The length of the title is too long, max: "+strconv.Itoa(common.Config.MaxTopicTitleLength), w, r, user)
case common.ErrNoBody: case common.ErrNoBody:
return common.LocalError("This topic doesn't have a body", w, r, user) return common.LocalError("This topic doesn't have a body", w, r, user)
} }
@ -469,7 +471,16 @@ func EditTopicSubmit(w http.ResponseWriter, r *http.Request, user common.User, s
} }
err = topic.Update(r.PostFormValue("topic_name"), r.PostFormValue("topic_content")) err = topic.Update(r.PostFormValue("topic_name"), r.PostFormValue("topic_content"))
// TODO: Avoid duplicating this across this route and the topic creation route
if err != nil { if err != nil {
switch err {
case common.ErrNoTitle:
return common.LocalErrorJSQ("This topic doesn't have a title", w, r, user, isJs)
case common.ErrLongTitle:
return common.LocalErrorJSQ("The length of the title is too long, max: "+strconv.Itoa(common.Config.MaxTopicTitleLength), w, r, user, isJs)
case common.ErrNoBody:
return common.LocalErrorJSQ("This topic doesn't have a body", w, r, user, isJs)
}
return common.InternalErrorJSQ(err, w, r, isJs) return common.InternalErrorJSQ(err, w, r, isJs)
} }

View File

@ -4,7 +4,7 @@ INSERT INTO [settings] ([name],[content],[type],[constraints]) VALUES ('activati
INSERT INTO [settings] ([name],[content],[type]) VALUES ('bigpost_min_words','250','int'); INSERT INTO [settings] ([name],[content],[type]) VALUES ('bigpost_min_words','250','int');
INSERT INTO [settings] ([name],[content],[type]) VALUES ('megapost_min_words','1000','int'); INSERT INTO [settings] ([name],[content],[type]) VALUES ('megapost_min_words','1000','int');
INSERT INTO [settings] ([name],[content],[type]) VALUES ('meta_desc','','html-attribute'); INSERT INTO [settings] ([name],[content],[type]) VALUES ('meta_desc','','html-attribute');
INSERT INTO [themes] ([uname],[default]) VALUES ('tempra-simple',1); INSERT INTO [themes] ([uname],[default]) VALUES ('cosora',1);
INSERT INTO [emails] ([email],[uid],[validated]) VALUES ('admin@localhost',1,1); INSERT INTO [emails] ([email],[uid],[validated]) VALUES ('admin@localhost',1,1);
INSERT INTO [users_groups] ([name],[permissions],[plugin_perms],[is_mod],[is_admin],[tag]) VALUES ('Administrator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserEmail":true,"EditUserPassword":true,"EditUserGroup":true,"EditUserGroupSuperMod":true,"EditUserGroupAdmin":false,"EditGroup":true,"EditGroupLocalPerms":true,"EditGroupGlobalPerms":true,"EditGroupSuperMod":true,"EditGroupAdmin":false,"ManageForums":true,"EditSettings":true,"ManageThemes":true,"ManagePlugins":true,"ViewAdminLogs":true,"ViewIPs":true,"UploadFiles":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,1,'Admin'); INSERT INTO [users_groups] ([name],[permissions],[plugin_perms],[is_mod],[is_admin],[tag]) VALUES ('Administrator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserEmail":true,"EditUserPassword":true,"EditUserGroup":true,"EditUserGroupSuperMod":true,"EditUserGroupAdmin":false,"EditGroup":true,"EditGroupLocalPerms":true,"EditGroupGlobalPerms":true,"EditGroupSuperMod":true,"EditGroupAdmin":false,"ManageForums":true,"EditSettings":true,"ManageThemes":true,"ManagePlugins":true,"ViewAdminLogs":true,"ViewIPs":true,"UploadFiles":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,1,'Admin');
INSERT INTO [users_groups] ([name],[permissions],[plugin_perms],[is_mod],[tag]) VALUES ('Moderator','{"BanUsers":true,"ActivateUsers":false,"EditUser":true,"EditUserEmail":false,"EditUserGroup":true,"ViewIPs":true,"UploadFiles":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,'Mod'); INSERT INTO [users_groups] ([name],[permissions],[plugin_perms],[is_mod],[tag]) VALUES ('Moderator','{"BanUsers":true,"ActivateUsers":false,"EditUser":true,"EditUserEmail":false,"EditUserGroup":true,"ViewIPs":true,"UploadFiles":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,'Mod');

View File

@ -4,7 +4,7 @@ INSERT INTO `settings`(`name`,`content`,`type`,`constraints`) VALUES ('activatio
INSERT INTO `settings`(`name`,`content`,`type`) VALUES ('bigpost_min_words','250','int'); INSERT INTO `settings`(`name`,`content`,`type`) VALUES ('bigpost_min_words','250','int');
INSERT INTO `settings`(`name`,`content`,`type`) VALUES ('megapost_min_words','1000','int'); INSERT INTO `settings`(`name`,`content`,`type`) VALUES ('megapost_min_words','1000','int');
INSERT INTO `settings`(`name`,`content`,`type`) VALUES ('meta_desc','','html-attribute'); INSERT INTO `settings`(`name`,`content`,`type`) VALUES ('meta_desc','','html-attribute');
INSERT INTO `themes`(`uname`,`default`) VALUES ('tempra-simple',1); INSERT INTO `themes`(`uname`,`default`) VALUES ('cosora',1);
INSERT INTO `emails`(`email`,`uid`,`validated`) VALUES ('admin@localhost',1,1); INSERT INTO `emails`(`email`,`uid`,`validated`) VALUES ('admin@localhost',1,1);
INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`,`is_mod`,`is_admin`,`tag`) VALUES ('Administrator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserEmail":true,"EditUserPassword":true,"EditUserGroup":true,"EditUserGroupSuperMod":true,"EditUserGroupAdmin":false,"EditGroup":true,"EditGroupLocalPerms":true,"EditGroupGlobalPerms":true,"EditGroupSuperMod":true,"EditGroupAdmin":false,"ManageForums":true,"EditSettings":true,"ManageThemes":true,"ManagePlugins":true,"ViewAdminLogs":true,"ViewIPs":true,"UploadFiles":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,1,'Admin'); INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`,`is_mod`,`is_admin`,`tag`) VALUES ('Administrator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserEmail":true,"EditUserPassword":true,"EditUserGroup":true,"EditUserGroupSuperMod":true,"EditUserGroupAdmin":false,"EditGroup":true,"EditGroupLocalPerms":true,"EditGroupGlobalPerms":true,"EditGroupSuperMod":true,"EditGroupAdmin":false,"ManageForums":true,"EditSettings":true,"ManageThemes":true,"ManagePlugins":true,"ViewAdminLogs":true,"ViewIPs":true,"UploadFiles":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,1,'Admin');
INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`,`is_mod`,`tag`) VALUES ('Moderator','{"BanUsers":true,"ActivateUsers":false,"EditUser":true,"EditUserEmail":false,"EditUserGroup":true,"ViewIPs":true,"UploadFiles":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,'Mod'); INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`,`is_mod`,`tag`) VALUES ('Moderator','{"BanUsers":true,"ActivateUsers":false,"EditUser":true,"EditUserEmail":false,"EditUserGroup":true,"ViewIPs":true,"UploadFiles":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,'Mod');

View File

@ -3,8 +3,8 @@
// Code generated by Gosora. More below: // Code generated by Gosora. More below:
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */ /* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
package main package main
import "./common"
import "net/http" import "net/http"
import "./common"
var error_tmpl_phrase_id int var error_tmpl_phrase_id int
@ -82,57 +82,61 @@ w.Write(header_frags[15])
} }
w.Write(header_frags[16]) w.Write(header_frags[16])
w.Write(menu_frags[0]) w.Write(menu_frags[0])
w.Write([]byte(common.BuildWidget("leftOfNav",tmpl_error_vars.Header)))
w.Write(menu_frags[1]) w.Write(menu_frags[1])
w.Write([]byte(tmpl_error_vars.Header.Site.ShortName))
w.Write(menu_frags[2]) w.Write(menu_frags[2])
w.Write(phrases[0]) w.Write([]byte(tmpl_error_vars.Header.Site.ShortName))
w.Write(menu_frags[3]) w.Write(menu_frags[3])
w.Write(phrases[1]) w.Write(phrases[0])
w.Write(menu_frags[4]) w.Write(menu_frags[4])
w.Write(phrases[2]) w.Write(phrases[1])
w.Write(menu_frags[5]) w.Write(menu_frags[5])
w.Write(phrases[3]) w.Write(phrases[2])
w.Write(menu_frags[6]) w.Write(menu_frags[6])
w.Write(phrases[4]) w.Write(phrases[3])
w.Write(menu_frags[7]) w.Write(menu_frags[7])
w.Write(phrases[5]) w.Write(phrases[4])
w.Write(menu_frags[8]) w.Write(menu_frags[8])
if tmpl_error_vars.CurrentUser.Loggedin { w.Write(phrases[5])
w.Write(menu_frags[9]) w.Write(menu_frags[9])
w.Write(phrases[6]) if tmpl_error_vars.CurrentUser.Loggedin {
w.Write(menu_frags[10]) w.Write(menu_frags[10])
w.Write(phrases[7]) w.Write(phrases[6])
w.Write(menu_frags[11]) w.Write(menu_frags[11])
w.Write([]byte(tmpl_error_vars.CurrentUser.Link)) w.Write(phrases[7])
w.Write(menu_frags[12]) w.Write(menu_frags[12])
w.Write(phrases[8]) w.Write([]byte(tmpl_error_vars.CurrentUser.Link))
w.Write(menu_frags[13]) w.Write(menu_frags[13])
w.Write(phrases[9]) w.Write(phrases[8])
w.Write(menu_frags[14]) w.Write(menu_frags[14])
w.Write(phrases[10]) w.Write(phrases[9])
w.Write(menu_frags[15]) w.Write(menu_frags[15])
w.Write(phrases[11]) w.Write(phrases[10])
w.Write(menu_frags[16]) w.Write(menu_frags[16])
w.Write([]byte(tmpl_error_vars.CurrentUser.Session)) w.Write(phrases[11])
w.Write(menu_frags[17]) w.Write(menu_frags[17])
w.Write(phrases[12]) w.Write([]byte(tmpl_error_vars.CurrentUser.Session))
w.Write(menu_frags[18]) w.Write(menu_frags[18])
w.Write(phrases[13]) w.Write(phrases[12])
w.Write(menu_frags[19]) w.Write(menu_frags[19])
} else { w.Write(phrases[13])
w.Write(menu_frags[20]) w.Write(menu_frags[20])
w.Write(phrases[14]) } else {
w.Write(menu_frags[21]) w.Write(menu_frags[21])
w.Write(phrases[15]) w.Write(phrases[14])
w.Write(menu_frags[22]) w.Write(menu_frags[22])
w.Write(phrases[16]) w.Write(phrases[15])
w.Write(menu_frags[23]) w.Write(menu_frags[23])
w.Write(phrases[17]) w.Write(phrases[16])
w.Write(menu_frags[24]) w.Write(menu_frags[24])
} w.Write(phrases[17])
w.Write(menu_frags[25]) w.Write(menu_frags[25])
w.Write(phrases[18]) }
w.Write(menu_frags[26]) w.Write(menu_frags[26])
w.Write(phrases[18])
w.Write(menu_frags[27])
w.Write([]byte(common.BuildWidget("rightOfNav",tmpl_error_vars.Header)))
w.Write(menu_frags[28])
w.Write(header_frags[17]) w.Write(header_frags[17])
if tmpl_error_vars.Header.Widgets.RightSidebar != "" { if tmpl_error_vars.Header.Widgets.RightSidebar != "" {
w.Write(header_frags[18]) w.Write(header_frags[18])

View File

@ -3,9 +3,9 @@
// Code generated by Gosora. More below: // Code generated by Gosora. More below:
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */ /* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
package main package main
import "strconv"
import "net/http" import "net/http"
import "./common" import "./common"
import "strconv"
var forum_tmpl_phrase_id int var forum_tmpl_phrase_id int
@ -115,57 +115,61 @@ w.Write(header_frags[15])
} }
w.Write(header_frags[16]) w.Write(header_frags[16])
w.Write(menu_frags[0]) w.Write(menu_frags[0])
w.Write([]byte(common.BuildWidget("leftOfNav",tmpl_forum_vars.Header)))
w.Write(menu_frags[1]) w.Write(menu_frags[1])
w.Write([]byte(tmpl_forum_vars.Header.Site.ShortName))
w.Write(menu_frags[2]) w.Write(menu_frags[2])
w.Write(phrases[0]) w.Write([]byte(tmpl_forum_vars.Header.Site.ShortName))
w.Write(menu_frags[3]) w.Write(menu_frags[3])
w.Write(phrases[1]) w.Write(phrases[0])
w.Write(menu_frags[4]) w.Write(menu_frags[4])
w.Write(phrases[2]) w.Write(phrases[1])
w.Write(menu_frags[5]) w.Write(menu_frags[5])
w.Write(phrases[3]) w.Write(phrases[2])
w.Write(menu_frags[6]) w.Write(menu_frags[6])
w.Write(phrases[4]) w.Write(phrases[3])
w.Write(menu_frags[7]) w.Write(menu_frags[7])
w.Write(phrases[5]) w.Write(phrases[4])
w.Write(menu_frags[8]) w.Write(menu_frags[8])
if tmpl_forum_vars.CurrentUser.Loggedin { w.Write(phrases[5])
w.Write(menu_frags[9]) w.Write(menu_frags[9])
w.Write(phrases[6]) if tmpl_forum_vars.CurrentUser.Loggedin {
w.Write(menu_frags[10]) w.Write(menu_frags[10])
w.Write(phrases[7]) w.Write(phrases[6])
w.Write(menu_frags[11]) w.Write(menu_frags[11])
w.Write([]byte(tmpl_forum_vars.CurrentUser.Link)) w.Write(phrases[7])
w.Write(menu_frags[12]) w.Write(menu_frags[12])
w.Write(phrases[8]) w.Write([]byte(tmpl_forum_vars.CurrentUser.Link))
w.Write(menu_frags[13]) w.Write(menu_frags[13])
w.Write(phrases[9]) w.Write(phrases[8])
w.Write(menu_frags[14]) w.Write(menu_frags[14])
w.Write(phrases[10]) w.Write(phrases[9])
w.Write(menu_frags[15]) w.Write(menu_frags[15])
w.Write(phrases[11]) w.Write(phrases[10])
w.Write(menu_frags[16]) w.Write(menu_frags[16])
w.Write([]byte(tmpl_forum_vars.CurrentUser.Session)) w.Write(phrases[11])
w.Write(menu_frags[17]) w.Write(menu_frags[17])
w.Write(phrases[12]) w.Write([]byte(tmpl_forum_vars.CurrentUser.Session))
w.Write(menu_frags[18]) w.Write(menu_frags[18])
w.Write(phrases[13]) w.Write(phrases[12])
w.Write(menu_frags[19]) w.Write(menu_frags[19])
} else { w.Write(phrases[13])
w.Write(menu_frags[20]) w.Write(menu_frags[20])
w.Write(phrases[14]) } else {
w.Write(menu_frags[21]) w.Write(menu_frags[21])
w.Write(phrases[15]) w.Write(phrases[14])
w.Write(menu_frags[22]) w.Write(menu_frags[22])
w.Write(phrases[16]) w.Write(phrases[15])
w.Write(menu_frags[23]) w.Write(menu_frags[23])
w.Write(phrases[17]) w.Write(phrases[16])
w.Write(menu_frags[24]) w.Write(menu_frags[24])
} w.Write(phrases[17])
w.Write(menu_frags[25]) w.Write(menu_frags[25])
w.Write(phrases[18]) }
w.Write(menu_frags[26]) w.Write(menu_frags[26])
w.Write(phrases[18])
w.Write(menu_frags[27])
w.Write([]byte(common.BuildWidget("rightOfNav",tmpl_forum_vars.Header)))
w.Write(menu_frags[28])
w.Write(header_frags[17]) w.Write(header_frags[17])
if tmpl_forum_vars.Header.Widgets.RightSidebar != "" { if tmpl_forum_vars.Header.Widgets.RightSidebar != "" {
w.Write(header_frags[18]) w.Write(header_frags[18])

View File

@ -85,57 +85,61 @@ w.Write(header_frags[15])
} }
w.Write(header_frags[16]) w.Write(header_frags[16])
w.Write(menu_frags[0]) w.Write(menu_frags[0])
w.Write([]byte(common.BuildWidget("leftOfNav",tmpl_forums_vars.Header)))
w.Write(menu_frags[1]) w.Write(menu_frags[1])
w.Write([]byte(tmpl_forums_vars.Header.Site.ShortName))
w.Write(menu_frags[2]) w.Write(menu_frags[2])
w.Write(phrases[0]) w.Write([]byte(tmpl_forums_vars.Header.Site.ShortName))
w.Write(menu_frags[3]) w.Write(menu_frags[3])
w.Write(phrases[1]) w.Write(phrases[0])
w.Write(menu_frags[4]) w.Write(menu_frags[4])
w.Write(phrases[2]) w.Write(phrases[1])
w.Write(menu_frags[5]) w.Write(menu_frags[5])
w.Write(phrases[3]) w.Write(phrases[2])
w.Write(menu_frags[6]) w.Write(menu_frags[6])
w.Write(phrases[4]) w.Write(phrases[3])
w.Write(menu_frags[7]) w.Write(menu_frags[7])
w.Write(phrases[5]) w.Write(phrases[4])
w.Write(menu_frags[8]) w.Write(menu_frags[8])
if tmpl_forums_vars.CurrentUser.Loggedin { w.Write(phrases[5])
w.Write(menu_frags[9]) w.Write(menu_frags[9])
w.Write(phrases[6]) if tmpl_forums_vars.CurrentUser.Loggedin {
w.Write(menu_frags[10]) w.Write(menu_frags[10])
w.Write(phrases[7]) w.Write(phrases[6])
w.Write(menu_frags[11]) w.Write(menu_frags[11])
w.Write([]byte(tmpl_forums_vars.CurrentUser.Link)) w.Write(phrases[7])
w.Write(menu_frags[12]) w.Write(menu_frags[12])
w.Write(phrases[8]) w.Write([]byte(tmpl_forums_vars.CurrentUser.Link))
w.Write(menu_frags[13]) w.Write(menu_frags[13])
w.Write(phrases[9]) w.Write(phrases[8])
w.Write(menu_frags[14]) w.Write(menu_frags[14])
w.Write(phrases[10]) w.Write(phrases[9])
w.Write(menu_frags[15]) w.Write(menu_frags[15])
w.Write(phrases[11]) w.Write(phrases[10])
w.Write(menu_frags[16]) w.Write(menu_frags[16])
w.Write([]byte(tmpl_forums_vars.CurrentUser.Session)) w.Write(phrases[11])
w.Write(menu_frags[17]) w.Write(menu_frags[17])
w.Write(phrases[12]) w.Write([]byte(tmpl_forums_vars.CurrentUser.Session))
w.Write(menu_frags[18]) w.Write(menu_frags[18])
w.Write(phrases[13]) w.Write(phrases[12])
w.Write(menu_frags[19]) w.Write(menu_frags[19])
} else { w.Write(phrases[13])
w.Write(menu_frags[20]) w.Write(menu_frags[20])
w.Write(phrases[14]) } else {
w.Write(menu_frags[21]) w.Write(menu_frags[21])
w.Write(phrases[15]) w.Write(phrases[14])
w.Write(menu_frags[22]) w.Write(menu_frags[22])
w.Write(phrases[16]) w.Write(phrases[15])
w.Write(menu_frags[23]) w.Write(menu_frags[23])
w.Write(phrases[17]) w.Write(phrases[16])
w.Write(menu_frags[24]) w.Write(menu_frags[24])
} w.Write(phrases[17])
w.Write(menu_frags[25]) w.Write(menu_frags[25])
w.Write(phrases[18]) }
w.Write(menu_frags[26]) w.Write(menu_frags[26])
w.Write(phrases[18])
w.Write(menu_frags[27])
w.Write([]byte(common.BuildWidget("rightOfNav",tmpl_forums_vars.Header)))
w.Write(menu_frags[28])
w.Write(header_frags[17]) w.Write(header_frags[17])
if tmpl_forums_vars.Header.Widgets.RightSidebar != "" { if tmpl_forums_vars.Header.Widgets.RightSidebar != "" {
w.Write(header_frags[18]) w.Write(header_frags[18])

View File

@ -3,10 +3,10 @@
// Code generated by Gosora. More below: // Code generated by Gosora. More below:
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */ /* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
package main package main
import "strconv"
import "net/http" import "net/http"
import "./common" import "./common"
import "./extend/guilds/lib" import "./extend/guilds/lib"
import "strconv"
var guilds_guild_list_tmpl_phrase_id int var guilds_guild_list_tmpl_phrase_id int
@ -80,57 +80,61 @@ w.Write(header_frags[15])
} }
w.Write(header_frags[16]) w.Write(header_frags[16])
w.Write(menu_frags[0]) w.Write(menu_frags[0])
w.Write([]byte(common.BuildWidget("leftOfNav",tmpl_guilds_guild_list_vars.Header)))
w.Write(menu_frags[1]) w.Write(menu_frags[1])
w.Write([]byte(tmpl_guilds_guild_list_vars.Header.Site.ShortName))
w.Write(menu_frags[2]) w.Write(menu_frags[2])
w.Write(phrases[0]) w.Write([]byte(tmpl_guilds_guild_list_vars.Header.Site.ShortName))
w.Write(menu_frags[3]) w.Write(menu_frags[3])
w.Write(phrases[1]) w.Write(phrases[0])
w.Write(menu_frags[4]) w.Write(menu_frags[4])
w.Write(phrases[2]) w.Write(phrases[1])
w.Write(menu_frags[5]) w.Write(menu_frags[5])
w.Write(phrases[3]) w.Write(phrases[2])
w.Write(menu_frags[6]) w.Write(menu_frags[6])
w.Write(phrases[4]) w.Write(phrases[3])
w.Write(menu_frags[7]) w.Write(menu_frags[7])
w.Write(phrases[5]) w.Write(phrases[4])
w.Write(menu_frags[8]) w.Write(menu_frags[8])
if tmpl_guilds_guild_list_vars.CurrentUser.Loggedin { w.Write(phrases[5])
w.Write(menu_frags[9]) w.Write(menu_frags[9])
w.Write(phrases[6]) if tmpl_guilds_guild_list_vars.CurrentUser.Loggedin {
w.Write(menu_frags[10]) w.Write(menu_frags[10])
w.Write(phrases[7]) w.Write(phrases[6])
w.Write(menu_frags[11]) w.Write(menu_frags[11])
w.Write([]byte(tmpl_guilds_guild_list_vars.CurrentUser.Link)) w.Write(phrases[7])
w.Write(menu_frags[12]) w.Write(menu_frags[12])
w.Write(phrases[8]) w.Write([]byte(tmpl_guilds_guild_list_vars.CurrentUser.Link))
w.Write(menu_frags[13]) w.Write(menu_frags[13])
w.Write(phrases[9]) w.Write(phrases[8])
w.Write(menu_frags[14]) w.Write(menu_frags[14])
w.Write(phrases[10]) w.Write(phrases[9])
w.Write(menu_frags[15]) w.Write(menu_frags[15])
w.Write(phrases[11]) w.Write(phrases[10])
w.Write(menu_frags[16]) w.Write(menu_frags[16])
w.Write([]byte(tmpl_guilds_guild_list_vars.CurrentUser.Session)) w.Write(phrases[11])
w.Write(menu_frags[17]) w.Write(menu_frags[17])
w.Write(phrases[12]) w.Write([]byte(tmpl_guilds_guild_list_vars.CurrentUser.Session))
w.Write(menu_frags[18]) w.Write(menu_frags[18])
w.Write(phrases[13]) w.Write(phrases[12])
w.Write(menu_frags[19]) w.Write(menu_frags[19])
} else { w.Write(phrases[13])
w.Write(menu_frags[20]) w.Write(menu_frags[20])
w.Write(phrases[14]) } else {
w.Write(menu_frags[21]) w.Write(menu_frags[21])
w.Write(phrases[15]) w.Write(phrases[14])
w.Write(menu_frags[22]) w.Write(menu_frags[22])
w.Write(phrases[16]) w.Write(phrases[15])
w.Write(menu_frags[23]) w.Write(menu_frags[23])
w.Write(phrases[17]) w.Write(phrases[16])
w.Write(menu_frags[24]) w.Write(menu_frags[24])
} w.Write(phrases[17])
w.Write(menu_frags[25]) w.Write(menu_frags[25])
w.Write(phrases[18]) }
w.Write(menu_frags[26]) w.Write(menu_frags[26])
w.Write(phrases[18])
w.Write(menu_frags[27])
w.Write([]byte(common.BuildWidget("rightOfNav",tmpl_guilds_guild_list_vars.Header)))
w.Write(menu_frags[28])
w.Write(header_frags[17]) w.Write(header_frags[17])
if tmpl_guilds_guild_list_vars.Header.Widgets.RightSidebar != "" { if tmpl_guilds_guild_list_vars.Header.Widgets.RightSidebar != "" {
w.Write(header_frags[18]) w.Write(header_frags[18])

View File

@ -84,57 +84,61 @@ w.Write(header_frags[15])
} }
w.Write(header_frags[16]) w.Write(header_frags[16])
w.Write(menu_frags[0]) w.Write(menu_frags[0])
w.Write([]byte(common.BuildWidget("leftOfNav",tmpl_ip_search_vars.Header)))
w.Write(menu_frags[1]) w.Write(menu_frags[1])
w.Write([]byte(tmpl_ip_search_vars.Header.Site.ShortName))
w.Write(menu_frags[2]) w.Write(menu_frags[2])
w.Write(phrases[0]) w.Write([]byte(tmpl_ip_search_vars.Header.Site.ShortName))
w.Write(menu_frags[3]) w.Write(menu_frags[3])
w.Write(phrases[1]) w.Write(phrases[0])
w.Write(menu_frags[4]) w.Write(menu_frags[4])
w.Write(phrases[2]) w.Write(phrases[1])
w.Write(menu_frags[5]) w.Write(menu_frags[5])
w.Write(phrases[3]) w.Write(phrases[2])
w.Write(menu_frags[6]) w.Write(menu_frags[6])
w.Write(phrases[4]) w.Write(phrases[3])
w.Write(menu_frags[7]) w.Write(menu_frags[7])
w.Write(phrases[5]) w.Write(phrases[4])
w.Write(menu_frags[8]) w.Write(menu_frags[8])
if tmpl_ip_search_vars.CurrentUser.Loggedin { w.Write(phrases[5])
w.Write(menu_frags[9]) w.Write(menu_frags[9])
w.Write(phrases[6]) if tmpl_ip_search_vars.CurrentUser.Loggedin {
w.Write(menu_frags[10]) w.Write(menu_frags[10])
w.Write(phrases[7]) w.Write(phrases[6])
w.Write(menu_frags[11]) w.Write(menu_frags[11])
w.Write([]byte(tmpl_ip_search_vars.CurrentUser.Link)) w.Write(phrases[7])
w.Write(menu_frags[12]) w.Write(menu_frags[12])
w.Write(phrases[8]) w.Write([]byte(tmpl_ip_search_vars.CurrentUser.Link))
w.Write(menu_frags[13]) w.Write(menu_frags[13])
w.Write(phrases[9]) w.Write(phrases[8])
w.Write(menu_frags[14]) w.Write(menu_frags[14])
w.Write(phrases[10]) w.Write(phrases[9])
w.Write(menu_frags[15]) w.Write(menu_frags[15])
w.Write(phrases[11]) w.Write(phrases[10])
w.Write(menu_frags[16]) w.Write(menu_frags[16])
w.Write([]byte(tmpl_ip_search_vars.CurrentUser.Session)) w.Write(phrases[11])
w.Write(menu_frags[17]) w.Write(menu_frags[17])
w.Write(phrases[12]) w.Write([]byte(tmpl_ip_search_vars.CurrentUser.Session))
w.Write(menu_frags[18]) w.Write(menu_frags[18])
w.Write(phrases[13]) w.Write(phrases[12])
w.Write(menu_frags[19]) w.Write(menu_frags[19])
} else { w.Write(phrases[13])
w.Write(menu_frags[20]) w.Write(menu_frags[20])
w.Write(phrases[14]) } else {
w.Write(menu_frags[21]) w.Write(menu_frags[21])
w.Write(phrases[15]) w.Write(phrases[14])
w.Write(menu_frags[22]) w.Write(menu_frags[22])
w.Write(phrases[16]) w.Write(phrases[15])
w.Write(menu_frags[23]) w.Write(menu_frags[23])
w.Write(phrases[17]) w.Write(phrases[16])
w.Write(menu_frags[24]) w.Write(menu_frags[24])
} w.Write(phrases[17])
w.Write(menu_frags[25]) w.Write(menu_frags[25])
w.Write(phrases[18]) }
w.Write(menu_frags[26]) w.Write(menu_frags[26])
w.Write(phrases[18])
w.Write(menu_frags[27])
w.Write([]byte(common.BuildWidget("rightOfNav",tmpl_ip_search_vars.Header)))
w.Write(menu_frags[28])
w.Write(header_frags[17]) w.Write(header_frags[17])
if tmpl_ip_search_vars.Header.Widgets.RightSidebar != "" { if tmpl_ip_search_vars.Header.Widgets.RightSidebar != "" {
w.Write(header_frags[18]) w.Write(header_frags[18])

View File

@ -1,21 +1,21 @@
package main package main
var ip_search_frags = make([][]byte,18)
var header_frags = make([][]byte,24) var header_frags = make([][]byte,24)
var paginator_frags = make([][]byte,16)
var footer_frags = make([][]byte,13)
var register_frags = make([][]byte,9)
var forums_frags = make([][]byte,26)
var topics_frags = make([][]byte,94)
var forum_frags = make([][]byte,87)
var login_frags = make([][]byte,8)
var guilds_guild_list_frags = make([][]byte,10)
var topic_alt_frags = make([][]byte,194) var topic_alt_frags = make([][]byte,194)
var profile_comments_row_frags = make([][]byte,51) var profile_comments_row_frags = make([][]byte,51)
var profile_frags = make([][]byte,48) var profile_frags = make([][]byte,48)
var forums_frags = make([][]byte,26)
var forum_frags = make([][]byte,87)
var register_frags = make([][]byte,9)
var menu_frags = make([][]byte,28)
var footer_frags = make([][]byte,13)
var paginator_frags = make([][]byte,16)
var topic_frags = make([][]byte,192)
var topics_frags = make([][]byte,94)
var error_frags = make([][]byte,4) var error_frags = make([][]byte,4)
var guilds_guild_list_frags = make([][]byte,10) var menu_frags = make([][]byte,30)
var login_frags = make([][]byte,8) var topic_frags = make([][]byte,192)
var ip_search_frags = make([][]byte,18)
// nolint // nolint
func init() { func init() {
@ -60,61 +60,64 @@ header_frags[15] = []byte(`.supermod_only { display: none !important; }`)
header_frags[16] = []byte(`</style> header_frags[16] = []byte(`</style>
<div class="container"> <div class="container">
`) `)
menu_frags[0] = []byte(`<nav class="nav"> menu_frags[0] = []byte(`<div class="left_of_nav">`)
menu_frags[1] = []byte(`</div>
<nav class="nav">
<div class="move_left"> <div class="move_left">
<div class="move_right"> <div class="move_right">
<ul>`) <ul>`)
menu_frags[1] = []byte(` menu_frags[2] = []byte(`
<li id="menu_overview" class="menu_left"><a href="/" rel="home">`) <li id="menu_overview" class="menu_left"><a href="/" rel="home">`)
menu_frags[2] = []byte(`</a></li> menu_frags[3] = []byte(`</a></li>
<li id="menu_forums" class="menu_left"><a href="/forums/" aria-label="`) <li id="menu_forums" class="menu_left"><a href="/forums/" aria-label="`)
menu_frags[3] = []byte(`" title="`) menu_frags[4] = []byte(`" title="`)
menu_frags[4] = []byte(`"></a></li> menu_frags[5] = []byte(`"></a></li>
<li class="menu_left menu_topics"><a href="/" aria-label="`) <li class="menu_left menu_topics"><a href="/" aria-label="`)
menu_frags[5] = []byte(`" title="`) menu_frags[6] = []byte(`" title="`)
menu_frags[6] = []byte(`"></a></li> menu_frags[7] = []byte(`"></a></li>
<li id="general_alerts" class="menu_right menu_alerts"> <li id="general_alerts" class="menu_right menu_alerts">
<div class="alert_bell"></div> <div class="alert_bell"></div>
<div class="alert_counter" aria-label="`) <div class="alert_counter" aria-label="`)
menu_frags[7] = []byte(`"></div> menu_frags[8] = []byte(`"></div>
<div class="alert_aftercounter"></div> <div class="alert_aftercounter"></div>
<div class="alertList" aria-label="`) <div class="alertList" aria-label="`)
menu_frags[8] = []byte(`"></div> menu_frags[9] = []byte(`"></div>
</li> </li>
`) `)
menu_frags[9] = []byte(` menu_frags[10] = []byte(`
<li class="menu_left menu_account"><a href="/user/edit/critical/" aria-label="`) <li class="menu_left menu_account"><a href="/user/edit/critical/" aria-label="`)
menu_frags[10] = []byte(`" title="`) menu_frags[11] = []byte(`" title="`)
menu_frags[11] = []byte(`"></a></li> menu_frags[12] = []byte(`"></a></li>
<li class="menu_left menu_profile"><a href="`) <li class="menu_left menu_profile"><a href="`)
menu_frags[12] = []byte(`" aria-label="`) menu_frags[13] = []byte(`" aria-label="`)
menu_frags[13] = []byte(`" title="`) menu_frags[14] = []byte(`" title="`)
menu_frags[14] = []byte(`"></a></li> menu_frags[15] = []byte(`"></a></li>
<li class="menu_left menu_panel menu_account supermod_only"><a href="/panel/" aria-label="`) <li class="menu_left menu_panel menu_account supermod_only"><a href="/panel/" aria-label="`)
menu_frags[15] = []byte(`" title="`) menu_frags[16] = []byte(`" title="`)
menu_frags[16] = []byte(`"></a></li> menu_frags[17] = []byte(`"></a></li>
<li class="menu_left menu_logout"><a href="/accounts/logout/?session=`) <li class="menu_left menu_logout"><a href="/accounts/logout/?session=`)
menu_frags[17] = []byte(`" aria-label="`) menu_frags[18] = []byte(`" aria-label="`)
menu_frags[18] = []byte(`" title="`) menu_frags[19] = []byte(`" title="`)
menu_frags[19] = []byte(`"></a></li> menu_frags[20] = []byte(`"></a></li>
`) `)
menu_frags[20] = []byte(` menu_frags[21] = []byte(`
<li class="menu_left menu_register"><a href="/accounts/create/" aria-label="`) <li class="menu_left menu_register"><a href="/accounts/create/" aria-label="`)
menu_frags[21] = []byte(`" title="`) menu_frags[22] = []byte(`" title="`)
menu_frags[22] = []byte(`"></a></li> menu_frags[23] = []byte(`"></a></li>
<li class="menu_left menu_login"><a href="/accounts/login/" aria-label="`) <li class="menu_left menu_login"><a href="/accounts/login/" aria-label="`)
menu_frags[23] = []byte(`" title="`) menu_frags[24] = []byte(`" title="`)
menu_frags[24] = []byte(`"></a></li> menu_frags[25] = []byte(`"></a></li>
`) `)
menu_frags[25] = []byte(` menu_frags[26] = []byte(`
<li class="menu_left menu_hamburger" title="`) <li class="menu_left menu_hamburger" title="`)
menu_frags[26] = []byte(`"><a></a></li> menu_frags[27] = []byte(`"><a></a></li>
</ul> </ul>
</div> </div>
</div> </div>
<div style="clear: both;"></div> <div style="clear: both;"></div>
</nav> </nav>
`) <div class="right_of_nav">`)
menu_frags[28] = []byte(`</div>`)
header_frags[17] = []byte(` header_frags[17] = []byte(`
<div id="back"><div id="main" `) <div id="back"><div id="main" `)
header_frags[18] = []byte(`class="shrink_main"`) header_frags[18] = []byte(`class="shrink_main"`)

View File

@ -87,57 +87,61 @@ w.Write(header_frags[15])
} }
w.Write(header_frags[16]) w.Write(header_frags[16])
w.Write(menu_frags[0]) w.Write(menu_frags[0])
w.Write([]byte(common.BuildWidget("leftOfNav",tmpl_login_vars.Header)))
w.Write(menu_frags[1]) w.Write(menu_frags[1])
w.Write([]byte(tmpl_login_vars.Header.Site.ShortName))
w.Write(menu_frags[2]) w.Write(menu_frags[2])
w.Write(phrases[0]) w.Write([]byte(tmpl_login_vars.Header.Site.ShortName))
w.Write(menu_frags[3]) w.Write(menu_frags[3])
w.Write(phrases[1]) w.Write(phrases[0])
w.Write(menu_frags[4]) w.Write(menu_frags[4])
w.Write(phrases[2]) w.Write(phrases[1])
w.Write(menu_frags[5]) w.Write(menu_frags[5])
w.Write(phrases[3]) w.Write(phrases[2])
w.Write(menu_frags[6]) w.Write(menu_frags[6])
w.Write(phrases[4]) w.Write(phrases[3])
w.Write(menu_frags[7]) w.Write(menu_frags[7])
w.Write(phrases[5]) w.Write(phrases[4])
w.Write(menu_frags[8]) w.Write(menu_frags[8])
if tmpl_login_vars.CurrentUser.Loggedin { w.Write(phrases[5])
w.Write(menu_frags[9]) w.Write(menu_frags[9])
w.Write(phrases[6]) if tmpl_login_vars.CurrentUser.Loggedin {
w.Write(menu_frags[10]) w.Write(menu_frags[10])
w.Write(phrases[7]) w.Write(phrases[6])
w.Write(menu_frags[11]) w.Write(menu_frags[11])
w.Write([]byte(tmpl_login_vars.CurrentUser.Link)) w.Write(phrases[7])
w.Write(menu_frags[12]) w.Write(menu_frags[12])
w.Write(phrases[8]) w.Write([]byte(tmpl_login_vars.CurrentUser.Link))
w.Write(menu_frags[13]) w.Write(menu_frags[13])
w.Write(phrases[9]) w.Write(phrases[8])
w.Write(menu_frags[14]) w.Write(menu_frags[14])
w.Write(phrases[10]) w.Write(phrases[9])
w.Write(menu_frags[15]) w.Write(menu_frags[15])
w.Write(phrases[11]) w.Write(phrases[10])
w.Write(menu_frags[16]) w.Write(menu_frags[16])
w.Write([]byte(tmpl_login_vars.CurrentUser.Session)) w.Write(phrases[11])
w.Write(menu_frags[17]) w.Write(menu_frags[17])
w.Write(phrases[12]) w.Write([]byte(tmpl_login_vars.CurrentUser.Session))
w.Write(menu_frags[18]) w.Write(menu_frags[18])
w.Write(phrases[13]) w.Write(phrases[12])
w.Write(menu_frags[19]) w.Write(menu_frags[19])
} else { w.Write(phrases[13])
w.Write(menu_frags[20]) w.Write(menu_frags[20])
w.Write(phrases[14]) } else {
w.Write(menu_frags[21]) w.Write(menu_frags[21])
w.Write(phrases[15]) w.Write(phrases[14])
w.Write(menu_frags[22]) w.Write(menu_frags[22])
w.Write(phrases[16]) w.Write(phrases[15])
w.Write(menu_frags[23]) w.Write(menu_frags[23])
w.Write(phrases[17]) w.Write(phrases[16])
w.Write(menu_frags[24]) w.Write(menu_frags[24])
} w.Write(phrases[17])
w.Write(menu_frags[25]) w.Write(menu_frags[25])
w.Write(phrases[18]) }
w.Write(menu_frags[26]) w.Write(menu_frags[26])
w.Write(phrases[18])
w.Write(menu_frags[27])
w.Write([]byte(common.BuildWidget("rightOfNav",tmpl_login_vars.Header)))
w.Write(menu_frags[28])
w.Write(header_frags[17]) w.Write(header_frags[17])
if tmpl_login_vars.Header.Widgets.RightSidebar != "" { if tmpl_login_vars.Header.Widgets.RightSidebar != "" {
w.Write(header_frags[18]) w.Write(header_frags[18])

View File

@ -110,57 +110,61 @@ w.Write(header_frags[15])
} }
w.Write(header_frags[16]) w.Write(header_frags[16])
w.Write(menu_frags[0]) w.Write(menu_frags[0])
w.Write([]byte(common.BuildWidget("leftOfNav",tmpl_profile_vars.Header)))
w.Write(menu_frags[1]) w.Write(menu_frags[1])
w.Write([]byte(tmpl_profile_vars.Header.Site.ShortName))
w.Write(menu_frags[2]) w.Write(menu_frags[2])
w.Write(phrases[0]) w.Write([]byte(tmpl_profile_vars.Header.Site.ShortName))
w.Write(menu_frags[3]) w.Write(menu_frags[3])
w.Write(phrases[1]) w.Write(phrases[0])
w.Write(menu_frags[4]) w.Write(menu_frags[4])
w.Write(phrases[2]) w.Write(phrases[1])
w.Write(menu_frags[5]) w.Write(menu_frags[5])
w.Write(phrases[3]) w.Write(phrases[2])
w.Write(menu_frags[6]) w.Write(menu_frags[6])
w.Write(phrases[4]) w.Write(phrases[3])
w.Write(menu_frags[7]) w.Write(menu_frags[7])
w.Write(phrases[5]) w.Write(phrases[4])
w.Write(menu_frags[8]) w.Write(menu_frags[8])
if tmpl_profile_vars.CurrentUser.Loggedin { w.Write(phrases[5])
w.Write(menu_frags[9]) w.Write(menu_frags[9])
w.Write(phrases[6]) if tmpl_profile_vars.CurrentUser.Loggedin {
w.Write(menu_frags[10]) w.Write(menu_frags[10])
w.Write(phrases[7]) w.Write(phrases[6])
w.Write(menu_frags[11]) w.Write(menu_frags[11])
w.Write([]byte(tmpl_profile_vars.CurrentUser.Link)) w.Write(phrases[7])
w.Write(menu_frags[12]) w.Write(menu_frags[12])
w.Write(phrases[8]) w.Write([]byte(tmpl_profile_vars.CurrentUser.Link))
w.Write(menu_frags[13]) w.Write(menu_frags[13])
w.Write(phrases[9]) w.Write(phrases[8])
w.Write(menu_frags[14]) w.Write(menu_frags[14])
w.Write(phrases[10]) w.Write(phrases[9])
w.Write(menu_frags[15]) w.Write(menu_frags[15])
w.Write(phrases[11]) w.Write(phrases[10])
w.Write(menu_frags[16]) w.Write(menu_frags[16])
w.Write([]byte(tmpl_profile_vars.CurrentUser.Session)) w.Write(phrases[11])
w.Write(menu_frags[17]) w.Write(menu_frags[17])
w.Write(phrases[12]) w.Write([]byte(tmpl_profile_vars.CurrentUser.Session))
w.Write(menu_frags[18]) w.Write(menu_frags[18])
w.Write(phrases[13]) w.Write(phrases[12])
w.Write(menu_frags[19]) w.Write(menu_frags[19])
} else { w.Write(phrases[13])
w.Write(menu_frags[20]) w.Write(menu_frags[20])
w.Write(phrases[14]) } else {
w.Write(menu_frags[21]) w.Write(menu_frags[21])
w.Write(phrases[15]) w.Write(phrases[14])
w.Write(menu_frags[22]) w.Write(menu_frags[22])
w.Write(phrases[16]) w.Write(phrases[15])
w.Write(menu_frags[23]) w.Write(menu_frags[23])
w.Write(phrases[17]) w.Write(phrases[16])
w.Write(menu_frags[24]) w.Write(menu_frags[24])
} w.Write(phrases[17])
w.Write(menu_frags[25]) w.Write(menu_frags[25])
w.Write(phrases[18]) }
w.Write(menu_frags[26]) w.Write(menu_frags[26])
w.Write(phrases[18])
w.Write(menu_frags[27])
w.Write([]byte(common.BuildWidget("rightOfNav",tmpl_profile_vars.Header)))
w.Write(menu_frags[28])
w.Write(header_frags[17]) w.Write(header_frags[17])
if tmpl_profile_vars.Header.Widgets.RightSidebar != "" { if tmpl_profile_vars.Header.Widgets.RightSidebar != "" {
w.Write(header_frags[18]) w.Write(header_frags[18])

View File

@ -88,57 +88,61 @@ w.Write(header_frags[15])
} }
w.Write(header_frags[16]) w.Write(header_frags[16])
w.Write(menu_frags[0]) w.Write(menu_frags[0])
w.Write([]byte(common.BuildWidget("leftOfNav",tmpl_register_vars.Header)))
w.Write(menu_frags[1]) w.Write(menu_frags[1])
w.Write([]byte(tmpl_register_vars.Header.Site.ShortName))
w.Write(menu_frags[2]) w.Write(menu_frags[2])
w.Write(phrases[0]) w.Write([]byte(tmpl_register_vars.Header.Site.ShortName))
w.Write(menu_frags[3]) w.Write(menu_frags[3])
w.Write(phrases[1]) w.Write(phrases[0])
w.Write(menu_frags[4]) w.Write(menu_frags[4])
w.Write(phrases[2]) w.Write(phrases[1])
w.Write(menu_frags[5]) w.Write(menu_frags[5])
w.Write(phrases[3]) w.Write(phrases[2])
w.Write(menu_frags[6]) w.Write(menu_frags[6])
w.Write(phrases[4]) w.Write(phrases[3])
w.Write(menu_frags[7]) w.Write(menu_frags[7])
w.Write(phrases[5]) w.Write(phrases[4])
w.Write(menu_frags[8]) w.Write(menu_frags[8])
if tmpl_register_vars.CurrentUser.Loggedin { w.Write(phrases[5])
w.Write(menu_frags[9]) w.Write(menu_frags[9])
w.Write(phrases[6]) if tmpl_register_vars.CurrentUser.Loggedin {
w.Write(menu_frags[10]) w.Write(menu_frags[10])
w.Write(phrases[7]) w.Write(phrases[6])
w.Write(menu_frags[11]) w.Write(menu_frags[11])
w.Write([]byte(tmpl_register_vars.CurrentUser.Link)) w.Write(phrases[7])
w.Write(menu_frags[12]) w.Write(menu_frags[12])
w.Write(phrases[8]) w.Write([]byte(tmpl_register_vars.CurrentUser.Link))
w.Write(menu_frags[13]) w.Write(menu_frags[13])
w.Write(phrases[9]) w.Write(phrases[8])
w.Write(menu_frags[14]) w.Write(menu_frags[14])
w.Write(phrases[10]) w.Write(phrases[9])
w.Write(menu_frags[15]) w.Write(menu_frags[15])
w.Write(phrases[11]) w.Write(phrases[10])
w.Write(menu_frags[16]) w.Write(menu_frags[16])
w.Write([]byte(tmpl_register_vars.CurrentUser.Session)) w.Write(phrases[11])
w.Write(menu_frags[17]) w.Write(menu_frags[17])
w.Write(phrases[12]) w.Write([]byte(tmpl_register_vars.CurrentUser.Session))
w.Write(menu_frags[18]) w.Write(menu_frags[18])
w.Write(phrases[13]) w.Write(phrases[12])
w.Write(menu_frags[19]) w.Write(menu_frags[19])
} else { w.Write(phrases[13])
w.Write(menu_frags[20]) w.Write(menu_frags[20])
w.Write(phrases[14]) } else {
w.Write(menu_frags[21]) w.Write(menu_frags[21])
w.Write(phrases[15]) w.Write(phrases[14])
w.Write(menu_frags[22]) w.Write(menu_frags[22])
w.Write(phrases[16]) w.Write(phrases[15])
w.Write(menu_frags[23]) w.Write(menu_frags[23])
w.Write(phrases[17]) w.Write(phrases[16])
w.Write(menu_frags[24]) w.Write(menu_frags[24])
} w.Write(phrases[17])
w.Write(menu_frags[25]) w.Write(menu_frags[25])
w.Write(phrases[18]) }
w.Write(menu_frags[26]) w.Write(menu_frags[26])
w.Write(phrases[18])
w.Write(menu_frags[27])
w.Write([]byte(common.BuildWidget("rightOfNav",tmpl_register_vars.Header)))
w.Write(menu_frags[28])
w.Write(header_frags[17]) w.Write(header_frags[17])
if tmpl_register_vars.Header.Widgets.RightSidebar != "" { if tmpl_register_vars.Header.Widgets.RightSidebar != "" {
w.Write(header_frags[18]) w.Write(header_frags[18])

View File

@ -3,9 +3,9 @@
// Code generated by Gosora. More below: // Code generated by Gosora. More below:
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */ /* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
package main package main
import "strconv"
import "net/http" import "net/http"
import "./common" import "./common"
import "strconv"
var topic_tmpl_phrase_id int var topic_tmpl_phrase_id int
@ -141,57 +141,61 @@ w.Write(header_frags[15])
} }
w.Write(header_frags[16]) w.Write(header_frags[16])
w.Write(menu_frags[0]) w.Write(menu_frags[0])
w.Write([]byte(common.BuildWidget("leftOfNav",tmpl_topic_vars.Header)))
w.Write(menu_frags[1]) w.Write(menu_frags[1])
w.Write([]byte(tmpl_topic_vars.Header.Site.ShortName))
w.Write(menu_frags[2]) w.Write(menu_frags[2])
w.Write(phrases[0]) w.Write([]byte(tmpl_topic_vars.Header.Site.ShortName))
w.Write(menu_frags[3]) w.Write(menu_frags[3])
w.Write(phrases[1]) w.Write(phrases[0])
w.Write(menu_frags[4]) w.Write(menu_frags[4])
w.Write(phrases[2]) w.Write(phrases[1])
w.Write(menu_frags[5]) w.Write(menu_frags[5])
w.Write(phrases[3]) w.Write(phrases[2])
w.Write(menu_frags[6]) w.Write(menu_frags[6])
w.Write(phrases[4]) w.Write(phrases[3])
w.Write(menu_frags[7]) w.Write(menu_frags[7])
w.Write(phrases[5]) w.Write(phrases[4])
w.Write(menu_frags[8]) w.Write(menu_frags[8])
if tmpl_topic_vars.CurrentUser.Loggedin { w.Write(phrases[5])
w.Write(menu_frags[9]) w.Write(menu_frags[9])
w.Write(phrases[6]) if tmpl_topic_vars.CurrentUser.Loggedin {
w.Write(menu_frags[10]) w.Write(menu_frags[10])
w.Write(phrases[7]) w.Write(phrases[6])
w.Write(menu_frags[11]) w.Write(menu_frags[11])
w.Write([]byte(tmpl_topic_vars.CurrentUser.Link)) w.Write(phrases[7])
w.Write(menu_frags[12]) w.Write(menu_frags[12])
w.Write(phrases[8]) w.Write([]byte(tmpl_topic_vars.CurrentUser.Link))
w.Write(menu_frags[13]) w.Write(menu_frags[13])
w.Write(phrases[9]) w.Write(phrases[8])
w.Write(menu_frags[14]) w.Write(menu_frags[14])
w.Write(phrases[10]) w.Write(phrases[9])
w.Write(menu_frags[15]) w.Write(menu_frags[15])
w.Write(phrases[11]) w.Write(phrases[10])
w.Write(menu_frags[16]) w.Write(menu_frags[16])
w.Write([]byte(tmpl_topic_vars.CurrentUser.Session)) w.Write(phrases[11])
w.Write(menu_frags[17]) w.Write(menu_frags[17])
w.Write(phrases[12]) w.Write([]byte(tmpl_topic_vars.CurrentUser.Session))
w.Write(menu_frags[18]) w.Write(menu_frags[18])
w.Write(phrases[13]) w.Write(phrases[12])
w.Write(menu_frags[19]) w.Write(menu_frags[19])
} else { w.Write(phrases[13])
w.Write(menu_frags[20]) w.Write(menu_frags[20])
w.Write(phrases[14]) } else {
w.Write(menu_frags[21]) w.Write(menu_frags[21])
w.Write(phrases[15]) w.Write(phrases[14])
w.Write(menu_frags[22]) w.Write(menu_frags[22])
w.Write(phrases[16]) w.Write(phrases[15])
w.Write(menu_frags[23]) w.Write(menu_frags[23])
w.Write(phrases[17]) w.Write(phrases[16])
w.Write(menu_frags[24]) w.Write(menu_frags[24])
} w.Write(phrases[17])
w.Write(menu_frags[25]) w.Write(menu_frags[25])
w.Write(phrases[18]) }
w.Write(menu_frags[26]) w.Write(menu_frags[26])
w.Write(phrases[18])
w.Write(menu_frags[27])
w.Write([]byte(common.BuildWidget("rightOfNav",tmpl_topic_vars.Header)))
w.Write(menu_frags[28])
w.Write(header_frags[17]) w.Write(header_frags[17])
if tmpl_topic_vars.Header.Widgets.RightSidebar != "" { if tmpl_topic_vars.Header.Widgets.RightSidebar != "" {
w.Write(header_frags[18]) w.Write(header_frags[18])

View File

@ -128,57 +128,61 @@ w.Write(header_frags[15])
} }
w.Write(header_frags[16]) w.Write(header_frags[16])
w.Write(menu_frags[0]) w.Write(menu_frags[0])
w.Write([]byte(common.BuildWidget("leftOfNav",tmpl_topic_alt_vars.Header)))
w.Write(menu_frags[1]) w.Write(menu_frags[1])
w.Write([]byte(tmpl_topic_alt_vars.Header.Site.ShortName))
w.Write(menu_frags[2]) w.Write(menu_frags[2])
w.Write(phrases[0]) w.Write([]byte(tmpl_topic_alt_vars.Header.Site.ShortName))
w.Write(menu_frags[3]) w.Write(menu_frags[3])
w.Write(phrases[1]) w.Write(phrases[0])
w.Write(menu_frags[4]) w.Write(menu_frags[4])
w.Write(phrases[2]) w.Write(phrases[1])
w.Write(menu_frags[5]) w.Write(menu_frags[5])
w.Write(phrases[3]) w.Write(phrases[2])
w.Write(menu_frags[6]) w.Write(menu_frags[6])
w.Write(phrases[4]) w.Write(phrases[3])
w.Write(menu_frags[7]) w.Write(menu_frags[7])
w.Write(phrases[5]) w.Write(phrases[4])
w.Write(menu_frags[8]) w.Write(menu_frags[8])
if tmpl_topic_alt_vars.CurrentUser.Loggedin { w.Write(phrases[5])
w.Write(menu_frags[9]) w.Write(menu_frags[9])
w.Write(phrases[6]) if tmpl_topic_alt_vars.CurrentUser.Loggedin {
w.Write(menu_frags[10]) w.Write(menu_frags[10])
w.Write(phrases[7]) w.Write(phrases[6])
w.Write(menu_frags[11]) w.Write(menu_frags[11])
w.Write([]byte(tmpl_topic_alt_vars.CurrentUser.Link)) w.Write(phrases[7])
w.Write(menu_frags[12]) w.Write(menu_frags[12])
w.Write(phrases[8]) w.Write([]byte(tmpl_topic_alt_vars.CurrentUser.Link))
w.Write(menu_frags[13]) w.Write(menu_frags[13])
w.Write(phrases[9]) w.Write(phrases[8])
w.Write(menu_frags[14]) w.Write(menu_frags[14])
w.Write(phrases[10]) w.Write(phrases[9])
w.Write(menu_frags[15]) w.Write(menu_frags[15])
w.Write(phrases[11]) w.Write(phrases[10])
w.Write(menu_frags[16]) w.Write(menu_frags[16])
w.Write([]byte(tmpl_topic_alt_vars.CurrentUser.Session)) w.Write(phrases[11])
w.Write(menu_frags[17]) w.Write(menu_frags[17])
w.Write(phrases[12]) w.Write([]byte(tmpl_topic_alt_vars.CurrentUser.Session))
w.Write(menu_frags[18]) w.Write(menu_frags[18])
w.Write(phrases[13]) w.Write(phrases[12])
w.Write(menu_frags[19]) w.Write(menu_frags[19])
} else { w.Write(phrases[13])
w.Write(menu_frags[20]) w.Write(menu_frags[20])
w.Write(phrases[14]) } else {
w.Write(menu_frags[21]) w.Write(menu_frags[21])
w.Write(phrases[15]) w.Write(phrases[14])
w.Write(menu_frags[22]) w.Write(menu_frags[22])
w.Write(phrases[16]) w.Write(phrases[15])
w.Write(menu_frags[23]) w.Write(menu_frags[23])
w.Write(phrases[17]) w.Write(phrases[16])
w.Write(menu_frags[24]) w.Write(menu_frags[24])
} w.Write(phrases[17])
w.Write(menu_frags[25]) w.Write(menu_frags[25])
w.Write(phrases[18]) }
w.Write(menu_frags[26]) w.Write(menu_frags[26])
w.Write(phrases[18])
w.Write(menu_frags[27])
w.Write([]byte(common.BuildWidget("rightOfNav",tmpl_topic_alt_vars.Header)))
w.Write(menu_frags[28])
w.Write(header_frags[17]) w.Write(header_frags[17])
if tmpl_topic_alt_vars.Header.Widgets.RightSidebar != "" { if tmpl_topic_alt_vars.Header.Widgets.RightSidebar != "" {
w.Write(header_frags[18]) w.Write(header_frags[18])

View File

@ -115,57 +115,61 @@ w.Write(header_frags[15])
} }
w.Write(header_frags[16]) w.Write(header_frags[16])
w.Write(menu_frags[0]) w.Write(menu_frags[0])
w.Write([]byte(common.BuildWidget("leftOfNav",tmpl_topics_vars.Header)))
w.Write(menu_frags[1]) w.Write(menu_frags[1])
w.Write([]byte(tmpl_topics_vars.Header.Site.ShortName))
w.Write(menu_frags[2]) w.Write(menu_frags[2])
w.Write(phrases[0]) w.Write([]byte(tmpl_topics_vars.Header.Site.ShortName))
w.Write(menu_frags[3]) w.Write(menu_frags[3])
w.Write(phrases[1]) w.Write(phrases[0])
w.Write(menu_frags[4]) w.Write(menu_frags[4])
w.Write(phrases[2]) w.Write(phrases[1])
w.Write(menu_frags[5]) w.Write(menu_frags[5])
w.Write(phrases[3]) w.Write(phrases[2])
w.Write(menu_frags[6]) w.Write(menu_frags[6])
w.Write(phrases[4]) w.Write(phrases[3])
w.Write(menu_frags[7]) w.Write(menu_frags[7])
w.Write(phrases[5]) w.Write(phrases[4])
w.Write(menu_frags[8]) w.Write(menu_frags[8])
if tmpl_topics_vars.CurrentUser.Loggedin { w.Write(phrases[5])
w.Write(menu_frags[9]) w.Write(menu_frags[9])
w.Write(phrases[6]) if tmpl_topics_vars.CurrentUser.Loggedin {
w.Write(menu_frags[10]) w.Write(menu_frags[10])
w.Write(phrases[7]) w.Write(phrases[6])
w.Write(menu_frags[11]) w.Write(menu_frags[11])
w.Write([]byte(tmpl_topics_vars.CurrentUser.Link)) w.Write(phrases[7])
w.Write(menu_frags[12]) w.Write(menu_frags[12])
w.Write(phrases[8]) w.Write([]byte(tmpl_topics_vars.CurrentUser.Link))
w.Write(menu_frags[13]) w.Write(menu_frags[13])
w.Write(phrases[9]) w.Write(phrases[8])
w.Write(menu_frags[14]) w.Write(menu_frags[14])
w.Write(phrases[10]) w.Write(phrases[9])
w.Write(menu_frags[15]) w.Write(menu_frags[15])
w.Write(phrases[11]) w.Write(phrases[10])
w.Write(menu_frags[16]) w.Write(menu_frags[16])
w.Write([]byte(tmpl_topics_vars.CurrentUser.Session)) w.Write(phrases[11])
w.Write(menu_frags[17]) w.Write(menu_frags[17])
w.Write(phrases[12]) w.Write([]byte(tmpl_topics_vars.CurrentUser.Session))
w.Write(menu_frags[18]) w.Write(menu_frags[18])
w.Write(phrases[13]) w.Write(phrases[12])
w.Write(menu_frags[19]) w.Write(menu_frags[19])
} else { w.Write(phrases[13])
w.Write(menu_frags[20]) w.Write(menu_frags[20])
w.Write(phrases[14]) } else {
w.Write(menu_frags[21]) w.Write(menu_frags[21])
w.Write(phrases[15]) w.Write(phrases[14])
w.Write(menu_frags[22]) w.Write(menu_frags[22])
w.Write(phrases[16]) w.Write(phrases[15])
w.Write(menu_frags[23]) w.Write(menu_frags[23])
w.Write(phrases[17]) w.Write(phrases[16])
w.Write(menu_frags[24]) w.Write(menu_frags[24])
} w.Write(phrases[17])
w.Write(menu_frags[25]) w.Write(menu_frags[25])
w.Write(phrases[18]) }
w.Write(menu_frags[26]) w.Write(menu_frags[26])
w.Write(phrases[18])
w.Write(menu_frags[27])
w.Write([]byte(common.BuildWidget("rightOfNav",tmpl_topics_vars.Header)))
w.Write(menu_frags[28])
w.Write(header_frags[17]) w.Write(header_frags[17])
if tmpl_topics_vars.Header.Widgets.RightSidebar != "" { if tmpl_topics_vars.Header.Widgets.RightSidebar != "" {
w.Write(header_frags[18]) w.Write(header_frags[18])

View File

@ -1,3 +1,4 @@
<div class="left_of_nav">{{dock "leftOfNav" .Header }}</div>
<nav class="nav"> <nav class="nav">
<div class="move_left"> <div class="move_left">
<div class="move_right"> <div class="move_right">
@ -26,3 +27,4 @@
</div> </div>
<div style="clear: both;"></div> <div style="clear: both;"></div>
</nav> </nav>
<div class="right_of_nav">{{dock "rightOfNav" .Header }}</div>

View File

@ -18,8 +18,8 @@
{{range .Logs}} {{range .Logs}}
<div class="rowitem panel_compactrow"> <div class="rowitem panel_compactrow">
<span style="float: left;"> <span style="float: left;">
<span>{{.Action}}</span><br /> <span>{{.Action}}</span>
<small style="margin-left: 2px;font-size: 12px;">{{.IPAddress}}</small> {{if $.CurrentUser.Perms.ViewIPs}}<br /><small style="margin-left: 2px;font-size: 12px;">{{.IPAddress}}</small>{{end}}
</span> </span>
<span class="to_right"> <span class="to_right">
<span style="font-size: 14px;">{{.DoneAt}}</span> <span style="font-size: 14px;">{{.DoneAt}}</span>

View File

@ -18,8 +18,8 @@
{{range .Logs}} {{range .Logs}}
<div class="rowitem panel_compactrow"> <div class="rowitem panel_compactrow">
<span style="float: left;"> <span style="float: left;">
<span>{{.Action}}</span><br /> <span>{{.Action}}</span>
<small style="margin-left: 2px;font-size: 12px;">{{.IPAddress}}</small> {{if $.CurrentUser.Perms.ViewIPs}}<br /><small style="margin-left: 2px;font-size: 12px;">{{.IPAddress}}</small>{{end}}
</span> </span>
<span class="to_right"> <span class="to_right">
<span style="font-size: 14px;">{{.DoneAt}}</span> <span style="font-size: 14px;">{{.DoneAt}}</span>