Repos / s4g / c57827b375
commit c57827b3751625d7f00fbc8bcdfb423da3c03125
Author: Nhân <hi@imnhan.com>
Date: Wed Aug 23 20:45:41 2023 +0700
implement Series (poorly)
Probably grossly inefficient, but it hasn't been a problem yet on my
blog (34 articles took around 80-90ms). Maybe think of something
better... sometime.
diff --git a/docs/_s4g/theme/navbar.css b/docs/_s4g/theme/navbar.css
index 3a7107b..71bba65 100644
--- a/docs/_s4g/theme/navbar.css
+++ b/docs/_s4g/theme/navbar.css
@@ -5,6 +5,7 @@ nav > a {
nav > .posted-on {
float: right;
font-style: italic;
+ margin-bottom: 0.5rem;
}
.nav-hr {
diff --git a/docs/_s4g/theme/post.tmpl b/docs/_s4g/theme/post.tmpl
index 6878886..15fa7c6 100644
--- a/docs/_s4g/theme/post.tmpl
+++ b/docs/_s4g/theme/post.tmpl
@@ -5,8 +5,47 @@
{{- template "navbar" .}}
<main>
+
+{{- if .Post.Parent }}
+<em>
+ This post is part of
+ <a href="{{.Post.Parent.WebPath}}">{{.Post.Parent.Title}}</a>
+</em>
+<hr>
+{{- end }}
+
<h1>{{.Post.Title}}</h1>
+
{{.Content}}
+{{if .Post.Parent }}
+ <div class="series-container">
+ <p>
+ Here's every post in
+ <a href="{{.Post.Parent.WebPath}}">{{.Post.Parent.Title}}</a>,
+ in chronological order:
+ </p>
+
+ <ol>
+ {{- range .Post.Parent.Children }}
+ {{ if not .IsDraft -}}
+ <li><a href="{{.WebPath}}">{{.Title}}</a>
+ {{- if eq $.Post.WebPath .WebPath }} (you are here) {{- end -}}
+ </li>
+ {{- end -}}
+ {{ end }}
+ </ol>
+ </div>
+
+ <style>
+ .series-container {
+ margin: 2rem 0;
+ padding: 0 1rem;
+ border: 1px dashed #aaa;
+ background-color: #eee;
+ }
+ </style>
+{{ end -}}
+
</main>
{{template "footer" .}}
diff --git a/docs/_s4g/theme/series-index.tmpl b/docs/_s4g/theme/series-index.tmpl
new file mode 100644
index 0000000..aee5b53
--- /dev/null
+++ b/docs/_s4g/theme/series-index.tmpl
@@ -0,0 +1,27 @@
+{{- define "head"}}{{- end}}
+
+{{define "body"}}
+
+{{- template "navbar" .}}
+
+<main>
+
+<h1>{{.Post.Title}}</h1>
+{{.Content}}
+
+<ol>
+{{ range .Post.Children }}
+{{- if not .IsDraft}}
+ <li style="margin-bottom: 1rem;">
+ <a href="{{.WebPath}}">{{.Title}}</a>
+ <br>
+ <span>{{.PostedAt.Local.Format "January 1, 2006"}}</span>
+ </li>
+{{- end}}
+{{ end }}
+</ol>
+
+</main>
+
+{{template "footer" .}}
+{{- end}}
diff --git a/docs/about/index.html b/docs/about/index.html
index d761c95..ee026a6 100644
--- a/docs/about/index.html
+++ b/docs/about/index.html
@@ -25,7 +25,9 @@
<main>
+
<h1>About</h1>
+
<p>This is a sample website to demonstrate some features of <a href="https://github.com/nhanb/s4g">s4g</a>.
It also doubles as a lazy end-to-end test suite until the core design
stablizes. Its source code, as well as output, is in the <a href="https://github.com/nhanb/s4g/tree/master/docs">/docs/</a> dir.</p>
diff --git a/docs/mfws.html b/docs/mfws.html
index 3bb6415..af1fd44 100644
--- a/docs/mfws.html
+++ b/docs/mfws.html
@@ -31,7 +31,9 @@
<main>
+
<h1>This is a motherfucking website.</h1>
+
<p>And it’s fucking perfect.</p>
<section id="Seriously-what-the-fuck-else-do-you-want">
<h2>Seriously, what the fuck else do you want?</h2>
diff --git a/feed.go b/feed.go
index c49dff7..f902ae1 100644
--- a/feed.go
+++ b/feed.go
@@ -9,7 +9,7 @@
// TODO: Use Article's updated date instead of PostedAt.
// I need to implement Article.UpdatedAt first though.
-func generateFeed(site *SiteMetadata, posts []Article, path string) []byte {
+func generateFeed(site *SiteMetadata, posts []*Article, path string) []byte {
siteAddr := site.Address
if !strings.HasSuffix(siteAddr, "/") {
siteAddr += "/"
diff --git a/main.go b/main.go
index 56a35a1..7077598 100644
--- a/main.go
+++ b/main.go
@@ -193,7 +193,7 @@ func regenerate(fsys writablefs.FS) (site *SiteMetadata, err error) {
generatedFiles := make(map[string]bool)
- var articlesInNav []Article
+ var articlesInNav []*Article
for _, link := range site.NavbarLinks {
a, ok := articles[link]
if !ok {
@@ -206,7 +206,7 @@ func regenerate(fsys writablefs.FS) (site *SiteMetadata, err error) {
articlesInNav = append(articlesInNav, a)
}
- var articlesInFeed []Article
+ var articlesInFeed []*Article
startYear := time.Now().Year()
for _, a := range articles {
if a.ShowInFeed {
@@ -222,6 +222,16 @@ func regenerate(fsys writablefs.FS) (site *SiteMetadata, err error) {
return articlesInFeed[i].PostedAt.Compare(articlesInFeed[j].PostedAt) > 0
})
+ // TODO: fix wasteful loop?
+ for _, a := range articles {
+ // Sort articles in series, oldest first
+ if len(a.Children) > 0 {
+ sort.Slice(a.Children, func(i int, j int) bool {
+ return a.Children[i].PostedAt.Compare(a.Children[j].PostedAt) < 0
+ })
+ }
+ }
+
for _, a := range articles {
err := a.WriteHtmlFile(site, articlesInNav, articlesInFeed, startYear)
if err != nil {
@@ -264,6 +274,12 @@ type Article struct {
WebPath string
TemplatePaths []string
OpenGraphImage string
+ Parent *Article
+ Children []*Article
+}
+
+func (a *Article) IsSeriesIndex() bool {
+ return a.PageType == PTSeriesIndex
}
func (a *Article) ComputeDerivedFields(addr, root string) {
@@ -332,8 +348,8 @@ func (a *Article) computeTemplatePaths() {
func (a *Article) WriteHtmlFile(
site *SiteMetadata,
- articlesInNav []Article,
- articlesInFeed []Article,
+ articlesInNav []*Article,
+ articlesInFeed []*Article,
startYear int,
) error {
contentHtml := djot.ToHtml(a.DjotBody)
@@ -352,8 +368,8 @@ func (a *Article) WriteHtmlFile(
Content template.HTML
Title string
Post *Article
- ArticlesInNav []Article
- ArticlesInFeed []Article
+ ArticlesInNav []*Article
+ ArticlesInFeed []*Article
Feed string
Now time.Time
StartYear int
@@ -384,10 +400,12 @@ func (a *Article) WriteHtmlFile(
return nil
}
-func findArticles(fsys writablefs.FS, site *SiteMetadata) (map[string]Article, error) {
- result := make(map[string]Article)
+func findArticles(fsys writablefs.FS, site *SiteMetadata) (map[string]*Article, error) {
+ articles := make(map[string]*Article)
+ var seriesPaths []string
err := fs.WalkDir(fsys, ".", func(path string, d fs.DirEntry, err error) error {
+ fmt.Println("DIR:", path)
if d.IsDir() || !strings.HasSuffix(d.Name(), DjotExt) {
return nil
}
@@ -438,12 +456,31 @@ func findArticles(fsys writablefs.FS, site *SiteMetadata) (map[string]Article, e
ArticleMetadata: meta,
}
article.ComputeDerivedFields(site.Address, site.Root)
- result[article.Path] = article
+
+ if article.PageType == PTSeriesIndex {
+ seriesPaths = append(seriesPaths, article.Path)
+ }
+
+ articles[article.Path] = &article
return nil
})
if err != nil {
return nil, err
}
- return result, nil
+
+ // TODO: there must be a more... elegant way?
+ for _, sPath := range seriesPaths {
+ for aPath, a := range articles {
+ if a.PageType != PTSeriesIndex &&
+ filepath.Dir(sPath) == filepath.Dir(filepath.Dir(aPath)) {
+ child := a
+ parent := articles[sPath]
+ parent.Children = append(parent.Children, child)
+ child.Parent = parent
+ }
+ }
+ }
+
+ return articles, nil
}
diff --git a/theme/navbar.css b/theme/navbar.css
index 3a7107b..71bba65 100644
--- a/theme/navbar.css
+++ b/theme/navbar.css
@@ -5,6 +5,7 @@ nav > a {
nav > .posted-on {
float: right;
font-style: italic;
+ margin-bottom: 0.5rem;
}
.nav-hr {
diff --git a/theme/post.tmpl b/theme/post.tmpl
index 6878886..15fa7c6 100644
--- a/theme/post.tmpl
+++ b/theme/post.tmpl
@@ -5,8 +5,47 @@
{{- template "navbar" .}}
<main>
+
+{{- if .Post.Parent }}
+<em>
+ This post is part of
+ <a href="{{.Post.Parent.WebPath}}">{{.Post.Parent.Title}}</a>
+</em>
+<hr>
+{{- end }}
+
<h1>{{.Post.Title}}</h1>
+
{{.Content}}
+{{if .Post.Parent }}
+ <div class="series-container">
+ <p>
+ Here's every post in
+ <a href="{{.Post.Parent.WebPath}}">{{.Post.Parent.Title}}</a>,
+ in chronological order:
+ </p>
+
+ <ol>
+ {{- range .Post.Parent.Children }}
+ {{ if not .IsDraft -}}
+ <li><a href="{{.WebPath}}">{{.Title}}</a>
+ {{- if eq $.Post.WebPath .WebPath }} (you are here) {{- end -}}
+ </li>
+ {{- end -}}
+ {{ end }}
+ </ol>
+ </div>
+
+ <style>
+ .series-container {
+ margin: 2rem 0;
+ padding: 0 1rem;
+ border: 1px dashed #aaa;
+ background-color: #eee;
+ }
+ </style>
+{{ end -}}
+
</main>
{{template "footer" .}}
diff --git a/theme/series-index.tmpl b/theme/series-index.tmpl
new file mode 100644
index 0000000..aee5b53
--- /dev/null
+++ b/theme/series-index.tmpl
@@ -0,0 +1,27 @@
+{{- define "head"}}{{- end}}
+
+{{define "body"}}
+
+{{- template "navbar" .}}
+
+<main>
+
+<h1>{{.Post.Title}}</h1>
+{{.Content}}
+
+<ol>
+{{ range .Post.Children }}
+{{- if not .IsDraft}}
+ <li style="margin-bottom: 1rem;">
+ <a href="{{.WebPath}}">{{.Title}}</a>
+ <br>
+ <span>{{.PostedAt.Local.Format "January 1, 2006"}}</span>
+ </li>
+{{- end}}
+{{ end }}
+</ol>
+
+</main>
+
+{{template "footer" .}}
+{{- end}}