Styled the categories on the site
This commit is contained in:
parent
f45bdcd83c
commit
d9aec4af2c
|
|
@ -1,9 +0,0 @@
|
||||||
<h2>Categories</h2>
|
|
||||||
<ul>
|
|
||||||
{{ range .Categories }}
|
|
||||||
<li>
|
|
||||||
<a href="{{ url_abs .Path }}">{{ .Name }}</a> ({{ .PostCount }})
|
|
||||||
{{ if .DescriptionBrief }}<br><small>{{ .DescriptionBrief }}</small>{{ end }}
|
|
||||||
</li>
|
|
||||||
{{ end }}
|
|
||||||
</ul>
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
<h2>{{ .Category.Name }}</h2>
|
|
||||||
{{ if .DescriptionHTML }}
|
|
||||||
<div>{{ .DescriptionHTML }}</div>
|
|
||||||
{{ end }}
|
|
||||||
{{ range .Posts }}
|
|
||||||
{{ if .Post.Title }}<h3>{{ .Post.Title }}</h3>{{ end }}
|
|
||||||
{{ .HTML }}
|
|
||||||
<a href="{{ url_abs .Path }}">{{ format_date .Post.PublishedAt }}</a>
|
|
||||||
{{ if .Categories }}
|
|
||||||
<p>
|
|
||||||
{{ range .Categories }}
|
|
||||||
<a href="{{ url_abs (printf "/categories/%s" .Slug) }}">{{ .Name }}</a>
|
|
||||||
{{ end }}
|
|
||||||
</p>
|
|
||||||
{{ end }}
|
|
||||||
{{ end }}
|
|
||||||
|
|
@ -2,5 +2,6 @@ package simplecss
|
||||||
|
|
||||||
import "embed"
|
import "embed"
|
||||||
|
|
||||||
//go:embed *.html
|
//go:embed templates/*.html
|
||||||
|
//go:embed static/*
|
||||||
var FS embed.FS
|
var FS embed.FS
|
||||||
|
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
{{ range .Posts }}
|
|
||||||
{{ if .Post.Title }}<h3>{{ .Post.Title }}</h3>{{ end }}
|
|
||||||
{{ .HTML }}
|
|
||||||
<a href="{{ url_abs .Path }}">{{ format_date .Post.PublishedAt }}</a>
|
|
||||||
{{ if .Categories }}
|
|
||||||
<p>
|
|
||||||
{{ range .Categories }}
|
|
||||||
<a href="{{ url_abs (printf "/categories/%s" .Slug) }}">{{ .Name }}</a>
|
|
||||||
{{ end }}
|
|
||||||
</p>
|
|
||||||
{{ end }}
|
|
||||||
{{ end }}
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
{{ if .Post.Title }}<h3>{{ .Post.Title }}</h3>{{ end }}
|
|
||||||
{{ .HTML }}
|
|
||||||
<a href="{{ url_abs .Path }}">{{ format_date .Post.PublishedAt }}</a>
|
|
||||||
{{ if .Categories }}
|
|
||||||
<p>
|
|
||||||
{{ range .Categories }}
|
|
||||||
<a href="{{ url_abs (printf "/categories/%s" .Slug) }}">{{ .Name }}</a>
|
|
||||||
{{ end }}
|
|
||||||
</p>
|
|
||||||
{{ end }}
|
|
||||||
55
layouts/simplecss/static/style.css
Normal file
55
layouts/simplecss/static/style.css
Normal file
|
|
@ -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;
|
||||||
|
}
|
||||||
10
layouts/simplecss/templates/_post_meta.html
Normal file
10
layouts/simplecss/templates/_post_meta.html
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
<div class="post-meta">
|
||||||
|
<a href="{{ url_abs .Path }}">{{ format_date .Post.PublishedAt }}</a>
|
||||||
|
{{ if .Categories }}
|
||||||
|
<div class="post-categories">
|
||||||
|
{{ range .Categories }}
|
||||||
|
<a href="{{ url_abs (printf "/categories/%s" .Slug) }}">{{ .Name }}</a>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
9
layouts/simplecss/templates/categories_list.html
Normal file
9
layouts/simplecss/templates/categories_list.html
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
<h2>Categories</h2>
|
||||||
|
<ul class="category-list">
|
||||||
|
{{ range .Categories }}
|
||||||
|
<li>
|
||||||
|
<span class="category-list-name"><a href="{{ url_abs .Path }}">{{ .Name }}</a> ({{ .PostCount }})</span>
|
||||||
|
{{ if .DescriptionBrief }}<small>{{ .DescriptionBrief }}</small>{{ end }}
|
||||||
|
</li>
|
||||||
|
{{ end }}
|
||||||
|
</ul>
|
||||||
11
layouts/simplecss/templates/categories_single.html
Normal file
11
layouts/simplecss/templates/categories_single.html
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
<h2>{{ .Category.Name }}</h2>
|
||||||
|
{{ if .DescriptionHTML }}
|
||||||
|
<div class="notice category-description">{{ .DescriptionHTML }}</div>
|
||||||
|
{{ end }}
|
||||||
|
{{ range .Posts }}
|
||||||
|
<div class="h-entry">
|
||||||
|
{{ if .Post.Title }}<h3>{{ .Post.Title }}</h3>{{ end }}
|
||||||
|
{{ .HTML }}
|
||||||
|
{{ template "_post_meta.html" . }}
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
<link rel="alternate" type="application/rss+xml" title="RSS Feed" href="{{ url_abs "/feed.xml" }}"/>
|
<link rel="alternate" type="application/rss+xml" title="RSS Feed" href="{{ url_abs "/feed.xml" }}"/>
|
||||||
<link rel="alternate" type="application/json" title="JSON feed" href="{{ url_abs "/feed.json" }}"/>
|
<link rel="alternate" type="application/json" title="JSON feed" href="{{ url_abs "/feed.json" }}"/>
|
||||||
<link rel="stylesheet" href="https://cdn.simplecss.org/simple.min.css">
|
<link rel="stylesheet" href="https://cdn.simplecss.org/simple.min.css">
|
||||||
|
<link rel="stylesheet" href="{{ url_abs "/static/style.css" }}">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
8
layouts/simplecss/templates/posts_list.html
Normal file
8
layouts/simplecss/templates/posts_list.html
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
{{ range .Posts }}
|
||||||
|
<div class="h-entry">
|
||||||
|
{{ if .Post.Title }}<h3>{{ .Post.Title }}</h3>{{ end }}
|
||||||
|
{{ .HTML }}
|
||||||
|
|
||||||
|
{{ template "_post_meta.html" . }}
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
5
layouts/simplecss/templates/posts_single.html
Normal file
5
layouts/simplecss/templates/posts_single.html
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
<div class="h-entry">
|
||||||
|
{{ if .Post.Title }}<h3>{{ .Post.Title }}</h3>{{ end }}
|
||||||
|
{{ .HTML }}
|
||||||
|
{{ template "_post_meta.html" . }}
|
||||||
|
</div>
|
||||||
|
|
@ -6,7 +6,9 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"html/template"
|
"html/template"
|
||||||
"io"
|
"io"
|
||||||
|
"io/fs"
|
||||||
"iter"
|
"iter"
|
||||||
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
@ -31,11 +33,15 @@ type Builder struct {
|
||||||
func New(site pubmodel.Site, opts Options) (*Builder, error) {
|
func New(site pubmodel.Site, opts Options) (*Builder, error) {
|
||||||
tmpls, err := template.New("").
|
tmpls, err := template.New("").
|
||||||
Funcs(templateFns(site, opts)).
|
Funcs(templateFns(site, opts)).
|
||||||
ParseFS(opts.TemplatesFS, tmplNamePostSingle, tmplNamePostList, tmplNameLayoutMain, tmplNameCategoryList, tmplNameCategorySingle)
|
ParseFS(opts.TemplatesFS, "*.html")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, t := range tmpls.Templates() {
|
||||||
|
log.Printf("Loaded template %s", t.Name())
|
||||||
|
}
|
||||||
|
|
||||||
return &Builder{
|
return &Builder{
|
||||||
site: site,
|
site: site,
|
||||||
opts: opts,
|
opts: opts,
|
||||||
|
|
@ -109,6 +115,9 @@ func (b *Builder) BuildSite(outDir string) error {
|
||||||
return b.writeUploads(buildCtx, b.site.Uploads)
|
return b.writeUploads(buildCtx, b.site.Uploads)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Build static assets
|
||||||
|
eg.Go(func() error { return b.writeStaticAssets(buildCtx) })
|
||||||
|
|
||||||
return eg.Wait()
|
return eg.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -432,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 {
|
func (b *Builder) writeUploads(ctx buildContext, uploads []models.Upload) error {
|
||||||
for _, u := range uploads {
|
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 {
|
if err := os.MkdirAll(filepath.Dir(fullPath), 0755); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -460,3 +469,37 @@ func (b *Builder) writeUploads(ctx buildContext, uploads []models.Upload) error
|
||||||
}
|
}
|
||||||
return nil
|
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
|
||||||
|
}()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,12 +29,17 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Options struct {
|
type Options struct {
|
||||||
// BasePosts is the base path for posts.
|
BasePosts string // BasePosts is the base path for posts.
|
||||||
BasePosts string
|
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 provides the raw templates for rendering the site.
|
||||||
TemplatesFS fs.FS
|
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 holds the number of posts to show in the feed.
|
||||||
FeedItems int
|
FeedItems int
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package publisher
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"io"
|
"io"
|
||||||
|
"io/fs"
|
||||||
"iter"
|
"iter"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
|
@ -102,9 +103,22 @@ func (p *Publisher) publishSite(ctx context.Context, pubSite pubmodel.Site, targ
|
||||||
renderTZ = time.UTC
|
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{
|
sb, err := sitebuilder.New(pubSite, sitebuilder.Options{
|
||||||
BasePosts: "/posts",
|
BasePosts: "/posts",
|
||||||
TemplatesFS: simplecss.FS,
|
BaseUploads: "/uploads",
|
||||||
|
BaseStatic: "/static",
|
||||||
|
TemplatesFS: templateFS,
|
||||||
|
StaticFS: staticFS,
|
||||||
FeedItems: 30,
|
FeedItems: 30,
|
||||||
RenderTZ: renderTZ,
|
RenderTZ: renderTZ,
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{ range .categories }}
|
{{ if .categories }}
|
||||||
<table class="table">
|
<table class="table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
@ -15,11 +15,13 @@
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
{{ range .categories }}
|
||||||
<td><a href="/sites/{{ $.site.ID }}/categories/{{ .ID }}">{{ .Name }}</a></td>
|
<tr>
|
||||||
<td><code>{{ .Slug }}</code></td>
|
<td><a href="/sites/{{ $.site.ID }}/categories/{{ .ID }}">{{ .Name }}</a></td>
|
||||||
<td>{{ .PostCount }}</td>
|
<td><code>{{ .Slug }}</code></td>
|
||||||
</tr>
|
<td>{{ .PostCount }}</td>
|
||||||
|
</tr>
|
||||||
|
{{ end }}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
{{ else }}
|
{{ else }}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue