diff --git a/pkg/core/types.go b/pkg/core/types.go index cb1d227..6d85ae8 100644 --- a/pkg/core/types.go +++ b/pkg/core/types.go @@ -22,6 +22,23 @@ func (p Pages) Len() int { return len(p) } func (p Pages) Swap(i, j int) { p[i], p[j] = p[j], p[i] } func (p Pages) Less(i, j int) bool { return p[i].StoreTitle < p[j].StoreTitle } +type UpdatedPages []Page + +func (p UpdatedPages) Len() int { return len(p) } +func (p UpdatedPages) Swap(i, j int) { p[i], p[j] = p[j], p[i] } +func (p UpdatedPages) Less(i, j int) bool { return p[i].Updated > p[j].Updated } + +type Section struct { + Section string + Pages UpdatedPages +} + +type Sections []Section + +func (s Sections) Len() int { return len(s) } +func (s Sections) Swap(i, j int) { s[i], s[j] = s[j], s[i] } +func (s Sections) Less(i, j int) bool { return s[i].Section < s[j].Section } + type User struct { Username string Password string diff --git a/pkg/db/helper.go b/pkg/db/helper.go index 5a37810..46ca6f9 100644 --- a/pkg/db/helper.go +++ b/pkg/db/helper.go @@ -8,12 +8,12 @@ import ( ) var reservedUsers = []string{ - "all", "blacklist", "login", "logout", "new", "search", + "sections", "user", "view", "wiki", diff --git a/pkg/db/page.go b/pkg/db/page.go index bb48ba9..3078b3a 100644 --- a/pkg/db/page.go +++ b/pkg/db/page.go @@ -8,6 +8,7 @@ import ( "git.giftfish.de/ston1th/gowiki/pkg/render" "git.giftfish.de/ston1th/gowiki/pkg/store" "sort" + "strings" ) const pagePrefix = "page/" @@ -21,9 +22,42 @@ var ( errDeleteIndexPage = errors.New("db: index page can not be deleted") ) -func (db *DB) GetAllPages(username string) (pages core.Pages) { +func (db *DB) GetAllSections(username string) (sections core.Sections) { + m := make(map[string]core.UpdatedPages) db.store.ForEach(func(k string, _ []byte) error { if trim, ok := hasTrimPrefix(k, pagePrefix); ok { + if trim == core.IndexURI { + return nil + } + p, err := db.getPage(trim, username) + if err == nil { + s := trim[:strings.Index(trim, "/")] + if _, ok := m[s]; !ok { + m[s] = core.UpdatedPages{} + } + m[s] = append(m[s], *p) + } + } + return nil + }) + for s, p := range m { + sort.Sort(p) + l := len(p) + if l > 5 { + l = 5 + } + sections = append(sections, core.Section{s, p[:l]}) + } + sort.Sort(sections) + return +} + +func (db *DB) GetAllSectionPages(section, username string) (pages core.Pages, err error) { + db.store.ForEach(func(k string, _ []byte) error { + if trim, ok := hasTrimPrefix(k, pagePrefix); ok { + if !strings.HasPrefix(trim, section+"/") { + return nil + } if trim == core.IndexURI { return nil } @@ -34,6 +68,10 @@ func (db *DB) GetAllPages(username string) (pages core.Pages) { } return nil }) + if len(pages) == 0 { + err = errPageNotFound + return + } sort.Sort(pages) return } diff --git a/pkg/server/handler.go b/pkg/server/handler.go index 65b514c..4d79fcc 100644 --- a/pkg/server/handler.go +++ b/pkg/server/handler.go @@ -205,14 +205,31 @@ func searchHandler(ctx *Context) { } } -func allHandler(ctx *Context) { - ctx.Template("allHandler") +func sectionsHandler(ctx *Context) { + ctx.Template("sectionsHandler") ctx.Data = webData{ - Title: "All Pages", - BodyTitle: "All Pages", + Title: "All Sections", + BodyTitle: "All Sections", Admin: ctx.Admin(), } - ctx.Data.Data = ctx.Srv.DB.GetAllPages(ctx.User()) + ctx.Data.Data = ctx.Srv.DB.GetAllSections(ctx.User()) + ctx.Exec() +} + +func sectionHandler(ctx *Context) { + ctx.Template("sectionHandler") + section := ctx.Var("section") + ctx.Data = webData{ + Title: section, + BodyTitle: section, + Admin: ctx.Admin(), + } + var err error + ctx.Data.Data, err = ctx.Srv.DB.GetAllSectionPages(section, ctx.User()) + if err != nil { + ctx.NotFound() + return + } ctx.Exec() } diff --git a/pkg/server/routes.go b/pkg/server/routes.go index f6105a9..580f359 100644 --- a/pkg/server/routes.go +++ b/pkg/server/routes.go @@ -24,6 +24,11 @@ var routes = []route{ staticHandler, []string{"GET"}, }, + { + "/sections", + sectionsHandler, + []string{"GET"}, + }, { "/search", searchHandler, @@ -35,11 +40,6 @@ var routes = []route{ pageNewHandler), []string{"GET", "POST"}, }, - { - "/all", - allHandler, - []string{"GET"}, - }, { "/login", loginHandler, @@ -109,6 +109,11 @@ var routes = []route{ pageHandler), []string{"GET"}, }, + { + "/{section:[a-zA-Z0-9]+}", + sectionHandler, + []string{"GET"}, + }, { "/{section:[a-zA-Z0-9]+}/{title:[a-zA-Z0-9+-]+}", pageHandler, diff --git a/pkg/server/templates.go b/pkg/server/templates.go index 5aaeda2..4f898b8 100644 --- a/pkg/server/templates.go +++ b/pkg/server/templates.go @@ -12,37 +12,6 @@ import ( ) const ( - all = `{{define "body"}} - -{{if .Data}} -
-{{$idx0 := index .Data 0}} -{{$owner := $idx0.Owner}} -{{$owner}} -
-
- -
-
-{{$owner}} -
-
- -
-{{end}} -{{end}}` forbidden = `{{define "body"}} +{{end}}` + section = `{{define "body"}} + +{{if .Data}} +
+ +
+{{end}} +{{end}}` + sections = `{{define "body"}} + +{{if .Data}} +
+{{range $index, $item := .Data}} +
+
+ +
+ {{range $page := $item.Pages}} + {{$page.Title}}
+ {{end}} +
+
+
+
+{{end}} +
+{{end}} {{end}}` userDel = `{{define "body"}} {{if .Data}} @@ -499,7 +510,7 @@ const ( Delete {{.Data.Username}}?
-

You are about to delete {{.Data.Username}}.
This will also remove all private pages of this user.

+

You are about to delete user {{.Data.Username}}.
This will also remove all private pages of this user.

@@ -570,6 +581,7 @@ const ( {{end}} {{end}}
+ {{end}} @@ -659,6 +671,7 @@ const ( Back + {{end}}` @@ -695,6 +708,7 @@ const ( Back + {{end}} @@ -838,6 +852,10 @@ html, body, .container, .content { .proper-content { padding-top: 40px; } +.section { + margin-bottom: 20px; + width: 250px; +} .wrapper { min-height: 100%; height: auto !important; @@ -883,7 +901,8 @@ func (s *HTTPServer) loadTemplates() { s.templ["loginHandler"] = parse(index, menu, login) s.templ["loginTotpHandler"] = parse(index, menu, loginTotp) s.templ["searchHandler"] = parse(index, menu, search) - s.templ["allHandler"] = parse(index, menu, all) + s.templ["sectionsHandler"] = parse(index, menu, sections) + s.templ["sectionHandler"] = parse(index, menu, section) s.templ["pageHandler"] = parse(index, menu, page) s.templ["pageNewHandler"] = parse(index, menu, pageNew) s.templ["pageEditHandler"] = parse(index, menu, pageEdit) diff --git a/templates.sh b/templates.sh index 9aca11f..ed93b6c 100755 --- a/templates.sh +++ b/templates.sh @@ -74,7 +74,8 @@ func (s *HTTPServer) loadTemplates() { s.templ["loginHandler"] = parse(index, menu, login) s.templ["loginTotpHandler"] = parse(index, menu, loginTotp) s.templ["searchHandler"] = parse(index, menu, search) - s.templ["allHandler"] = parse(index, menu, all) + s.templ["sectionsHandler"] = parse(index, menu, sections) + s.templ["sectionHandler"] = parse(index, menu, section) s.templ["pageHandler"] = parse(index, menu, page) s.templ["pageNewHandler"] = parse(index, menu, pageNew) s.templ["pageEditHandler"] = parse(index, menu, pageEdit) diff --git a/templates/custom.css b/templates/custom.css index 043109f..5184a9c 100644 --- a/templates/custom.css +++ b/templates/custom.css @@ -125,6 +125,10 @@ html, body, .container, .content { .proper-content { padding-top: 40px; } +.section { + margin-bottom: 20px; + width: 250px; +} .wrapper { min-height: 100%; height: auto !important; diff --git a/templates/index.html b/templates/index.html index e2fb677..a305035 100644 --- a/templates/index.html +++ b/templates/index.html @@ -3,7 +3,7 @@ GoWiki | {{.Title}} - + diff --git a/templates/menu.html b/templates/menu.html index bdd6685..9b599c0 100644 --- a/templates/menu.html +++ b/templates/menu.html @@ -1,7 +1,7 @@ {{define "menu"}}