diff --git a/assets/css/main.scss b/assets/css/main.scss
index c8f0344..dc6ad7d 100644
--- a/assets/css/main.scss
+++ b/assets/css/main.scss
@@ -10,21 +10,7 @@ $container-max-widths: (
@import "bootstrap/scss/bootstrap.scss";
-// Local classes
-
-.post-form {
- display: grid;
- grid-template-rows: min-content auto min-content;
- position: absolute;
- top: 0;
- bottom: 0;
- left: 0;
- right: 0;
-}
-
-.post-form textarea {
- height: 100%;
-}
+// Post list
.postlist .post img {
max-width: 300px;
@@ -32,6 +18,49 @@ $container-max-widths: (
max-height: 300px;
}
+.postlist .post-date {
+ font-size: 0.9rem;
+}
+
+// Post form
+
+// Post edit page styling
+.post-edit-page {
+ height: 100vh;
+}
+
+.post-edit-page main {
+ display: flex;
+ flex-direction: column;
+ overflow: hidden;
+}
+
+.post-edit-page .post-form {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ min-height: 0;
+}
+
+.post-edit-page .post-form .row {
+ flex: 1;
+ display: flex;
+ min-height: 0;
+}
+
+.post-edit-page .post-form .col-md-9 {
+ display: flex;
+ flex-direction: column;
+}
+
+.post-edit-page .post-form textarea {
+ flex: 1;
+ resize: vertical;
+ min-height: 300px;
+}
+
+
+
.show-upload figure img {
max-width: 100vw;
height: auto;
diff --git a/handlers/posts.go b/handlers/posts.go
index a339685..a133758 100644
--- a/handlers/posts.go
+++ b/handlers/posts.go
@@ -53,6 +53,7 @@ func (ph PostsHandler) New(c fiber.Ctx) error {
"post": p,
"categories": cats,
"selectedCategories": map[int64]bool{},
+ "bodyClass": "post-edit-page",
})
}
@@ -93,6 +94,7 @@ func (ph PostsHandler) Edit(c fiber.Ctx) error {
"post": post,
"categories": cats,
"selectedCategories": selectedCategories,
+ "bodyClass": "post-edit-page",
})
}))
}
diff --git a/layouts/simplecss/categories_list.html b/layouts/simplecss/categories_list.html
deleted file mode 100644
index 32331f6..0000000
--- a/layouts/simplecss/categories_list.html
+++ /dev/null
@@ -1,9 +0,0 @@
-
Categories
-
-{{ range .Categories }}
-
- {{ .Name }} ({{ .PostCount }})
- {{ if .DescriptionBrief }}{{ .DescriptionBrief }} {{ end }}
-
-{{ end }}
-
\ No newline at end of file
diff --git a/layouts/simplecss/categories_single.html b/layouts/simplecss/categories_single.html
deleted file mode 100644
index e8d59d1..0000000
--- a/layouts/simplecss/categories_single.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{ .Category.Name }}
-{{ if .DescriptionHTML }}
- {{ .DescriptionHTML }}
-{{ end }}
-{{ range .Posts }}
- {{ if .Post.Title }}{{ .Post.Title }} {{ end }}
- {{ .HTML }}
- {{ format_date .Post.PublishedAt }}
- {{ if .Categories }}
-
- {{ range .Categories }}
- {{ .Name }}
- {{ end }}
-
- {{ end }}
-{{ end }}
\ No newline at end of file
diff --git a/layouts/simplecss/fs.go b/layouts/simplecss/fs.go
index 2c1b2fb..d82f6ae 100644
--- a/layouts/simplecss/fs.go
+++ b/layouts/simplecss/fs.go
@@ -2,5 +2,6 @@ package simplecss
import "embed"
-//go:embed *.html
+//go:embed templates/*.html
+//go:embed static/*
var FS embed.FS
diff --git a/layouts/simplecss/posts_list.html b/layouts/simplecss/posts_list.html
deleted file mode 100644
index e6a77fe..0000000
--- a/layouts/simplecss/posts_list.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{ range .Posts }}
- {{ if .Post.Title }}{{ .Post.Title }} {{ end }}
- {{ .HTML }}
- {{ format_date .Post.PublishedAt }}
- {{ if .Categories }}
-
- {{ range .Categories }}
- {{ .Name }}
- {{ end }}
-
- {{ end }}
-{{ end }}
\ No newline at end of file
diff --git a/layouts/simplecss/posts_single.html b/layouts/simplecss/posts_single.html
deleted file mode 100644
index cda9bb2..0000000
--- a/layouts/simplecss/posts_single.html
+++ /dev/null
@@ -1,10 +0,0 @@
-{{ if .Post.Title }}{{ .Post.Title }} {{ end }}
-{{ .HTML }}
-{{ format_date .Post.PublishedAt }}
-{{ if .Categories }}
-
- {{ range .Categories }}
- {{ .Name }}
- {{ end }}
-
-{{ end }}
\ No newline at end of file
diff --git a/layouts/simplecss/static/style.css b/layouts/simplecss/static/style.css
new file mode 100644
index 0000000..cdfc4c2
--- /dev/null
+++ b/layouts/simplecss/static/style.css
@@ -0,0 +1,55 @@
+.h-entry {
+ margin-block-start: 1.5rem;
+ margin-block-end: 2.5rem;
+}
+
+.post-meta {
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+ font-size: 0.95rem;
+}
+
+.post-meta a {
+ color: var(--text-light);
+ text-decoration: none;
+}
+
+.post-meta a:hover {
+ text-decoration: underline;
+}
+
+.post-categories {
+ display: inline-flex;
+ gap: 0.5rem;
+}
+
+.post-categories a:before {
+ content: "#";
+}
+
+/* Category list */
+
+ul.category-list {
+ list-style: none;
+ padding-inline-start: 0;
+}
+
+ul.category-list li {
+ display: flex;
+ flex-direction: row;
+
+ justify-content: start;
+ gap: 4rem;
+}
+
+ul.category-list span.category-list-name {
+ min-width: 15vw;
+}
+
+/* Category single */
+
+.category-description {
+ margin-block-start: 1.5rem;
+ margin-block-end: 2.5rem;
+}
\ No newline at end of file
diff --git a/layouts/simplecss/templates/_post_meta.html b/layouts/simplecss/templates/_post_meta.html
new file mode 100644
index 0000000..a042f41
--- /dev/null
+++ b/layouts/simplecss/templates/_post_meta.html
@@ -0,0 +1,10 @@
+
\ No newline at end of file
diff --git a/layouts/simplecss/templates/categories_list.html b/layouts/simplecss/templates/categories_list.html
new file mode 100644
index 0000000..e5fc8c8
--- /dev/null
+++ b/layouts/simplecss/templates/categories_list.html
@@ -0,0 +1,9 @@
+Categories
+
+{{ range .Categories }}
+
+ {{ .Name }} ({{ .PostCount }})
+ {{ if .DescriptionBrief }}{{ .DescriptionBrief }} {{ end }}
+
+{{ end }}
+
\ No newline at end of file
diff --git a/layouts/simplecss/templates/categories_single.html b/layouts/simplecss/templates/categories_single.html
new file mode 100644
index 0000000..deaeb02
--- /dev/null
+++ b/layouts/simplecss/templates/categories_single.html
@@ -0,0 +1,11 @@
+{{ .Category.Name }}
+{{ if .DescriptionHTML }}
+ {{ .DescriptionHTML }}
+{{ end }}
+{{ range .Posts }}
+
+ {{ if .Post.Title }}
{{ .Post.Title }} {{ end }}
+ {{ .HTML }}
+ {{ template "_post_meta.html" . }}
+
+{{ end }}
\ No newline at end of file
diff --git a/layouts/simplecss/layout_main.html b/layouts/simplecss/templates/layout_main.html
similarity index 89%
rename from layouts/simplecss/layout_main.html
rename to layouts/simplecss/templates/layout_main.html
index cc2e616..4aa5199 100644
--- a/layouts/simplecss/layout_main.html
+++ b/layouts/simplecss/templates/layout_main.html
@@ -7,6 +7,7 @@
+
diff --git a/layouts/simplecss/templates/posts_list.html b/layouts/simplecss/templates/posts_list.html
new file mode 100644
index 0000000..5f10f1e
--- /dev/null
+++ b/layouts/simplecss/templates/posts_list.html
@@ -0,0 +1,8 @@
+{{ range .Posts }}
+
+ {{ if .Post.Title }}
{{ .Post.Title }} {{ end }}
+ {{ .HTML }}
+
+ {{ template "_post_meta.html" . }}
+
+{{ end }}
\ No newline at end of file
diff --git a/layouts/simplecss/templates/posts_single.html b/layouts/simplecss/templates/posts_single.html
new file mode 100644
index 0000000..8895b19
--- /dev/null
+++ b/layouts/simplecss/templates/posts_single.html
@@ -0,0 +1,5 @@
+
+ {{ if .Post.Title }}
{{ .Post.Title }} {{ end }}
+ {{ .HTML }}
+ {{ template "_post_meta.html" . }}
+
\ No newline at end of file
diff --git a/providers/sitebuilder/builder.go b/providers/sitebuilder/builder.go
index 5775149..1a4275d 100644
--- a/providers/sitebuilder/builder.go
+++ b/providers/sitebuilder/builder.go
@@ -6,7 +6,9 @@ import (
"fmt"
"html/template"
"io"
+ "io/fs"
"iter"
+ "log"
"os"
"path/filepath"
"strings"
@@ -31,11 +33,15 @@ type Builder struct {
func New(site pubmodel.Site, opts Options) (*Builder, error) {
tmpls, err := template.New("").
Funcs(templateFns(site, opts)).
- ParseFS(opts.TemplatesFS, tmplNamePostSingle, tmplNamePostList, tmplNameLayoutMain, tmplNameCategoryList, tmplNameCategorySingle)
+ ParseFS(opts.TemplatesFS, "*.html")
if err != nil {
return nil, err
}
+ for _, t := range tmpls.Templates() {
+ log.Printf("Loaded template %s", t.Name())
+ }
+
return &Builder{
site: site,
opts: opts,
@@ -109,6 +115,9 @@ func (b *Builder) BuildSite(outDir string) error {
return b.writeUploads(buildCtx, b.site.Uploads)
})
+ // Build static assets
+ eg.Go(func() error { return b.writeStaticAssets(buildCtx) })
+
return eg.Wait()
}
@@ -176,10 +185,11 @@ func (b *Builder) renderFeeds(ctx buildContext, postIter iter.Seq[models.Maybe[*
}
feed.Items = append(feed.Items, &feedhub.Item{
- Id: filepath.Join(b.site.BaseURL, post.GUID),
- Title: postTitle,
- Link: &feedhub.Link{Href: renderedPost.PostURL},
- Content: string(renderedPost.HTML),
+ Id: filepath.Join(b.site.BaseURL, post.GUID),
+ Title: postTitle,
+ Link: &feedhub.Link{Href: renderedPost.PostURL},
+ Content: string(renderedPost.HTML),
+ // TO FIX: Why the heck does this only include the first category?
Category: catName,
// TO FIX: Created should be first published
Created: post.PublishedAt,
@@ -431,7 +441,7 @@ func (b *Builder) renderTemplate(w io.Writer, name string, data interface{}) err
func (b *Builder) writeUploads(ctx buildContext, uploads []models.Upload) error {
for _, u := range uploads {
- fullPath := filepath.Join(ctx.outDir, "uploads", u.Slug)
+ fullPath := filepath.Join(ctx.outDir, b.opts.BaseUploads, u.Slug)
if err := os.MkdirAll(filepath.Dir(fullPath), 0755); err != nil {
return err
}
@@ -459,3 +469,37 @@ func (b *Builder) writeUploads(ctx buildContext, uploads []models.Upload) error
}
return nil
}
+
+func (b *Builder) writeStaticAssets(ctx buildContext) error {
+ return fs.WalkDir(b.opts.StaticFS, ".", func(path string, d os.DirEntry, err error) error {
+ if err != nil {
+ return err
+ } else if d.IsDir() {
+ return nil
+ }
+
+ fullPath := filepath.Join(ctx.outDir, b.opts.BaseStatic, path)
+ if err := os.MkdirAll(filepath.Dir(fullPath), 0755); err != nil {
+ return err
+ }
+
+ return func() error {
+ r, err := b.opts.StaticFS.Open(path)
+ if err != nil {
+ return err
+ }
+ defer r.Close()
+
+ w, err := os.Create(fullPath)
+ if err != nil {
+ return err
+ }
+ defer w.Close()
+
+ if _, err := io.Copy(w, r); err != nil {
+ return err
+ }
+ return nil
+ }()
+ })
+}
diff --git a/providers/sitebuilder/tmpls.go b/providers/sitebuilder/tmpls.go
index 2152290..cea02f5 100644
--- a/providers/sitebuilder/tmpls.go
+++ b/providers/sitebuilder/tmpls.go
@@ -29,12 +29,17 @@ const (
)
type Options struct {
- // BasePosts is the base path for posts.
- BasePosts string
+ BasePosts string // BasePosts is the base path for posts.
+ BaseUploads string // BaseUploads is the base path for uploads.
+ BaseStatic string // BaseStatic is the base path for static assets.
// TemplatesFS provides the raw templates for rendering the site.
TemplatesFS fs.FS
+ // StaticFS provides the raw assets for the site. This will be written as is
+ // from the BaseStatic dir.
+ StaticFS fs.FS
+
// FeedItems holds the number of posts to show in the feed.
FeedItems int
diff --git a/services/publisher/service.go b/services/publisher/service.go
index 2ed9046..939817a 100644
--- a/services/publisher/service.go
+++ b/services/publisher/service.go
@@ -3,6 +3,7 @@ package publisher
import (
"context"
"io"
+ "io/fs"
"iter"
"log"
"os"
@@ -102,9 +103,22 @@ func (p *Publisher) publishSite(ctx context.Context, pubSite pubmodel.Site, targ
renderTZ = time.UTC
}
+ templateFS, err := fs.Sub(simplecss.FS, "templates")
+ if err != nil {
+ return err
+ }
+
+ staticFS, err := fs.Sub(simplecss.FS, "static")
+ if err != nil {
+ return err
+ }
+
sb, err := sitebuilder.New(pubSite, sitebuilder.Options{
BasePosts: "/posts",
- TemplatesFS: simplecss.FS,
+ BaseUploads: "/uploads",
+ BaseStatic: "/static",
+ TemplatesFS: templateFS,
+ StaticFS: staticFS,
FeedItems: 30,
RenderTZ: renderTZ,
})
diff --git a/views/categories/edit.html b/views/categories/edit.html
index c838778..c6c3606 100644
--- a/views/categories/edit.html
+++ b/views/categories/edit.html
@@ -1,6 +1,6 @@
-
{{ if .isNew }}New Category{{ else }}Edit Category{{ end }}
+ {{ if .isNew }}New Category{{ else }}Edit Category{{ end }}
{{ if .isNew }}
@@ -10,27 +10,27 @@
{{ end }}
-
Description
+
Description
Markdown supported. Displayed on the category archive page.
-
+
{{ if .isNew }}Create{{ else }}Save{{ end }}
{{ if not .isNew }}
diff --git a/views/categories/index.html b/views/categories/index.html
index f768977..2d17beb 100644
--- a/views/categories/index.html
+++ b/views/categories/index.html
@@ -1,35 +1,32 @@
-
-
-
- Name
- Slug
- Posts
-
-
-
-
- {{ range .categories }}
+ {{ if .categories }}
+
+
- {{ .Name }}
- {{ .Slug }}
- {{ .PostCount }}
-
- Edit
-
+ Name
+ Slug
+ Posts
- {{ else }}
-
- No categories yet.
-
- {{ end }}
-
-
+
+
+ {{ range .categories }}
+
+ {{ .Name }}
+ {{ .Slug }}
+ {{ .PostCount }}
+
+ {{ end }}
+
+
+ {{ else }}
+
+
📚 No categories yet.
+
+ {{ end }}
diff --git a/views/layouts/main.html b/views/layouts/main.html
index 2b81177..908094f 100644
--- a/views/layouts/main.html
+++ b/views/layouts/main.html
@@ -7,7 +7,7 @@
-
+
{{ template "_common/nav" . }}
{{ embed }}
diff --git a/views/posts/edit.html b/views/posts/edit.html
index 07be770..d162788 100644
--- a/views/posts/edit.html
+++ b/views/posts/edit.html
@@ -1,6 +1,6 @@
{{ $isPublished := ne .post.State 1 }}
-