added sections overview
This commit is contained in:
parent
72d00aeb21
commit
799ff0fb2f
16 changed files with 181 additions and 66 deletions
|
|
@ -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) 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 }
|
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 {
|
type User struct {
|
||||||
Username string
|
Username string
|
||||||
Password string
|
Password string
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,12 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var reservedUsers = []string{
|
var reservedUsers = []string{
|
||||||
"all",
|
|
||||||
"blacklist",
|
"blacklist",
|
||||||
"login",
|
"login",
|
||||||
"logout",
|
"logout",
|
||||||
"new",
|
"new",
|
||||||
"search",
|
"search",
|
||||||
|
"sections",
|
||||||
"user",
|
"user",
|
||||||
"view",
|
"view",
|
||||||
"wiki",
|
"wiki",
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"git.giftfish.de/ston1th/gowiki/pkg/render"
|
"git.giftfish.de/ston1th/gowiki/pkg/render"
|
||||||
"git.giftfish.de/ston1th/gowiki/pkg/store"
|
"git.giftfish.de/ston1th/gowiki/pkg/store"
|
||||||
"sort"
|
"sort"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
const pagePrefix = "page/"
|
const pagePrefix = "page/"
|
||||||
|
|
@ -21,9 +22,42 @@ var (
|
||||||
errDeleteIndexPage = errors.New("db: index page can not be deleted")
|
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 {
|
db.store.ForEach(func(k string, _ []byte) error {
|
||||||
if trim, ok := hasTrimPrefix(k, pagePrefix); ok {
|
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 {
|
if trim == core.IndexURI {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -34,6 +68,10 @@ func (db *DB) GetAllPages(username string) (pages core.Pages) {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
if len(pages) == 0 {
|
||||||
|
err = errPageNotFound
|
||||||
|
return
|
||||||
|
}
|
||||||
sort.Sort(pages)
|
sort.Sort(pages)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -205,14 +205,31 @@ func searchHandler(ctx *Context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func allHandler(ctx *Context) {
|
func sectionsHandler(ctx *Context) {
|
||||||
ctx.Template("allHandler")
|
ctx.Template("sectionsHandler")
|
||||||
ctx.Data = webData{
|
ctx.Data = webData{
|
||||||
Title: "All Pages",
|
Title: "All Sections",
|
||||||
BodyTitle: "All Pages",
|
BodyTitle: "All Sections",
|
||||||
Admin: ctx.Admin(),
|
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()
|
ctx.Exec()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,11 @@ var routes = []route{
|
||||||
staticHandler,
|
staticHandler,
|
||||||
[]string{"GET"},
|
[]string{"GET"},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"/sections",
|
||||||
|
sectionsHandler,
|
||||||
|
[]string{"GET"},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"/search",
|
"/search",
|
||||||
searchHandler,
|
searchHandler,
|
||||||
|
|
@ -35,11 +40,6 @@ var routes = []route{
|
||||||
pageNewHandler),
|
pageNewHandler),
|
||||||
[]string{"GET", "POST"},
|
[]string{"GET", "POST"},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"/all",
|
|
||||||
allHandler,
|
|
||||||
[]string{"GET"},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"/login",
|
"/login",
|
||||||
loginHandler,
|
loginHandler,
|
||||||
|
|
@ -109,6 +109,11 @@ var routes = []route{
|
||||||
pageHandler),
|
pageHandler),
|
||||||
[]string{"GET"},
|
[]string{"GET"},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"/{section:[a-zA-Z0-9]+}",
|
||||||
|
sectionHandler,
|
||||||
|
[]string{"GET"},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"/{section:[a-zA-Z0-9]+}/{title:[a-zA-Z0-9+-]+}",
|
"/{section:[a-zA-Z0-9]+}/{title:[a-zA-Z0-9+-]+}",
|
||||||
pageHandler,
|
pageHandler,
|
||||||
|
|
|
||||||
|
|
@ -12,37 +12,6 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
all = `{{define "body"}}
|
|
||||||
<div class="page-header">
|
|
||||||
<div class="row">
|
|
||||||
<h2>{{.BodyTitle}}</h2>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{if .Data}}
|
|
||||||
<div class="row mt-5">
|
|
||||||
{{$idx0 := index .Data 0}}
|
|
||||||
{{$owner := $idx0.Owner}}
|
|
||||||
<strong>{{$owner}}</strong>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<ul type="circle">
|
|
||||||
{{range $item := .Data}}
|
|
||||||
{{if ne $owner $item.Owner}}
|
|
||||||
{{$owner = $item.Owner}}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<strong>{{$owner}}</strong>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<ul type="circle">
|
|
||||||
{{end}}
|
|
||||||
<li><a href="/{{$item.StoreTitle}}"><b>{{$item.Title}}</b></a></li>
|
|
||||||
{{end}}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
{{end}}
|
|
||||||
{{end}}`
|
|
||||||
forbidden = `{{define "body"}}
|
forbidden = `{{define "body"}}
|
||||||
<div class="page-header">
|
<div class="page-header">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|
@ -65,7 +34,7 @@ const (
|
||||||
<head>
|
<head>
|
||||||
<title>GoWiki | {{.Title}}</title>
|
<title>GoWiki | {{.Title}}</title>
|
||||||
<link rel="stylesheet" type="text/css" href="/bootstrap.css" media="screen" integrity="sha256-NeLmQ7cX66J4MdtgGlG3O/TgvsSyP1b9WbaQtxYZUbQ="></link>
|
<link rel="stylesheet" type="text/css" href="/bootstrap.css" media="screen" integrity="sha256-NeLmQ7cX66J4MdtgGlG3O/TgvsSyP1b9WbaQtxYZUbQ="></link>
|
||||||
<link rel="stylesheet" type="text/css" href="/custom.css" media="screen" integrity="sha256-/SZfW8eVqFuioMg+QXacvK1Zc3XLtT5LGu9tMle65Jc="></link>
|
<link rel="stylesheet" type="text/css" href="/custom.css" media="screen" integrity="sha256-o0xveJH8qNnWr/39Jnx97yDlYrvjuUnzE4q3p+94Yp4="></link>
|
||||||
<meta name="theme-color" content="#375a7f">
|
<meta name="theme-color" content="#375a7f">
|
||||||
<meta name="description" content="{{.Title}}">
|
<meta name="description" content="{{.Title}}">
|
||||||
</head>
|
</head>
|
||||||
|
|
@ -166,7 +135,7 @@ const (
|
||||||
menu = `{{define "menu"}}
|
menu = `{{define "menu"}}
|
||||||
<ul class="navbar-nav">
|
<ul class="navbar-nav">
|
||||||
<li class="nav-item"><a class="nav-link" href="/wiki/Index">Index</a></li>
|
<li class="nav-item"><a class="nav-link" href="/wiki/Index">Index</a></li>
|
||||||
<li class="nav-item"><a class="nav-link" href="/all">All Pages</a></li>
|
<li class="nav-item"><a class="nav-link" href="/sections">Sections</a></li>
|
||||||
{{if .Login}}
|
{{if .Login}}
|
||||||
<li class="nav-item"><a class="nav-link" href="/new">New Page</a></li>
|
<li class="nav-item"><a class="nav-link" href="/new">New Page</a></li>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
@ -488,6 +457,48 @@ const (
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{{end}}`
|
||||||
|
section = `{{define "body"}}
|
||||||
|
<div class="page-header">
|
||||||
|
<div class="row">
|
||||||
|
<h2>{{.BodyTitle}}</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{if .Data}}
|
||||||
|
<div class="row">
|
||||||
|
<ul type="circle">
|
||||||
|
{{range $item := .Data}}
|
||||||
|
<li><a href="/{{$item.StoreTitle}}"><b>{{$item.Title}}</b></a></li>
|
||||||
|
{{end}}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
{{end}}`
|
||||||
|
sections = `{{define "body"}}
|
||||||
|
<div class="page-header">
|
||||||
|
<div class="row">
|
||||||
|
<h2>{{.BodyTitle}}</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{if .Data}}
|
||||||
|
<div class="row">
|
||||||
|
{{range $index, $item := .Data}}
|
||||||
|
<div class="col-xs-4 section">
|
||||||
|
<div class="card border-primary mx-auto">
|
||||||
|
<div class="card-header">
|
||||||
|
<strong><a href="/{{$item.Section}}">{{$item.Section}}</a></strong>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
{{range $page := $item.Pages}}
|
||||||
|
<strong><a href="/{{$page.StoreTitle}}">{{$page.Title}}</a></strong><br>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="offset-1"></div>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
{{end}}`
|
{{end}}`
|
||||||
userDel = `{{define "body"}}
|
userDel = `{{define "body"}}
|
||||||
{{if .Data}}
|
{{if .Data}}
|
||||||
|
|
@ -499,7 +510,7 @@ const (
|
||||||
<strong>Delete {{.Data.Username}}?</strong>
|
<strong>Delete {{.Data.Username}}?</strong>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<p>You are about to delete <a href="/user/edit/{{.Data.Username}}">{{.Data.Username}}</a>.<br>This will also remove all private pages of this user.</p>
|
<p>You are about to delete user <a href="/{{.Data.Username}}">{{.Data.Username}}</a>.<br>This will also remove all private pages of this user.</p>
|
||||||
<form class="form-horizontal" action="/user/del/{{.Data.Username}}" method="post">
|
<form class="form-horizontal" action="/user/del/{{.Data.Username}}" method="post">
|
||||||
<input type="hidden" name="token" value="{{.Token}}">
|
<input type="hidden" name="token" value="{{.Token}}">
|
||||||
<button class="btn btn-sm btn-danger" type="submit">Delete</button>
|
<button class="btn btn-sm btn-danger" type="submit">Delete</button>
|
||||||
|
|
@ -570,6 +581,7 @@ const (
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
@ -659,6 +671,7 @@ const (
|
||||||
<a href="/user" class="btn btn-sm btn-primary">Back</a>
|
<a href="/user" class="btn btn-sm btn-primary">Back</a>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{end}}`
|
{{end}}`
|
||||||
|
|
@ -695,6 +708,7 @@ const (
|
||||||
<a href="/user/edit/{{.Data.Username}}" class="btn btn-sm btn-primary">Back</a>
|
<a href="/user/edit/{{.Data.Username}}" class="btn btn-sm btn-primary">Back</a>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
@ -838,6 +852,10 @@ html, body, .container, .content {
|
||||||
.proper-content {
|
.proper-content {
|
||||||
padding-top: 40px;
|
padding-top: 40px;
|
||||||
}
|
}
|
||||||
|
.section {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
width: 250px;
|
||||||
|
}
|
||||||
.wrapper {
|
.wrapper {
|
||||||
min-height: 100%;
|
min-height: 100%;
|
||||||
height: auto !important;
|
height: auto !important;
|
||||||
|
|
@ -883,7 +901,8 @@ func (s *HTTPServer) loadTemplates() {
|
||||||
s.templ["loginHandler"] = parse(index, menu, login)
|
s.templ["loginHandler"] = parse(index, menu, login)
|
||||||
s.templ["loginTotpHandler"] = parse(index, menu, loginTotp)
|
s.templ["loginTotpHandler"] = parse(index, menu, loginTotp)
|
||||||
s.templ["searchHandler"] = parse(index, menu, search)
|
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["pageHandler"] = parse(index, menu, page)
|
||||||
s.templ["pageNewHandler"] = parse(index, menu, pageNew)
|
s.templ["pageNewHandler"] = parse(index, menu, pageNew)
|
||||||
s.templ["pageEditHandler"] = parse(index, menu, pageEdit)
|
s.templ["pageEditHandler"] = parse(index, menu, pageEdit)
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,8 @@ func (s *HTTPServer) loadTemplates() {
|
||||||
s.templ["loginHandler"] = parse(index, menu, login)
|
s.templ["loginHandler"] = parse(index, menu, login)
|
||||||
s.templ["loginTotpHandler"] = parse(index, menu, loginTotp)
|
s.templ["loginTotpHandler"] = parse(index, menu, loginTotp)
|
||||||
s.templ["searchHandler"] = parse(index, menu, search)
|
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["pageHandler"] = parse(index, menu, page)
|
||||||
s.templ["pageNewHandler"] = parse(index, menu, pageNew)
|
s.templ["pageNewHandler"] = parse(index, menu, pageNew)
|
||||||
s.templ["pageEditHandler"] = parse(index, menu, pageEdit)
|
s.templ["pageEditHandler"] = parse(index, menu, pageEdit)
|
||||||
|
|
|
||||||
|
|
@ -125,6 +125,10 @@ html, body, .container, .content {
|
||||||
.proper-content {
|
.proper-content {
|
||||||
padding-top: 40px;
|
padding-top: 40px;
|
||||||
}
|
}
|
||||||
|
.section {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
width: 250px;
|
||||||
|
}
|
||||||
.wrapper {
|
.wrapper {
|
||||||
min-height: 100%;
|
min-height: 100%;
|
||||||
height: auto !important;
|
height: auto !important;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
<head>
|
<head>
|
||||||
<title>GoWiki | {{.Title}}</title>
|
<title>GoWiki | {{.Title}}</title>
|
||||||
<link rel="stylesheet" type="text/css" href="/bootstrap.css" media="screen" integrity="sha256-NeLmQ7cX66J4MdtgGlG3O/TgvsSyP1b9WbaQtxYZUbQ="></link>
|
<link rel="stylesheet" type="text/css" href="/bootstrap.css" media="screen" integrity="sha256-NeLmQ7cX66J4MdtgGlG3O/TgvsSyP1b9WbaQtxYZUbQ="></link>
|
||||||
<link rel="stylesheet" type="text/css" href="/custom.css" media="screen" integrity="sha256-/SZfW8eVqFuioMg+QXacvK1Zc3XLtT5LGu9tMle65Jc="></link>
|
<link rel="stylesheet" type="text/css" href="/custom.css" media="screen" integrity="sha256-o0xveJH8qNnWr/39Jnx97yDlYrvjuUnzE4q3p+94Yp4="></link>
|
||||||
<meta name="theme-color" content="#375a7f">
|
<meta name="theme-color" content="#375a7f">
|
||||||
<meta name="description" content="{{.Title}}">
|
<meta name="description" content="{{.Title}}">
|
||||||
</head>
|
</head>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
{{define "menu"}}
|
{{define "menu"}}
|
||||||
<ul class="navbar-nav">
|
<ul class="navbar-nav">
|
||||||
<li class="nav-item"><a class="nav-link" href="/wiki/Index">Index</a></li>
|
<li class="nav-item"><a class="nav-link" href="/wiki/Index">Index</a></li>
|
||||||
<li class="nav-item"><a class="nav-link" href="/all">All Pages</a></li>
|
<li class="nav-item"><a class="nav-link" href="/sections">Sections</a></li>
|
||||||
{{if .Login}}
|
{{if .Login}}
|
||||||
<li class="nav-item"><a class="nav-link" href="/new">New Page</a></li>
|
<li class="nav-item"><a class="nav-link" href="/new">New Page</a></li>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
|
||||||
|
|
@ -5,24 +5,9 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{if .Data}}
|
{{if .Data}}
|
||||||
<div class="row mt-5">
|
|
||||||
{{$idx0 := index .Data 0}}
|
|
||||||
{{$owner := $idx0.Owner}}
|
|
||||||
<strong>{{$owner}}</strong>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<ul type="circle">
|
<ul type="circle">
|
||||||
{{range $item := .Data}}
|
{{range $item := .Data}}
|
||||||
{{if ne $owner $item.Owner}}
|
|
||||||
{{$owner = $item.Owner}}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<strong>{{$owner}}</strong>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<ul type="circle">
|
|
||||||
{{end}}
|
|
||||||
<li><a href="/{{$item.StoreTitle}}"><b>{{$item.Title}}</b></a></li>
|
<li><a href="/{{$item.StoreTitle}}"><b>{{$item.Title}}</b></a></li>
|
||||||
{{end}}
|
{{end}}
|
||||||
</ul>
|
</ul>
|
||||||
26
templates/sections.html
Normal file
26
templates/sections.html
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
{{define "body"}}
|
||||||
|
<div class="page-header">
|
||||||
|
<div class="row">
|
||||||
|
<h2>{{.BodyTitle}}</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{if .Data}}
|
||||||
|
<div class="row">
|
||||||
|
{{range $index, $item := .Data}}
|
||||||
|
<div class="col-xs-4 section">
|
||||||
|
<div class="card border-primary mx-auto">
|
||||||
|
<div class="card-header">
|
||||||
|
<strong><a href="/{{$item.Section}}">{{$item.Section}}</a></strong>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
{{range $page := $item.Pages}}
|
||||||
|
<strong><a href="/{{$page.StoreTitle}}">{{$page.Title}}</a></strong><br>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="offset-1"></div>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
{{end}}
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
<strong>Delete {{.Data.Username}}?</strong>
|
<strong>Delete {{.Data.Username}}?</strong>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<p>You are about to delete <a href="/user/edit/{{.Data.Username}}">{{.Data.Username}}</a>.<br>This will also remove all private pages of this user.</p>
|
<p>You are about to delete user <a href="/{{.Data.Username}}">{{.Data.Username}}</a>.<br>This will also remove all private pages of this user.</p>
|
||||||
<form class="form-horizontal" action="/user/del/{{.Data.Username}}" method="post">
|
<form class="form-horizontal" action="/user/del/{{.Data.Username}}" method="post">
|
||||||
<input type="hidden" name="token" value="{{.Token}}">
|
<input type="hidden" name="token" value="{{.Token}}">
|
||||||
<button class="btn btn-sm btn-danger" type="submit">Delete</button>
|
<button class="btn btn-sm btn-danger" type="submit">Delete</button>
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,7 @@
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@
|
||||||
<a href="/user" class="btn btn-sm btn-primary">Back</a>
|
<a href="/user" class="btn btn-sm btn-primary">Back</a>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@
|
||||||
<a href="/user/edit/{{.Data.Username}}" class="btn btn-sm btn-primary">Back</a>
|
<a href="/user/edit/{{.Data.Username}}" class="btn btn-sm btn-primary">Back</a>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue