Browse Source
Massive overhaul, fixing menus and changing template engine. Added /month/ and /author/ filters
master
Massive overhaul, fixing menus and changing template engine. Added /month/ and /author/ filters
master
Gisle Aune
7 years ago
44 changed files with 861 additions and 518 deletions
-
94controllers/listcontroller.go
-
44controllers/pagecontroller.go
-
34controllers/tagcontroller.go
-
19main.go
-
11model/category.go
-
74model/header.go
-
7model/page.go
-
21model/tag.go
-
44view/amber/base/master.amber
-
30view/amber/base/mixins.amber
-
63view/amber/create.amber
-
25view/amber/index.amber
-
25view/amber/menu.amber
-
12view/amber/message.amber
-
30view/amber/page/delete.amber
-
64view/amber/page/edit.amber
-
29view/amber/page/menu.amber
-
14view/amber/page/source.amber
-
13view/amber/page/view.amber
-
17view/amber/tags.amber
-
26view/amber/user/login.amber
-
4view/amber/user/menu.amber
-
79view/renderer.go
-
41view/templates/base/default.tmpl
-
66view/templates/index.tmpl
-
44view/templates/page/create.tmpl
-
37view/templates/page/delete.tmpl
-
44view/templates/page/edit.tmpl
-
44view/templates/page/view.tmpl
-
48view/templates/tags/list.tmpl
-
24view/templates/user/login.tmpl
-
9viewmodel/base.go
-
16viewmodel/indexbase.go
-
12viewmodel/indexlist.go
-
49viewmodel/indextags.go
-
19viewmodel/message.go
-
9viewmodel/pagebase.go
-
26viewmodel/pagecreate.go
-
19viewmodel/pagedelete.go
-
14viewmodel/pageedit.go
-
20viewmodel/pagesource.go
-
11viewmodel/pageview.go
-
46viewmodel/taglist.go
-
2viewmodel/userlogin.go
@ -1,34 +0,0 @@ |
|||
package controllers |
|||
|
|||
import ( |
|||
"net/http" |
|||
|
|||
"git.aiterp.net/AiteRP/aitestory/view" |
|||
"git.aiterp.net/AiteRP/aitestory/viewmodel" |
|||
|
|||
"git.aiterp.net/AiteRP/aitestory/model" |
|||
"git.aiterp.net/gisle/wrouter" |
|||
"git.aiterp.net/gisle/wrouter/auth" |
|||
) |
|||
|
|||
// TagController serves and handles the tag managment pages
|
|||
var TagController = wrouter.Router{} |
|||
|
|||
func tagList(path string, w http.ResponseWriter, req *http.Request, user *auth.User) bool { |
|||
//var err error
|
|||
if (req.Method != "GET" && req.Method != "POST") || len(req.URL.Path) > len(path) { |
|||
return false |
|||
} |
|||
|
|||
tl := viewmodel.TagList{} |
|||
tl.Tags, _ = model.ListTags() |
|||
tl.Setup(user) |
|||
|
|||
view.Render(w, "tags/list", 200, tl) |
|||
|
|||
return true |
|||
} |
|||
|
|||
func init() { |
|||
TagController.Function("/", tagList) |
|||
} |
@ -0,0 +1,44 @@ |
|||
doctype 5 |
|||
|
|||
import mixins |
|||
|
|||
html |
|||
head |
|||
block meta |
|||
meta[name="description"][content="This is a great website"] |
|||
meta[charset="UTF-8"] |
|||
meta[name="viewport"][content="width=device-width, initial-scale=1.0, maximum-scale=2.0, user-scalable=no"] |
|||
meta[name="theme-color"][content="#112233"] |
|||
meta[http-equiv="Content-Type"][content="text/html; charset=utf-8"] |
|||
|
|||
block css |
|||
link[rel="stylesheet"][href="/ui/css/base.css"] |
|||
link[rel="stylesheet"][href="/ui/css/magic.css"] |
|||
link[rel="stylesheet"][href="/ui/css/theme.css"] |
|||
link[rel="stylesheet"][media="screen"][href="/ui/fonts/source-sans-pro/source-sans-pro.css"][type="text/css"] |
|||
|
|||
block js |
|||
script[type="text/javascript"][src="/ui/js/background.js"] |
|||
|
|||
title #{ViewTitle} |
|||
body |
|||
if ViewBackground != "" |
|||
img[id="main-background"][src="/ui/img/bg.png"] |
|||
else |
|||
img[id="main-background"][src="/ui/img/bg.png"] |
|||
|
|||
div.content-wrapper |
|||
nav |
|||
block menu |
|||
if User.LoggedIn |
|||
ul |
|||
+menuitem("/user/logout", "U", "Logout") |
|||
else |
|||
ul |
|||
+menuitem("/user/login", "U", "Login") |
|||
|
|||
if ViewPath != "/" |
|||
+menuitem("/", "<", "Back") |
|||
|
|||
main |
|||
block main |
@ -0,0 +1,30 @@ |
|||
$root = $ |
|||
|
|||
mixin menuitem($path, $icon, $text) |
|||
li |
|||
.selected ? $root.ViewPath == $path |
|||
a[href=$path] |
|||
div.mg-icon #{$icon} |
|||
div.mg-label #{$text} |
|||
|
|||
mixin tagmenuitem($tag) |
|||
li |
|||
[class=$tag.CSSClass] |
|||
a[href=$tag.Path] |
|||
div.mg-icon #{$tag.Icon} |
|||
div.mg-label #{$tag.Name} |
|||
|
|||
|
|||
|
|||
mixin formoption($name, $selected, $label, $info) |
|||
div.radio-wrapper |
|||
$id = printf("checkbox-%s", $name) |
|||
|
|||
if $selected |
|||
input[id=$id][type="checkbox"][name=$name][value="true"][checked] |
|||
else |
|||
input[id=$id][type="checkbox"][name=$name][value="true"] |
|||
|
|||
label[for="checkbox-unlisted"] |
|||
b #{$label}: |
|||
spamn #{$info} |
@ -0,0 +1,63 @@ |
|||
extends base/master |
|||
|
|||
block append css |
|||
link[rel="stylesheet"][href="/ui/css/form.css"] |
|||
|
|||
block append js |
|||
script[type="text/javascript"][src="/ui/js/form-page.js"] |
|||
|
|||
block menu |
|||
import menu |
|||
|
|||
block main |
|||
$page = $.Page |
|||
|
|||
article |
|||
h1 Create |
|||
form[action="/page/create"][method="POST"] |
|||
p.danger #{$.Error} |
|||
|
|||
input.big |
|||
[placeholder="Page Name"] |
|||
[value=$page.Name] |
|||
[type="text"] |
|||
[name="name"] |
|||
textarea.tall |
|||
[placeholder="Content"] |
|||
[name="source"] |
|||
| #{$page.Source} |
|||
input |
|||
[placeholder="IC Date (e.g. 'Oct 27, 2185')"] |
|||
[name="fictionalDate"] |
|||
[type="text"] |
|||
[value=$page.FictionalDate] ? !$page.FictionalDate.IsZero |
|||
|
|||
h2 Category |
|||
div.group[title="Category"] |
|||
each $category in $.Categories |
|||
div.radio-wrapper |
|||
$radioid = printf("radio-%s", $category.Key) |
|||
if $category.Key == $page.Category |
|||
input[id=$radioid][name="category"][type="radio"][name="category"][value=$category.Key][checked] |
|||
else |
|||
input[id=$radioid][name="category"][type="radio"][name="category"][value=$category.Key] |
|||
label[for=$radioid] |
|||
b #{$category.Key}: |
|||
span #{$category.Info} |
|||
|
|||
h2 Tags |
|||
textarea |
|||
[name="tags"] |
|||
[placeholder="Location: Miner's Respite\nOrganization: Redrock Agency\nCharacter: Renala T'Iavay\nEvent: Skipping Work\nSeries: Just Another Tuesday"] |
|||
| #{$.TagInput} |
|||
|
|||
h2 Options |
|||
div.group |
|||
+formoption("unlisted", $page.Unlisted, "Unlisted", "The page will not show up in any page list. Meant for omni-tool messages, quick copypastes and so on.") |
|||
+formoption("indexed", $page.Unlisted, "Indexable", "Third-party search engines (that play by the rules) are permitted to crawl this page.") |
|||
|
|||
// Future options (maybe) |
|||
input[type="hidden"][name="type"][value="Markdown"] |
|||
input[type="hidden"][name="published"][value="True"] |
|||
|
|||
button[type="submit"] Create |
@ -0,0 +1,25 @@ |
|||
extends base/master |
|||
|
|||
block menu |
|||
import menu |
|||
|
|||
block main |
|||
article |
|||
table.page-list |
|||
tbody |
|||
each $header in Headers |
|||
tr |
|||
td.pl-icon #{$header.CategoryInfo.Icon} |
|||
td.pl-content |
|||
div.plc-title |
|||
a[href=$header.Path] #{$header.Name} |
|||
div.plc-meta |
|||
div.plcm-date #{formatDate($header.PublishDate)} |
|||
if $header.Dated |
|||
div.plcm-date #{formatDate($header.FictionalDate)} |
|||
if $header.PrimaryTag |
|||
div.plcm-tag[class=$header.PrimaryTag.CSSCLass] #{$header.PrimaryTag.Name} |
|||
div.plcm-author #{formatUserID($header.Author)} |
|||
tr.spacer |
|||
td |
|||
|
@ -0,0 +1,25 @@ |
|||
import base/mixins |
|||
|
|||
$authorPath = printf("/author/%s", ActiveAuthor) |
|||
|
|||
a[href="/"] |
|||
h1 Aite RP |
|||
|
|||
ul |
|||
if User.LoggedIn |
|||
+menuitem("/page/create", "+", "Create") |
|||
|
|||
ul |
|||
each $category in Categories |
|||
+menuitem($category.Path, $category.Icon, $category.Plural) |
|||
|
|||
ul |
|||
if ActiveTag.ID |
|||
+menuitem(ActiveTag.Path, ActiveTag.Icon, ActiveTag.Name) |
|||
if ActiveDate |
|||
+menuitem(ActiveDatePath, "D", ActiveDate) |
|||
if ActiveAuthor |
|||
+menuitem($authorPath, "A", formatUserID(ActiveAuthor)) |
|||
|
|||
ul |
|||
+menuitem("/tags/", "T", "Tags") |
@ -0,0 +1,12 @@ |
|||
extends base/master |
|||
|
|||
block menu |
|||
a[href="/"] |
|||
h1 Aite RP |
|||
|
|||
block main |
|||
article |
|||
h1 |
|||
.danger ? $.Danger |
|||
| #{$.Title} |
|||
p #{$.Text} |
@ -0,0 +1,30 @@ |
|||
extends ../base/master |
|||
|
|||
block append css |
|||
link[rel="stylesheet"][href="/ui/css/form.css"] |
|||
|
|||
block append js |
|||
script[type="text/javascript"][src="/ui/js/form-page.js"] |
|||
|
|||
block menu |
|||
import menu |
|||
|
|||
block main |
|||
$page = $.Page |
|||
|
|||
article |
|||
h1.danger Delete |
|||
form[action=$page.OpPath("delete")][method="POST"] |
|||
p.danger This is irreversible, so make sure you are deleting the right page. |
|||
|
|||
ul |
|||
li <b>ID:</b> #{$.Page.ID} |
|||
li <b>Name:</b> #{$.Page.Name} |
|||
li <b>Category:</b> #{$.Page.Category} |
|||
li <b>Published:</b> #{formatDateLong($.Page.PublishDate)} |
|||
ul |
|||
|
|||
input[type="hidden"][name="aft"][value=$.User.SessionID] |
|||
|
|||
|
|||
button[type="submit"] Delete |
@ -0,0 +1,64 @@ |
|||
extends ../base/master |
|||
|
|||
|
|||
block append css |
|||
link[rel="stylesheet"][href="/ui/css/form.css"] |
|||
|
|||
block append js |
|||
script[type="text/javascript"][src="/ui/js/form-page.js"] |
|||
|
|||
block menu |
|||
import menu |
|||
|
|||
block main |
|||
$page = $.Page |
|||
|
|||
article |
|||
h1 Create |
|||
form[action=$page.OpPath("edit")][method="POST"] |
|||
p.danger #{$.Error} |
|||
|
|||
input.big |
|||
[placeholder="Page Name"] |
|||
[value=$page.Name] |
|||
[type="text"] |
|||
[name="name"] |
|||
textarea.tall |
|||
[placeholder="Content"] |
|||
[name="source"] |
|||
| #{$page.Source} |
|||
input |
|||
[placeholder="IC Date (e.g. 'Oct 27, 2185')"] |
|||
[name="fictionalDate"] |
|||
[type="text"] |
|||
[value=$page.FictionalDate] ? !$page.FictionalDate.IsZero |
|||
|
|||
h2 Category |
|||
div.group[title="Category"] |
|||
each $category in $.Categories |
|||
div.radio-wrapper |
|||
$radioid = printf("radio-%s", $category.Key) |
|||
if $category.Key == $page.Category |
|||
input[id=$radioid][name="category"][type="radio"][name="category"][value=$category.Key][checked] |
|||
else |
|||
input[id=$radioid][name="category"][type="radio"][name="category"][value=$category.Key] |
|||
label[for=$radioid] |
|||
b #{$category.Key}: |
|||
span #{$category.Info} |
|||
|
|||
h2 Tags |
|||
textarea |
|||
[name="tags"] |
|||
[placeholder="Location: Miner's Respite\nOrganization: Redrock Agency\nCharacter: Renala T'Iavay\nEvent: Skipping Work\nSeries: Just Another Tuesday"] |
|||
| #{$.TagInput} |
|||
|
|||
h2 Options |
|||
div.group |
|||
+formoption("unlisted", $page.Unlisted, "Unlisted", "The page will not show up in any page list. Meant for omni-tool messages, quick copypastes and so on.") |
|||
+formoption("indexed", $page.Indexed, "Indexable", "Third-party search engines (that play by the rules) are permitted to crawl this page.") |
|||
|
|||
// Future options (maybe) |
|||
input[type="hidden"][name="type"][value="Markdown"] |
|||
input[type="hidden"][name="published"][value="True"] |
|||
|
|||
button[type="submit"] Edit |
@ -0,0 +1,29 @@ |
|||
import ../base/mixins |
|||
|
|||
$pagePath = printf("/page/%s", $.Page.ID) |
|||
$pageEditPath = printf("/page/edit/%s", $.Page.ID) |
|||
$pageDeletePath = printf("/page/delete/%s", $.Page.ID) |
|||
$pageSourcePath = printf("/page/source/%s", $.Page.ID) |
|||
$datePath = printf("/month/%s", $.Page.FictionalDate.UTC.Format("2006-01")) |
|||
$authorPath = printf("/author/%s", $.Page.Author) |
|||
|
|||
a[href="/"] |
|||
h1 Page |
|||
|
|||
if !$.HideMenu |
|||
ul |
|||
+menuitem($pagePath, "V", "View") |
|||
if $.Page.Author == $.User.ID |
|||
+menuitem($pageEditPath, "E", "Edit") |
|||
+menuitem($pageDeletePath, "X", "Delete") |
|||
else |
|||
+menuitem($pageSourcePath, "#", "Source") |
|||
|
|||
ul |
|||
each $tag in $.Page.Tags |
|||
+tagmenuitem($tag) |
|||
|
|||
ul |
|||
if $.Page.Dated |
|||
+menuitem($datePath, "D", formatDate($.Page.FictionalDate)) |
|||
+menuitem($authorPath, "A", formatUserID($.Page.Author)) |
@ -0,0 +1,14 @@ |
|||
extends ../base/master |
|||
|
|||
block append meta |
|||
if !$.Page.Indexed |
|||
meta[name="robots"][content="noindex"] |
|||
meta[name="googlebot"][content="noindex"] |
|||
|
|||
block menu |
|||
import menu |
|||
|
|||
block main |
|||
article |
|||
code.block |
|||
#{$.Page.Source} |
@ -0,0 +1,13 @@ |
|||
extends ../base/master |
|||
|
|||
block append meta |
|||
if !$.Page.Indexed |
|||
meta[name="robots"][content="noindex"] |
|||
meta[name="googlebot"][content="noindex"] |
|||
|
|||
block menu |
|||
import menu |
|||
|
|||
block main |
|||
article.narrow |
|||
#{$.Page.Content} |
@ -0,0 +1,17 @@ |
|||
extends base/master |
|||
|
|||
block menu |
|||
import menu |
|||
|
|||
block main |
|||
article |
|||
h1 All Tags |
|||
div.tag-list |
|||
each $key, $tags in $.Map |
|||
if $tags |
|||
div.tl-item |
|||
h2 #{$key} |
|||
ul |
|||
each $tag in $tags |
|||
li |
|||
a[class=$tag.CSSClass][href=$tag.Path] #{$tag.Name} |
@ -0,0 +1,26 @@ |
|||
extends ../base/master |
|||
|
|||
block append css |
|||
link[rel="stylesheet"][href="/ui/css/form.css"] |
|||
|
|||
block menu |
|||
import menu |
|||
|
|||
block main |
|||
article |
|||
h1 Login |
|||
form[action="/user/login"][method="POST"] |
|||
p Use your wiki.aiterp.net account. |
|||
p.danger #{$.Error} |
|||
input |
|||
[placeholder="Username"] |
|||
[name="username"] |
|||
[type="text"] |
|||
[value=$.UserName] |
|||
[autofocus] ? $.UserName == "" |
|||
input |
|||
[placeholder="Password"] |
|||
[name="password"] |
|||
[type="password"] |
|||
[autofocus] ? $.UserName != "" |
|||
button[type="submit"] Login |
@ -0,0 +1,4 @@ |
|||
import ../base/mixins |
|||
|
|||
a[href="/"] |
|||
h1 User |
@ -1,41 +0,0 @@ |
|||
{{define "base"}} |
|||
<!DOCTYPE html> |
|||
<!-- For preview and template creation only --> |
|||
|
|||
<html> |
|||
<head> |
|||
<title>{{ .ViewTitle }}</title> |
|||
|
|||
<meta charset="UTF-8"> |
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=2.0, user-scalable=no" /> |
|||
<meta name="theme-color" content="#222222"> |
|||
<meta name="robots" content="noindex"> |
|||
<meta name="googlebot" content="noindex"> |
|||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> |
|||
|
|||
<link rel="stylesheet" href="/ui/css/base.css" /> |
|||
<link rel="stylesheet" href="/ui/css/magic.css" /> |
|||
<link rel="stylesheet" href="/ui/css/theme.css" /> |
|||
|
|||
<link rel="stylesheet" media="screen" href="/ui/fonts/source-sans-pro/source-sans-pro.css" type="text/css"/> |
|||
|
|||
<script type="text/javascript" src="/ui/js/background.js"></script> |
|||
|
|||
{{ block "head" . }}{{end}} |
|||
</head> |
|||
|
|||
<body> |
|||
<img id="main-background" src="/ui/img/bg.png" /> |
|||
|
|||
<div id="content-wrapper"> |
|||
<main> |
|||
{{ block "content" . }}{{end}} |
|||
</main> |
|||
|
|||
<nav class="main-menu"> |
|||
{{ block "menu" . }}{{end}} |
|||
</nav> |
|||
</div> |
|||
</body> |
|||
</html> |
|||
{{end}} |
@ -1,66 +0,0 @@ |
|||
{{ define "content" }} |
|||
<article> |
|||
<table class="page-list"> |
|||
{{ range .Headers }} |
|||
<tbody> |
|||
<tr class=""> |
|||
<td class="pl-icon">{{.CategoryInfo.Icon}}</td> |
|||
<td class="pl-content"> |
|||
<div class="plc-title"><a href="/page/{{.ID}}">{{.Name}}</a></div> |
|||
<div class="plc-meta"> |
|||
<div class="plcm-date">{{.PublishDate | formatDate}}</div> |
|||
{{ if .Dated }} |
|||
<div class="plcm-date">{{.FictionalDate | formatDate}}</div> |
|||
{{ end }} |
|||
{{ if .PrimaryTag }} |
|||
<div class="plcm-tag {{.PrimaryTag.CSSCLass}}">{{.PrimaryTag.Name}}</div> |
|||
{{ end }} |
|||
<div class="plcm-author">{{.Author | formatUserID}}</div> |
|||
</div> |
|||
</td> |
|||
</tr> |
|||
<tr class="spacer"><td></td></tr> |
|||
{{ end }} |
|||
</table> |
|||
</article> |
|||
{{ end }} |
|||
|
|||
{{ define "menu" }} |
|||
<a href="/"><h1>Aite RP</h1></a> |
|||
|
|||
<ul> |
|||
{{ range .Categories }} |
|||
<li class="{{ if eq .Key $.ActiveCategory.Key }}selected{{end}}"><a href="/{{.Plural}}/"><div class="mg-icon">{{.Icon}}</div><div class="mg-label">{{.Plural}}</div></a></li> |
|||
{{ end }} |
|||
</ul> |
|||
|
|||
{{ if $.ActiveTag.ID }} |
|||
<ul> |
|||
<li class="selected"><a href="/{{$.ActiveTag.Type}}/{{$.ActiveTag.Hook}}"><div class="mg-icon">{{$.ActiveTag.Icon}}</div><div class="mg-label">{{$.ActiveTag.Name}}</div></a></li> |
|||
</ul> |
|||
{{ end }} |
|||
|
|||
<ul> |
|||
<li><a href="/tags/"><div class="mg-icon">T</div><div class="mg-label">Tags</div></a></li> |
|||
</ul> |
|||
|
|||
{{ if $.User.LoggedIn }} |
|||
<ul> |
|||
<li><a href="/page/create"><div class="mg-icon">+</div><div class="mg-label">Create</div></a></li> |
|||
</ul> |
|||
|
|||
<ul> |
|||
<li><a href="/user/logout"><div class="mg-icon">A</div><div class="mg-label">Logout</div></a></li> |
|||
</ul> |
|||
{{ else }} |
|||
<ul> |
|||
<li><a href="/user/login"><div class="mg-icon">A</div><div class="mg-label">Login</div></a></li> |
|||
</ul> |
|||
{{ end }} |
|||
|
|||
|
|||
{{ end }} |
|||
|
|||
{{ define "head" }} |
|||
|
|||
{{ end }} |
@ -1,44 +0,0 @@ |
|||
{{ define "content" }} |
|||
<article> |
|||
<h1>{{$.Operation}}</h1> |
|||
<form action="/page/create", method="POST"> |
|||
<p class="danger">{{$.Error}}</p> |
|||
<input class="big" placeholder="Page Name" name="name" type="text" value="{{$.Page.Name}}" /> |
|||
<textarea class="tall" placeholder="Content" name="source">{{$.Page.Source}}</textarea> |
|||
<input placeholder="IC Date (e.g. 'Oct 27, 2185')" name="fictionalDate" type="text" value="{{if $.Page.FictionalDate.IsZero}}{{else}}{{$.Page.FictionalDate}}{{end}}" /> |
|||
<div class="group"> |
|||
{{ range $.Categories }} |
|||
<div class="radio-wrapper"> |
|||
<input name="category" type="radio" name="category" value="{{.Key}}" {{if eq $.Page.Category .Key}}checked{{end}}><b> {{.Key}}</b>: {{.Info}}</input> |
|||
</div> |
|||
{{ end }} |
|||
</div> |
|||
<textarea name="tags" placeholder="Tags, e.g. 'Location: Miner's Respite'. One per line, topmost is primary tag">{{$.TagInput}}</textarea> |
|||
<div class="group"> |
|||
<div class="radio-wrapper"> |
|||
<input type="checkbox" name="unlisted" value="true" {{if $.Page.Unlisted}}checked{{end}}><b> Unlisted</b>: This page will not show up on page lists, but anyone with a link can view it.</input> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- Future option --> |
|||
<input type="hidden" name="type" value="Markdown" /> |
|||
<input type="hidden" name="published" value="True" /> |
|||
|
|||
<button type="submit">{{$.Operation}}</button> |
|||
|
|||
</form> |
|||
</article> |
|||
{{ end }} |
|||
|
|||
{{ define "menu" }} |
|||
<a href="/"><h1>Aite RP</h1></a> |
|||
|
|||
<ul> |
|||
<li><a href="/"><div class="mg-icon"><</div><div class="mg-label">Back</div></a></li> |
|||
</ul> |
|||
{{ end }} |
|||
|
|||
{{ define "head" }} |
|||
<link rel="stylesheet" href="/ui/css/form.css" /> |
|||
<script type="text/javascript" src="/ui/js/form-page.js"></script> |
|||
{{ end }} |
@ -1,37 +0,0 @@ |
|||
{{ define "content" }} |
|||
<article class="narrow"> |
|||
<h1 class="danger">Delete Page</h1> |
|||
<form action="/page/delete/{{$.Page.ID}}", method="POST"> |
|||
<p class="danger"> |
|||
This is an irreversible action, so make sure that this is the correct page! |
|||
</p> |
|||
<ul> |
|||
<li><b>ID:</b> {{$.Page.ID}}</li> |
|||
<li><b>Name:</b> {{$.Page.Name}}</li> |
|||
<li><b>Category:</b> {{$.Page.Category}}</li> |
|||
<li><b>Published:</b> {{$.Page.PublishDate | formatDateLong}}</li> |
|||
</ul> |
|||
<input type="hidden" name="aft" value="{{$.User.SessionID}}" /> |
|||
|
|||
<button type="submit">Delete Page</button> |
|||
</article> |
|||
{{ end }} |
|||
|
|||
{{ define "menu" }} |
|||
<a href="/"><h1>Page</h1></a> |
|||
|
|||
{{ if eq $.User.ID $.Page.Author}} |
|||
<ul> |
|||
<li><a href="/page/edit/{{$.Page.ID}}"><div class="mg-icon">E</div><div class="mg-label">Edit</div></a></li> |
|||
<li class="selected"><a href="/page/delete/{{$.Page.ID}}"><div class="mg-icon">X</div><div class="mg-label">Delete</div></a></li> |
|||
</ul> |
|||
{{ end }} |
|||
|
|||
<ul> |
|||
<li><a href="/page/{{$.Page.ID}}"><div class="mg-icon"><</div><div class="mg-label">Back</div></a></li> |
|||
</ul> |
|||
{{ end }} |
|||
|
|||
{{ define "head" }} |
|||
<link rel="stylesheet" href="/ui/css/form.css" /> |
|||
{{ end }} |
@ -1,44 +0,0 @@ |
|||
{{ define "content" }} |
|||
<article> |
|||
<h1>{{$.Operation}}</h1> |
|||
<form action="/page/edit/{{$.Page.ID}}", method="POST"> |
|||
<p class="danger">{{$.Error}}</p> |
|||
<input class="big" placeholder="Page Name" name="name" type="text" value="{{$.Page.Name}}" /> |
|||
<textarea class="tall" placeholder="Content" name="source">{{$.Page.Source}}</textarea> |
|||
<input placeholder="IC Date (e.g. 'Oct 27, 2185')" name="fictionalDate" type="text" value="{{if $.Page.FictionalDate.IsZero}}{{else}}{{$.Page.FictionalDate}}{{end}}" /> |
|||
<div class="group"> |
|||
{{ range $.Categories }} |
|||
<div class="radio-wrapper"> |
|||
<input name="category" type="radio" name="category" value="{{.Key}}" {{if eq $.Page.Category .Key}}checked{{end}}><b> {{.Key}}</b>: {{.Info}}</input> |
|||
</div> |
|||
{{ end }} |
|||
</div> |
|||
<textarea name="tags" placeholder="Tags, e.g. 'Location: Miner's Respite'. One per line, topmost is primary tag">{{$.TagInput}}</textarea> |
|||
<div class="group"> |
|||
<div class="radio-wrapper"> |
|||
<input type="checkbox" name="unlisted" value="true" {{if $.Page.Unlisted}}checked{{end}}><b> Unlisted</b>: This page will not show up on page lists, but anyone with a link can view it.</input> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- Future option --> |
|||
<input type="hidden" name="type" value="Markdown" /> |
|||
<input type="hidden" name="published" value="True" /> |
|||
|
|||
<button type="submit">{{$.Operation}}</button> |
|||
|
|||
</form> |
|||
</article> |
|||
{{ end }} |
|||
|
|||
{{ define "menu" }} |
|||
<a href="/"><h1>Aite RP</h1></a> |
|||
|
|||
<ul> |
|||
<li><a href="/"><div class="mg-icon"><</div><div class="mg-label">Back</div></a></li> |
|||
</ul> |
|||
{{ end }} |
|||
|
|||
{{ define "head" }} |
|||
<link rel="stylesheet" href="/ui/css/form.css" /> |
|||
<script type="text/javascript" src="/ui/js/form-page.js"></script> |
|||
{{ end }} |
@ -1,44 +0,0 @@ |
|||
{{ define "content" }} |
|||
<article class="narrow"> |
|||
{{$.Page.Content}} |
|||
</article> |
|||
{{ end }} |
|||
|
|||
{{ define "menu" }} |
|||
<a href="/"><h1>Page</h1></a> |
|||
{{ if $.Page.Dated}} |
|||
<div class="page-property">{{$.Page.FictionalDate | formatDate}}</div> |
|||
{{ else }} |
|||
<div class="page-property">{{$.Page.PublishDate | formatDate}}</div> |
|||
{{ end }} |
|||
|
|||
<ul> |
|||
{{ range $.Page.Tags }} |
|||
<li><a href="/{{.Type}}/{{.Hook}}"><div class="mg-icon">{{.Icon}}</div><div class="mg-label {{.CSSCLass}}">{{.Name}}</div></a></li> |
|||
{{ end }} |
|||
</ul> |
|||
|
|||
{{ if eq $.User.ID $.Page.Author}} |
|||
<ul> |
|||
<li><a href="/page/edit/{{$.Page.ID}}"><div class="mg-icon">E</div><div class="mg-label">Edit</div></a></li> |
|||
<li><a href="/page/delete/{{$.Page.ID}}"><div class="mg-icon">X</div><div class="mg-label">Delete</div></a></li> |
|||
</ul> |
|||
{{ end }} |
|||
|
|||
<ul> |
|||
<li><a href="/"><div class="mg-icon"><</div><div class="mg-label">Back</div></a></li> |
|||
</ul> |
|||
|
|||
{{ if $.User.LoggedIn }} |
|||
<ul> |
|||
<li><a href="/user/logout"><div class="mg-icon">A</div><div class="mg-label">Logout</div></a></li> |
|||
</ul> |
|||
{{ else }} |
|||
<ul> |
|||
<li><a href="/user/login"><div class="mg-icon">A</div><div class="mg-label">Login</div></a></li> |
|||
</ul> |
|||
{{ end }} |
|||
{{ end }} |
|||
|
|||
{{ define "head" }} |
|||
{{ end }} |
@ -1,48 +0,0 @@ |
|||
{{ define "content" }} |
|||
<article> |
|||
<h1>All Tags</h1> |
|||
|
|||
<div class="tag-list"> |
|||
{{ range $tagHeader, $tags := .Map }} |
|||
<div class="tl-item"> |
|||
<h2>{{ $tagHeader }}</h2> |
|||
<ul> |
|||
{{ range $tags }} |
|||
<li><a class="ttype-{{.Type | tolower }}" href="/{{.Type}}/{{.Name}}">{{ .Name }}</a></li> |
|||
{{ end }} |
|||
</ul> |
|||
</div> |
|||
{{ end }} |
|||
</div> |
|||
|
|||
|
|||
</article> |
|||
{{ end }} |
|||
|
|||
{{ define "menu" }} |
|||
<a href="/"><h1>Tags</h1></a> |
|||
|
|||
<ul> |
|||
<li><a href="/"><div class="mg-icon"><</div><div class="mg-label">Back</div></a></li> |
|||
</ul> |
|||
|
|||
{{ if $.User.LoggedIn }} |
|||
<ul> |
|||
<li><a href="/page/create"><div class="mg-icon">+</div><div class="mg-label">Create</div></a></li> |
|||
</ul> |
|||
|
|||
<ul> |
|||
<li><a href="/user/logout"><div class="mg-icon">A</div><div class="mg-label">Logout</div></a></li> |
|||
</ul> |
|||
{{ else }} |
|||
<ul> |
|||
<li><a href="/user/login"><div class="mg-icon">A</div><div class="mg-label">Login</div></a></li> |
|||
</ul> |
|||
{{ end }} |
|||
|
|||
|
|||
{{ end }} |
|||
|
|||
{{ define "head" }} |
|||
|
|||
{{ end }} |
@ -1,24 +0,0 @@ |
|||
{{ define "content" }} |
|||
<article> |
|||
<h1>Login</h1> |
|||
<form action="/user/login", method="POST"> |
|||
<p>Use your wiki.aiterp.net account.</p> |
|||
<p class="danger">{{$.Error}}</p> |
|||
<input placeholder="Username" name="username" type="text" value="{{$.UserName}}" {{if ne $.UserName ""}}autofocus{{end}} /> |
|||
<input placeholder="Password" name="password" type="password" {{if $.UserName}}autofocus{{end}} /> |
|||
<button type="submit">Submit</button> |
|||
</form> |
|||
</article> |
|||
{{ end }} |
|||
|
|||
{{ define "menu" }} |
|||
<a href="/"><h1>Aite RP</h1></a> |
|||
|
|||
<ul> |
|||
<li><a href="/"><div class="mg-icon"><</div><div class="mg-label">Back</div></a></li> |
|||
</ul> |
|||
{{ end }} |
|||
|
|||
{{ define "head" }} |
|||
<link rel="stylesheet" href="/ui/css/form.css" /> |
|||
{{ end }} |
@ -0,0 +1,16 @@ |
|||
package viewmodel |
|||
|
|||
import "git.aiterp.net/AiteRP/aitestory/model" |
|||
|
|||
// IndexBase is used for the index menu.
|
|||
type IndexBase struct { |
|||
Categories []model.PageCategory |
|||
ActiveTag model.Tag |
|||
ActiveAuthor string |
|||
ActiveDate string |
|||
ActiveDatePath string |
|||
} |
|||
|
|||
func (im *IndexBase) setupMenu() { |
|||
im.Categories = model.PageCategories |
|||
} |
@ -0,0 +1,49 @@ |
|||
package viewmodel |
|||
|
|||
import ( |
|||
"fmt" |
|||
|
|||
"git.aiterp.net/AiteRP/aitestory/model" |
|||
"git.aiterp.net/gisle/wrouter/auth" |
|||
) |
|||
|
|||
// IndexTags is a view model for rendering the tag lists.
|
|||
type IndexTags struct { |
|||
Base |
|||
IndexBase |
|||
|
|||
Type string |
|||
Tags []model.Tag |
|||
TagCategories []string |
|||
|
|||
tagMap map[string][]model.Tag |
|||
} |
|||
|
|||
// Map lazy-loads the map of tags, which is only
|
|||
// used when listing all of them.
|
|||
func (it IndexTags) Map() map[string][]model.Tag { |
|||
// Set up the map
|
|||
it.tagMap = make(map[string][]model.Tag, len(model.TagTypes)) |
|||
for _, tagType := range model.TagTypes { |
|||
it.tagMap[tagType] = make([]model.Tag, 0, 64) |
|||
} |
|||
|
|||
// Organize
|
|||
for _, tag := range it.Tags { |
|||
it.tagMap[tag.Type] = append(it.tagMap[tag.Type], tag) |
|||
} |
|||
|
|||
return it.tagMap |
|||
} |
|||
|
|||
// Setup sets up the page model and the base, and should
|
|||
// be run after the details have been filled in.
|
|||
func (it *IndexTags) Setup(user *auth.User, viewPath string) { |
|||
title := it.Type |
|||
if it.Type != "" { |
|||
title = "All" |
|||
} |
|||
|
|||
it.setupMenu() |
|||
it.setupBase(user, fmt.Sprintf("%s Tags", title), viewPath) |
|||
} |
@ -0,0 +1,19 @@ |
|||
package viewmodel |
|||
|
|||
import "git.aiterp.net/gisle/wrouter/auth" |
|||
|
|||
// Message is a simple viewmodel for the message pages
|
|||
type Message struct { |
|||
Base |
|||
Title string |
|||
Text string |
|||
Danger bool |
|||
} |
|||
|
|||
// NewMessage creates a message model
|
|||
func NewMessage(user *auth.User, title string, danger bool, text string) *Message { |
|||
msg := &Message{Title: title, Text: text, Danger: danger} |
|||
msg.setupBase(user, title, "") |
|||
|
|||
return msg |
|||
} |
@ -0,0 +1,9 @@ |
|||
package viewmodel |
|||
|
|||
import "git.aiterp.net/AiteRP/aitestory/model" |
|||
|
|||
// PageBase describes the basic parts of a page.
|
|||
type PageBase struct { |
|||
Page *model.Page |
|||
HideMenu bool |
|||
} |
@ -0,0 +1,26 @@ |
|||
package viewmodel |
|||
|
|||
import ( |
|||
"git.aiterp.net/AiteRP/aitestory/model" |
|||
"git.aiterp.net/gisle/wrouter/auth" |
|||
) |
|||
|
|||
// PageCreate is the view model for the page create form.
|
|||
type PageCreate struct { |
|||
Base |
|||
IndexBase |
|||
|
|||
Page model.Page |
|||
Error string |
|||
TagInput string |
|||
} |
|||
|
|||
// Setup sets the view model up.
|
|||
func (pf *PageCreate) Setup(user *auth.User) { |
|||
pf.setupMenu() |
|||
pf.setupBase(user, "Create", "/page/create") |
|||
|
|||
pf.Categories = model.PageCategories |
|||
|
|||
pf.Page.Defaults() |
|||
} |
@ -0,0 +1,19 @@ |
|||
package viewmodel |
|||
|
|||
import ( |
|||
"fmt" |
|||
|
|||
"git.aiterp.net/gisle/wrouter/auth" |
|||
) |
|||
|
|||
// PageDelete is the view model used to view the page's delete form.
|
|||
type PageDelete struct { |
|||
Base |
|||
PageBase |
|||
} |
|||
|
|||
// Setup sets up the page view model. It should be calles last
|
|||
func (pv *PageDelete) Setup(user *auth.User) { |
|||
pv.HideMenu = false |
|||
pv.setupBase(user, pv.Page.Name, fmt.Sprintf("/page/delete/%s", pv.Page.ID)) |
|||
} |
@ -0,0 +1,20 @@ |
|||
package viewmodel |
|||
|
|||
import ( |
|||
"fmt" |
|||
|
|||
"git.aiterp.net/gisle/wrouter/auth" |
|||
) |
|||
|
|||
// PageSource is the view model used to view the page's source.
|
|||
// It's got no extra data on its own.
|
|||
type PageSource struct { |
|||
Base |
|||
PageBase |
|||
} |
|||
|
|||
// Setup sets up the page view model. It should be calles last
|
|||
func (pv *PageSource) Setup(user *auth.User) { |
|||
pv.HideMenu = false |
|||
pv.setupBase(user, pv.Page.Name, fmt.Sprintf("/page/source/%s", pv.Page.ID)) |
|||
} |
@ -1,15 +1,20 @@ |
|||
package viewmodel |
|||
|
|||
import ( |
|||
"git.aiterp.net/AiteRP/aitestory/model" |
|||
"fmt" |
|||
|
|||
"git.aiterp.net/gisle/wrouter/auth" |
|||
) |
|||
|
|||
// PageView is the view model used to view the page. It's got no extra
|
|||
// data on its own.
|
|||
type PageView struct { |
|||
Base |
|||
Page *model.Page |
|||
PageBase |
|||
} |
|||
|
|||
// Setup sets up the page view model. It should be calles last
|
|||
func (pv *PageView) Setup(user *auth.User) { |
|||
pv.setupBase(user, pv.Page.Name) |
|||
pv.HideMenu = false |
|||
pv.setupBase(user, pv.Page.Name, fmt.Sprintf("/page/%s", pv.Page.ID)) |
|||
} |
@ -1,46 +0,0 @@ |
|||
package viewmodel |
|||
|
|||
import ( |
|||
"fmt" |
|||
|
|||
"git.aiterp.net/AiteRP/aitestory/model" |
|||
"git.aiterp.net/gisle/wrouter/auth" |
|||
) |
|||
|
|||
// TagList is a view model for rendering the tag lists.
|
|||
type TagList struct { |
|||
Base |
|||
Type string |
|||
Tags []model.Tag |
|||
TagCategories []string |
|||
|
|||
tagMap map[string][]model.Tag |
|||
} |
|||
|
|||
// Map lazy-loads the map of tags, which is only
|
|||
// used when listing all of them.
|
|||
func (tl TagList) Map() map[string][]model.Tag { |
|||
// Set up the map
|
|||
tl.tagMap = make(map[string][]model.Tag, len(model.TagTypes)) |
|||
for _, tagType := range model.TagTypes { |
|||
tl.tagMap[tagType] = make([]model.Tag, 0, 64) |
|||
} |
|||
|
|||
// Organize
|
|||
for _, tag := range tl.Tags { |
|||
tl.tagMap[tag.Type] = append(tl.tagMap[tag.Type], tag) |
|||
} |
|||
|
|||
return tl.tagMap |
|||
} |
|||
|
|||
// Setup sets up the page model and the base, and should
|
|||
// be run after the details have been filled in.
|
|||
func (tl *TagList) Setup(user *auth.User) { |
|||
title := tl.Type |
|||
if tl.Type != "" { |
|||
title = "All" |
|||
} |
|||
|
|||
tl.setupBase(user, fmt.Sprintf("%s Tags", title)) |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue