Page is done

This commit is contained in:
2017-10-08 15:18:38 +02:00
parent d15e4e967e
commit f471aed610
18 changed files with 453 additions and 43 deletions
+7 -7
View File
@@ -21,13 +21,13 @@ func (category *PageCategory) URLRoot() string {
// a limited selection of categories. I may move it to a configuration
// or the database, but for now I think this list is pretty fixed
var PageCategories = []PageCategory{
{"OoC", "OoC", "ooc", "OoC content is for announcements, scheduling, general information, or anything that is not in-universe"},
{"Info", "Info", "info", "Information gained during and between RP sessions"},
{"News", "News", "news", "News stories that might be pertinent to ongoing plots"},
{"Item", "Items", "item", "Items relevant to plots, that is more than just a document saved on a character's own omni-tool"},
{"Document", "Documents", "document", "Data files, shadow broker dossiers, and other data that is not inside an item"},
{"Background", "Background", "background", "Rumors, suspicious persons, or inter-RP occurences that may be noticed"},
{"Story", "Stories", "story", "Background stories and inter-RP character intearactions"},
{"OoC", "OoC", "O", "OoC content is for announcements, scheduling, general information, or anything that is not in-universe"},
{"Info", "Info", "i", "Information gained during and between RP sessions"},
{"News", "News", "N", "News stories that might be pertinent to ongoing plots"},
{"Item", "Items", "I", "Items relevant to plots, that is more than just a document saved on a character's own omni-tool"},
{"Document", "Document", "D", "Data files, shadow broker dossiers, and other data that is not inside an item"},
{"Background", "Background", "B", "Rumors, suspicious persons, or inter-RP occurences that may be noticed"},
{"Story", "Stories", "S", "Background stories and inter-RP character intearactions"},
}
var pageCategories []string
+20 -5
View File
@@ -23,6 +23,17 @@ type Header struct {
PrimaryTag *Tag `json:"primaryTag"`
}
// CategoryInfo gets information about the category
func (header *Header) CategoryInfo() PageCategory {
for _, category := range PageCategories {
if category.Key == header.Category {
return category
}
}
return PageCategory{"Unknown", "Unknown", "?", ""}
}
// ListHeaders grabs all the general pages from
// the database to list them
func ListHeaders() ([]Header, error) {
@@ -31,7 +42,8 @@ func ListHeaders() ([]Header, error) {
FROM page
LEFT JOIN page_tag ON (page.id = page_tag.page_id AND page_tag.primary = true)
LEFT JOIN tag ON (tag.id = page_tag.tag_id)
WHERE page.specific=false AND page.published=true AND page.unlisted=false;
WHERE page.specific=false AND page.published=true AND page.unlisted=false
ORDER BY page.fictional_date DESC
`
db := server.Main.DB
@@ -63,7 +75,8 @@ func ListHeadersByCategory(category string) ([]Header, error) {
FROM page
LEFT JOIN page_tag ON (page.id = page_tag.page_id AND page_tag.primary = true)
LEFT JOIN tag ON (tag.id = page_tag.tag_id)
WHERE page.specific=false AND page.published=true AND page.unlisted=false AND page.category = ?;
WHERE page.specific=false AND page.published=true AND page.unlisted=false AND page.category = ?
ORDER BY page.fictional_date DESC
`
db := server.Main.DB
@@ -97,7 +110,8 @@ func ListHeadersByTag(category string, tag *Tag) ([]Header, error) {
RIGHT JOIN page ON page.id = page_tag.page_id
LEFT JOIN (page_tag AS pt2) ON (page.id = pt2.page_id AND pt2.primary = true)
LEFT JOIN (tag AS tag) ON (tag.id = pt2.tag_id)
WHERE page_tag.tag_id=?
WHERE page_tag.tag_id=? AND page.unlisted=false AND page.published=true
ORDER BY page.fictional_date DESC
`
const query2 = `
SELECT page.id,page.name,page.author,page.category,page.fictional_date,page.publish_date,page.edit_date,page.dated,tag.id,tag.type,tag.name
@@ -105,7 +119,8 @@ func ListHeadersByTag(category string, tag *Tag) ([]Header, error) {
RIGHT JOIN page ON page.id = page_tag.page_id
LEFT JOIN (page_tag AS pt2) ON (page.id = pt2.page_id AND pt2.primary = true)
LEFT JOIN (tag AS tag) ON (tag.id = pt2.tag_id)
WHERE page_tag.tag_id=? AND page.category=?
WHERE page_tag.tag_id=? AND page.category=? AND page.unlisted=false AND page.published=true
ORDER BY page.fictional_date DESC
`
if tag == nil {
@@ -190,7 +205,7 @@ func parseHeader(header *Header, rows *sql.Rows) error {
rows.Scan(&header.ID, &header.Name, &header.Author, &header.Category, &fictionalDate, &publishDate, &editDate, &header.Dated, &tagID, &tagType, &tagName)
if tagID != "" {
header.PrimaryTag = &Tag{tagID, tagName, tagType}
header.PrimaryTag = &Tag{tagID, tagType, tagName}
}
header.FictionalDate, err = time.Parse("2006-01-02 15:04:05", fictionalDate)
+30 -10
View File
@@ -4,6 +4,7 @@ import (
"database/sql"
"errors"
"fmt"
"html/template"
"net/url"
"time"
@@ -46,6 +47,7 @@ type Page struct {
prevTags []Tag
cachedOutput string
primaryTag *Tag
}
// Defaults fills in the default details for a page, suited for populating a form
@@ -99,6 +101,10 @@ func (page *Page) Insert() error {
}
}
if len(page.Tags) > 0 {
page.primaryTag = &page.Tags[0]
}
return nil
}
@@ -157,6 +163,9 @@ func (page *Page) Update() error {
return err
}
}
if len(page.Tags) > 0 {
page.primaryTag = &page.Tags[0]
}
return nil
}
@@ -184,29 +193,33 @@ func (page *Page) Delete() error {
}
// Content parses the content of the page
func (page *Page) Content() (string, error) {
if page.cachedOutput != "" {
return page.cachedOutput, nil
}
func (page *Page) Content() (template.HTML, error) {
if page.Type == "Markdown" {
// TODO: Convert [[Ehanis Tioran]] to [Ehanis Tioran](https://wiki.aiterp.net/index.php?title=Ehanis%20Tioran)
unsafe := blackfriday.MarkdownCommon([]byte(page.Source))
page.cachedOutput = string(bluemonday.UGCPolicy().SanitizeBytes(unsafe))
output := string(bluemonday.UGCPolicy().SanitizeBytes(unsafe))
return page.cachedOutput, nil
return template.HTML(output), nil
}
return "", fmt.Errorf("Page type '%s' is not supported", page.Type)
}
// PrimaryTag gets the page's primary tag
func (page *Page) PrimaryTag() Tag {
if page.primaryTag == nil {
return Tag{}
}
return *page.primaryTag
}
// ParseForm validates the values in a form and sets the page's values whenever possible regardless
// so that it can be pushed to the viewmodel to allow the user to correct their mistakes without fear
// of losing their hard work
func (page *Page) ParseForm(form url.Values) []error {
errors := make([]error, 0, 4)
page.cachedOutput = ""
err := formparser.String(form.Get("name"), &page.Name, 2, 192)
if err != nil {
@@ -266,10 +279,11 @@ func FindPage(id string) (*Page, error) {
WHERE id=?
`
const selectPageTags = `
SELECT tag.id,tag.type,tag.name
SELECT tag.id,tag.type,tag.name,page_tag.primary
FROM page_tag
RIGHT JOIN tag ON (tag.id = page_tag.tag_id)
WHERE page_tag.page_id = ?
ORDER BY tag.type DESC, tag.name
`
db := server.Main.DB
@@ -297,9 +311,15 @@ func FindPage(id string) (*Page, error) {
page.Tags = make([]Tag, 0, 64)
for rows.Next() {
primary := false
tag := Tag{}
rows.Scan(&tag.ID, &tag.Type, &tag.Name)
rows.Scan(&tag.ID, &tag.Type, &tag.Name, &primary)
page.Tags = append(page.Tags, tag)
if primary {
page.primaryTag = &tag
}
}
return page, nil
+1 -1
View File
@@ -259,7 +259,7 @@ func TestPage(t *testing.T) {
t.Errorf("page.Content: %s", err)
}
assertEquals(t, "page.Content()", content, "<h1>Returning Va’ynna’s Omni-Tool</h1>\n\n<p>Additional Content is additional</p>\n")
assertEquals(t, "page.Content()", string(content), "<h1>Returning Va’ynna’s Omni-Tool</h1>\n\n<p>Additional Content is additional</p>\n")
})
t.Run("WikiURL", func(t *testing.T) {
+12
View File
@@ -2,6 +2,7 @@ package model
import (
"errors"
"fmt"
"strings"
"git.aiterp.net/AiteRP/aitestory/server"
@@ -24,6 +25,17 @@ type Tag struct {
Name string
}
// Icon is the API used to get the icon for the tag.
func (tag Tag) Icon() string {
return tag.Type[0:1]
}
// CSSCLass gets the CSS class that colors the tag on the
// page list
func (tag Tag) CSSCLass() string {
return fmt.Sprintf("ttype-%s", strings.ToLower(tag.Type))
}
// Insert adds the tag to the database, giving it a new unique ID
func (tag *Tag) Insert() error {
db := server.Main.DB