From 279f73187b9de250de3b1788d1ce543c60832bc6 Mon Sep 17 00:00:00 2001 From: Anhgelus Morhtuuzh Date: Tue, 10 Dec 2024 19:00:56 +0100 Subject: feat(custom): config and generation --- data.go | 93 ++++++++++++++++++++++++++++++++++++--- main.go | 14 ++++++ schema.json | 3 ++ templates/page/custom_page.gohtml | 8 ++++ 4 files changed, 111 insertions(+), 7 deletions(-) create mode 100644 templates/page/custom_page.gohtml diff --git a/data.go b/data.go index 49df295..f809e3f 100644 --- a/data.go +++ b/data.go @@ -1,18 +1,31 @@ package main import ( + "encoding/json" "github.com/anhgelus/golatt" "html/template" + "log/slog" + "os" "strconv" + "strings" +) + +const ( + TitleContentType = "title" + SubtitleContentType = "subtitle" + ParagraphContentType = "paragraph" + ListContentType = "list" + OrderedListContentType = "ordered_list" ) type Config struct { - Image string `json:"image"` - Description string `json:"description"` - Person *Person `json:"person"` - Color *Color `json:"colors"` - Links []*Link `json:"links"` - Legal *Legal `json:"legal"` + Image string `json:"image"` + Description string `json:"description"` + Person *Person `json:"person"` + Color *Color `json:"colors"` + Links []*Link `json:"links"` + Legal *Legal `json:"legal"` + CustomPages []string `json:"custom_pages"` } type Person struct { @@ -79,7 +92,49 @@ func (c *Config) GetBackgroundImage() template.CSS { } func (c *Config) GetTextColor() template.CSS { - return template.CSS("--text-color: " + c.Color.Text + ";") + return c.Color.GetTextColor() +} + +type CustomPage struct { + Title string `json:"title"` + URI string `json:"uri"` + Image string `json:"image"` + Description string `json:"description"` + Color *Color `json:"colors"` + Content []*CustomContent `json:"content"` +} + +type CustomContent struct { + Type string `json:"type"` + Content string `json:"content"` +} + +type Content interface { + Get() template.HTML +} + +func (c *Config) LoadCustomPages() ([]*CustomPage, error) { + if c.CustomPages == nil { + return nil, nil + } + var pages []*CustomPage + for _, cp := range c.CustomPages { + b, err := os.ReadFile(cp) + if err != nil { + return nil, err + } + var p *CustomPage + err = json.Unmarshal(b, p) + if err != nil { + return nil, err + } + pages = append(pages, p) + } + return pages, nil +} + +func (t *Color) GetTextColor() template.CSS { + return template.CSS("--text-color: " + t.Text + ";") } func (b *ButtonColor) GetTextColor() template.CSS { @@ -93,3 +148,27 @@ func (b *ButtonColor) GetBackground() template.CSS { func (t *Color) GetTagColor() template.CSS { return template.CSS("--tag-hover: " + t.TagHover + ";") } + +func (c *CustomContent) Get() template.HTML { + if c.Type == TitleContentType { + return template.HTML("

" + c.Content + "

") + } else if c.Type == SubtitleContentType { + return template.HTML("

" + c.Content + "

") + } else if c.Type == ParagraphContentType { + return template.HTML("

" + c.Content + "

") + } else if c.Type == ListContentType { + v := "" + for _, s := range strings.Split(c.Content, "--") { + v += "
  • " + strings.Trim(s, " ") + "
  • " + } + return template.HTML("") + } else if c.Type == OrderedListContentType { + v := "" + for _, s := range strings.Split(c.Content, "--") { + v += "
  • " + strings.Trim(s, " ") + "
  • " + } + return template.HTML("
      " + v + "
    ") + } + slog.Warn("Unknown type", "type", c.Type, "value", c.Content) + return "" +} diff --git a/main.go b/main.go index 57ef485..cd23aea 100644 --- a/main.go +++ b/main.go @@ -50,6 +50,10 @@ func main() { if err != nil { panic(err) } + customPages, err := cfg.LoadCustomPages() + if err != nil { + panic(err) + } g := golatt.New(templates) g.DefaultSeoData = &golatt.SeoData{ Image: cfg.Image, @@ -74,6 +78,16 @@ func main() { &cfg). Handle() + for _, cp := range customPages { + g.NewTemplate("custom_page", + cp.URI, + cp.Title, + cp.Image, + cp.Description, + cp). + Handle() + } + g.NotFoundHandler = func(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, "/", http.StatusTemporaryRedirect) } diff --git a/schema.json b/schema.json index 2678ecf..dcc75ef 100644 --- a/schema.json +++ b/schema.json @@ -176,6 +176,9 @@ "image", "tags" ] + }, + "custom_page": { + "type": "array" } }, "additionalProperties": false, diff --git a/templates/page/custom_page.gohtml b/templates/page/custom_page.gohtml new file mode 100644 index 0000000..15bd0e9 --- /dev/null +++ b/templates/page/custom_page.gohtml @@ -0,0 +1,8 @@ +{{define "body"}} +
    +

    {{ .Title }}

    + {{ range $content := .Content }} + {{ .Get }} + {{ end }} +
    +{{end}} -- cgit v1.2.3 From e379601ec1f1ca70f955f7ea9dd07775fb4da93b Mon Sep 17 00:00:00 2001 From: Anhgelus Morhtuuzh Date: Tue, 10 Dec 2024 19:13:44 +0100 Subject: fix(custom): missing method for new config --- data.go | 53 +++++++++++++++++++++++++++++++++++++++++------------ main.go | 1 + schema.json | 2 +- 3 files changed, 43 insertions(+), 13 deletions(-) diff --git a/data.go b/data.go index f809e3f..ad6fcea 100644 --- a/data.go +++ b/data.go @@ -18,6 +18,12 @@ const ( OrderedListContentType = "ordered_list" ) +type ConfigData interface { + GetTextColor() template.CSS + GetBackground() template.CSS + GetBackgroundImage() template.CSS +} + type Config struct { Image string `json:"image"` Description string `json:"description"` @@ -76,15 +82,7 @@ type Legal struct { } func (c *Config) GetBackground() template.CSS { - bg := c.Color.Background - css := "background: " + bg.Type + "-gradient(" - if bg.Type == "linear" { - css += strconv.Itoa(int(bg.Angle)) + "deg," - } - for _, c := range bg.Colors { - css += c.Color + " " + strconv.Itoa(int(c.Position)) + "%," - } - return template.CSS(css[:len(css)-1] + ");") + return c.Color.GetBackground() } func (c *Config) GetBackgroundImage() template.CSS { @@ -115,6 +113,7 @@ type Content interface { func (c *Config) LoadCustomPages() ([]*CustomPage, error) { if c.CustomPages == nil { + println("null") return nil, nil } var pages []*CustomPage @@ -123,12 +122,12 @@ func (c *Config) LoadCustomPages() ([]*CustomPage, error) { if err != nil { return nil, err } - var p *CustomPage - err = json.Unmarshal(b, p) + var p CustomPage + err = json.Unmarshal(b, &p) if err != nil { return nil, err } - pages = append(pages, p) + pages = append(pages, &p) } return pages, nil } @@ -137,6 +136,18 @@ func (t *Color) GetTextColor() template.CSS { return template.CSS("--text-color: " + t.Text + ";") } +func (t *Color) GetBackground() template.CSS { + bg := t.Background + css := "background: " + bg.Type + "-gradient(" + if bg.Type == "linear" { + css += strconv.Itoa(int(bg.Angle)) + "deg," + } + for _, c := range bg.Colors { + css += c.Color + " " + strconv.Itoa(int(c.Position)) + "%," + } + return template.CSS(css[:len(css)-1] + ");") +} + func (b *ButtonColor) GetTextColor() template.CSS { return template.CSS("--text-color: " + b.Text + ";--text-color-hover: " + b.TextHover + ";") } @@ -149,6 +160,18 @@ func (t *Color) GetTagColor() template.CSS { return template.CSS("--tag-hover: " + t.TagHover + ";") } +func (p *CustomPage) GetTextColor() template.CSS { + return p.Color.GetTextColor() +} + +func (p *CustomPage) GetBackgroundImage() template.CSS { + return template.CSS("--background-image: url(" + golatt.GetStaticPath(p.Image) + ");") +} + +func (p *CustomPage) GetBackground() template.CSS { + return p.Color.GetBackground() +} + func (c *CustomContent) Get() template.HTML { if c.Type == TitleContentType { return template.HTML("

    " + c.Content + "

    ") @@ -159,12 +182,18 @@ func (c *CustomContent) Get() template.HTML { } else if c.Type == ListContentType { v := "" for _, s := range strings.Split(c.Content, "--") { + if len(strings.Trim(s, " ")) == 0 { + continue + } v += "
  • " + strings.Trim(s, " ") + "
  • " } return template.HTML("") } else if c.Type == OrderedListContentType { v := "" for _, s := range strings.Split(c.Content, "--") { + if len(strings.Trim(s, " ")) == 0 { + continue + } v += "
  • " + strings.Trim(s, " ") + "
  • " } return template.HTML("
      " + v + "
    ") diff --git a/main.go b/main.go index cd23aea..34086cc 100644 --- a/main.go +++ b/main.go @@ -79,6 +79,7 @@ func main() { Handle() for _, cp := range customPages { + slog.Info("Creating custom page...", "title", cp.Title, "uri", cp.URI) g.NewTemplate("custom_page", cp.URI, cp.Title, diff --git a/schema.json b/schema.json index dcc75ef..9b325c3 100644 --- a/schema.json +++ b/schema.json @@ -177,7 +177,7 @@ "tags" ] }, - "custom_page": { + "custom_pages": { "type": "array" } }, -- cgit v1.2.3 From 9b6819f25fc860ea1c2dc84b61b7576b73aaa78c Mon Sep 17 00:00:00 2001 From: Anhgelus Morhtuuzh Date: Tue, 10 Dec 2024 19:19:41 +0100 Subject: feat(custom): better style and navbar --- scss/main.scss | 12 ++++++++++++ templates/page/custom_page.gohtml | 7 ++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/scss/main.scss b/scss/main.scss index bd22152..6c1f316 100644 --- a/scss/main.scss +++ b/scss/main.scss @@ -236,3 +236,15 @@ h4 { padding: 0 2rem 1rem 2rem; border-radius: 32px; } + +.custom-page { + & h2 { + margin-bottom: 1rem; + } + & h3 { + margin-bottom: 0.5rem; + } + & ul { + list-style: disc inside; + } +} diff --git a/templates/page/custom_page.gohtml b/templates/page/custom_page.gohtml index 15bd0e9..4cb8078 100644 --- a/templates/page/custom_page.gohtml +++ b/templates/page/custom_page.gohtml @@ -1,6 +1,11 @@ {{define "body"}}
    -

    {{ .Title }}

    +
    +

    {{ .Title }}

    + +
    {{ range $content := .Content }} {{ .Get }} {{ end }} -- cgit v1.2.3 From a5955c32fb3b22e37769df49196ddab7b7d53b7d Mon Sep 17 00:00:00 2001 From: Anhgelus Morhtuuzh Date: Tue, 10 Dec 2024 19:55:05 +0100 Subject: feat(custom): support links --- data.go | 40 ++++++++++++++++++++++++++++++++++++--- scss/main.scss | 7 +++++++ templates/page/custom_page.gohtml | 4 +--- 3 files changed, 45 insertions(+), 6 deletions(-) diff --git a/data.go b/data.go index ad6fcea..ad51683 100644 --- a/data.go +++ b/data.go @@ -2,6 +2,7 @@ package main import ( "encoding/json" + "fmt" "github.com/anhgelus/golatt" "html/template" "log/slog" @@ -16,6 +17,7 @@ const ( ParagraphContentType = "paragraph" ListContentType = "list" OrderedListContentType = "ordered_list" + ButtonsContentType = "links" ) type ConfigData interface { @@ -172,7 +174,15 @@ func (p *CustomPage) GetBackground() template.CSS { return p.Color.GetBackground() } -func (c *CustomContent) Get() template.HTML { +func (p *CustomPage) GetContent() template.HTML { + var res template.HTML + for _, c := range p.Content { + res += c.Get(p) + } + return res +} + +func (c *CustomContent) Get(p *CustomPage) template.HTML { if c.Type == TitleContentType { return template.HTML("

    " + c.Content + "

    ") } else if c.Type == SubtitleContentType { @@ -191,12 +201,36 @@ func (c *CustomContent) Get() template.HTML { } else if c.Type == OrderedListContentType { v := "" for _, s := range strings.Split(c.Content, "--") { - if len(strings.Trim(s, " ")) == 0 { + if len(strings.TrimSpace(s)) == 0 { continue } - v += "
  • " + strings.Trim(s, " ") + "
  • " + v += "
  • " + strings.TrimSpace(s) + "
  • " } return template.HTML("
      " + v + "
    ") + } else if c.Type == ButtonsContentType { + // [Bonsoir](/hello) -- [Bonjour](/not_hello) + v := "" + for _, s := range strings.Split(c.Content, "--") { + if len(strings.TrimSpace(s)) == 0 { + continue + } + sp := strings.Split(s, "](") + if len(sp) != 2 { + slog.Warn("Invalid button", "s", s) + continue + } + url := strings.TrimSpace(sp[1]) + v += fmt.Sprintf( + ``, + url[:len(url)-1], + strings.TrimSpace(sp[0])[1:], + ) + } + return template.HTML(fmt.Sprintf( + ``, + p.Color.Button.GetBackground()+p.Color.Button.GetTextColor(), + v, + )) } slog.Warn("Unknown type", "type", c.Type, "value", c.Content) return "" diff --git a/scss/main.scss b/scss/main.scss index 6c1f316..bef8c81 100644 --- a/scss/main.scss +++ b/scss/main.scss @@ -247,4 +247,11 @@ h4 { & ul { list-style: disc inside; } + & .links { + margin-top: 1rem; + margin-bottom: 1rem; + &:last-child { + margin-bottom: 0; + } + } } diff --git a/templates/page/custom_page.gohtml b/templates/page/custom_page.gohtml index 4cb8078..83a4983 100644 --- a/templates/page/custom_page.gohtml +++ b/templates/page/custom_page.gohtml @@ -6,8 +6,6 @@ Home - {{ range $content := .Content }} - {{ .Get }} - {{ end }} + {{ .GetContent }}
    {{end}} -- cgit v1.2.3 From 8f86a7299d75b2905e4e6eb61f43750c51ed48e4 Mon Sep 17 00:00:00 2001 From: Anhgelus Morhtuuzh Date: Tue, 10 Dec 2024 20:34:11 +0100 Subject: feat(config): json schema for custom pages --- config.schema.json | 193 ++++++++++++++++++++++++++++++++++++++++++++++++ custom_page.schema.json | 117 +++++++++++++++++++++++++++++ schema.json | 193 ------------------------------------------------ 3 files changed, 310 insertions(+), 193 deletions(-) create mode 100644 config.schema.json create mode 100644 custom_page.schema.json delete mode 100644 schema.json diff --git a/config.schema.json b/config.schema.json new file mode 100644 index 0000000..9b325c3 --- /dev/null +++ b/config.schema.json @@ -0,0 +1,193 @@ +{ + "type": "object", + "properties": { + "colors": { + "type": "object", + "properties": { + "background": { + "type": "object", + "properties": { + "angle": { + "type": "integer", + "format": "int32", + "minimum": 0, + "maximum": 359 + }, + "colors": { + "type": "array", + "items": { + "type": "object", + "properties": { + "color": { + "type": "string" + }, + "position": { + "type": "integer", + "format": "int32", + "minimum": 0, + "maximum": 100 + } + }, + "additionalProperties": false, + "required": [ + "color", + "position" + ] + } + }, + "type": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "type", + "angle", + "colors" + ] + }, + "buttons": { + "type": "object", + "properties": { + "background": { + "type": "string" + }, + "background_hover": { + "type": "string" + }, + "text": { + "type": "string" + }, + "text_hover": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "text", + "text_hover", + "background", + "background_hover" + ] + }, + "text": { + "type": "string" + }, + "tag_hover": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "background", + "buttons", + "text", + "tag_hover" + ] + }, + "description": { + "type": "string" + }, + "image": { + "type": "string" + }, + "legal": { + "type": "object", + "properties": { + "font_source": { + "type": "string" + }, + "images_source": { + "type": "array", + "items": { + "type": "string" + } + }, + "legal_information_link": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "legal_information_link", + "images_source", + "font_source" + ] + }, + "links": { + "type": "array", + "items": { + "type": "object", + "properties": { + "content": { + "type": "string" + }, + "link": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "link", + "content" + ] + } + }, + "person": { + "type": "object", + "properties": { + "image": { + "type": "string" + }, + "name": { + "type": "string" + }, + "pronouns": { + "type": "string" + }, + "tags": { + "type": "array", + "items": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "name": { + "type": "string" + }, + "link": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "name", + "description", + "link" + ] + } + } + }, + "additionalProperties": false, + "required": [ + "name", + "pronouns", + "image", + "tags" + ] + }, + "custom_pages": { + "type": "array" + } + }, + "additionalProperties": false, + "required": [ + "image", + "description", + "person", + "colors", + "links", + "legal" + ] +} diff --git a/custom_page.schema.json b/custom_page.schema.json new file mode 100644 index 0000000..c7a1907 --- /dev/null +++ b/custom_page.schema.json @@ -0,0 +1,117 @@ +{ + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "uri": { + "type": "string" + }, + "image": { + "type": "string" + }, + "description": { + "type": "string" + }, + "colors": { + "type": "object", + "properties": { + "text": { + "type": "string" + }, + "tag_hover": { + "type": "string" + }, + "background": { + "type": "object", + "properties": { + "type": { + "type": "string" + }, + "angle": { + "type": "number" + }, + "colors": { + "type": "array", + "items": { + "type": "object", + "properties": { + "color": { + "type": "string" + }, + "position": { + "type": "number" + } + }, + "required": [ + "color", + "position" + ] + } + } + }, + "required": [ + "type", + "angle", + "colors" + ] + }, + "buttons": { + "type": "object", + "properties": { + "text": { + "type": "string" + }, + "text_hover": { + "type": "string" + }, + "background": { + "type": "string" + }, + "background_hover": { + "type": "string" + } + }, + "required": [ + "text", + "text_hover", + "background", + "background_hover" + ] + } + }, + "required": [ + "text", + "tag_hover", + "background", + "buttons" + ] + }, + "content": { + "type": "array", + "items": { + "type": "object", + "properties": { + "type": { + "type": "string" + }, + "content": { + "type": "string" + } + }, + "required": [ + "type", + "content" + ] + } + } + }, + "required": [ + "title", + "uri", + "image", + "description", + "colors", + "content" + ] +} \ No newline at end of file diff --git a/schema.json b/schema.json deleted file mode 100644 index 9b325c3..0000000 --- a/schema.json +++ /dev/null @@ -1,193 +0,0 @@ -{ - "type": "object", - "properties": { - "colors": { - "type": "object", - "properties": { - "background": { - "type": "object", - "properties": { - "angle": { - "type": "integer", - "format": "int32", - "minimum": 0, - "maximum": 359 - }, - "colors": { - "type": "array", - "items": { - "type": "object", - "properties": { - "color": { - "type": "string" - }, - "position": { - "type": "integer", - "format": "int32", - "minimum": 0, - "maximum": 100 - } - }, - "additionalProperties": false, - "required": [ - "color", - "position" - ] - } - }, - "type": { - "type": "string" - } - }, - "additionalProperties": false, - "required": [ - "type", - "angle", - "colors" - ] - }, - "buttons": { - "type": "object", - "properties": { - "background": { - "type": "string" - }, - "background_hover": { - "type": "string" - }, - "text": { - "type": "string" - }, - "text_hover": { - "type": "string" - } - }, - "additionalProperties": false, - "required": [ - "text", - "text_hover", - "background", - "background_hover" - ] - }, - "text": { - "type": "string" - }, - "tag_hover": { - "type": "string" - } - }, - "additionalProperties": false, - "required": [ - "background", - "buttons", - "text", - "tag_hover" - ] - }, - "description": { - "type": "string" - }, - "image": { - "type": "string" - }, - "legal": { - "type": "object", - "properties": { - "font_source": { - "type": "string" - }, - "images_source": { - "type": "array", - "items": { - "type": "string" - } - }, - "legal_information_link": { - "type": "string" - } - }, - "additionalProperties": false, - "required": [ - "legal_information_link", - "images_source", - "font_source" - ] - }, - "links": { - "type": "array", - "items": { - "type": "object", - "properties": { - "content": { - "type": "string" - }, - "link": { - "type": "string" - } - }, - "additionalProperties": false, - "required": [ - "link", - "content" - ] - } - }, - "person": { - "type": "object", - "properties": { - "image": { - "type": "string" - }, - "name": { - "type": "string" - }, - "pronouns": { - "type": "string" - }, - "tags": { - "type": "array", - "items": { - "type": "object", - "properties": { - "description": { - "type": "string" - }, - "name": { - "type": "string" - }, - "link": { - "type": "string" - } - }, - "additionalProperties": false, - "required": [ - "name", - "description", - "link" - ] - } - } - }, - "additionalProperties": false, - "required": [ - "name", - "pronouns", - "image", - "tags" - ] - }, - "custom_pages": { - "type": "array" - } - }, - "additionalProperties": false, - "required": [ - "image", - "description", - "person", - "colors", - "links", - "legal" - ] -} -- cgit v1.2.3 From 40fe301b5462b84e06747ff30add26b4259d38a4 Mon Sep 17 00:00:00 2001 From: Anhgelus Morhtuuzh Date: Tue, 10 Dec 2024 20:39:13 +0100 Subject: fix(navigation): not updating style and background image --- index.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/index.ts b/index.ts index 24951c2..c3f46b0 100644 --- a/index.ts +++ b/index.ts @@ -23,10 +23,7 @@ function changePage(href: string) { const doc = new DOMParser().parseFromString(html, "text/html") window.history.pushState({}, "", href) document.title = doc.title - const distMain = doc.querySelector("main") - const currentMain = document.querySelector("main") - if (distMain === null || currentMain === null) document.body = doc.body - else currentMain.innerHTML = distMain.innerHTML + document.body = doc.body setupEvents() scrollTo({ top: 0, -- cgit v1.2.3