vkv website
This commit is contained in:
parent
81a1d68334
commit
5fcd02d086
|
@ -1,6 +1,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"flag"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
|
@ -12,6 +13,7 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
siteName = flag.String("site", "ewnl", "site id, either 'ewnl' or 'vkvnl'")
|
||||
resources = flag.String("resources", "./resources", "folder with templates and other resources")
|
||||
content = flag.String("content", "./content,/projectx", "comma separated list of folders search for content")
|
||||
statics = flag.String("statics", "./statics", "folder with static content")
|
||||
|
@ -20,12 +22,22 @@ var (
|
|||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
if *resources == "" || *content == "" || *public == "" || *statics == "" {
|
||||
if *siteName == "" || *resources == "" || *content == "" || *public == "" || *statics == "" {
|
||||
log.Fatal("missing parameter")
|
||||
}
|
||||
|
||||
var siteId site.SiteID
|
||||
switch *siteName {
|
||||
case "ewnl":
|
||||
siteId = site.SITE_EWNL
|
||||
case "vkvnl":
|
||||
siteId = site.SITE_VKVNL
|
||||
default:
|
||||
log.Fatal(errors.New("unknown site"))
|
||||
}
|
||||
|
||||
// initialize site
|
||||
config, err := site.NewSiteConfig(site.SITE_EWNL)
|
||||
config, err := site.NewSiteConfig(siteId)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
|
|
@ -31,8 +31,8 @@ type TemplateConfig struct {
|
|||
type SiteConfig struct {
|
||||
ID SiteID
|
||||
BaseURL string
|
||||
PathsWithKind bool
|
||||
TemplateConfigs []*TemplateConfig
|
||||
RSS bool
|
||||
StaticPages []*StaticPage
|
||||
KindMap map[adoc.Kind]Kind
|
||||
}
|
||||
|
|
|
@ -24,11 +24,13 @@ var pluralKind = map[Kind]string{
|
|||
}
|
||||
|
||||
type Post struct {
|
||||
doc *adoc.ADoc
|
||||
Date time.Time
|
||||
Kind Kind
|
||||
Language Language
|
||||
Tags []Tag
|
||||
doc *adoc.ADoc
|
||||
baseURL string
|
||||
prefixPath bool
|
||||
Date time.Time
|
||||
Kind Kind
|
||||
Language Language
|
||||
Tags []Tag
|
||||
}
|
||||
|
||||
func NewPost(config *SiteConfig, doc *adoc.ADoc) *Post {
|
||||
|
@ -37,11 +39,13 @@ func NewPost(config *SiteConfig, doc *adoc.ADoc) *Post {
|
|||
tags = append(tags, Tag(t))
|
||||
}
|
||||
return &Post{
|
||||
doc: doc,
|
||||
Date: doc.Date,
|
||||
Kind: config.MapKind(doc.Kind),
|
||||
Language: Language(doc.Language),
|
||||
Tags: tags,
|
||||
doc: doc,
|
||||
baseURL: config.BaseURL,
|
||||
prefixPath: config.PathsWithKind,
|
||||
Date: doc.Date,
|
||||
Kind: config.MapKind(doc.Kind),
|
||||
Language: Language(doc.Language),
|
||||
Tags: tags,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,11 +58,15 @@ func (p *Post) Year() string {
|
|||
}
|
||||
|
||||
func (p *Post) Link() string {
|
||||
return fmt.Sprintf("%s/", path.Join("/", pluralKind[p.Kind], p.Year(), p.Slug()))
|
||||
link := "/"
|
||||
if p.prefixPath {
|
||||
link = path.Join(link, pluralKind[p.Kind])
|
||||
}
|
||||
return fmt.Sprintf("%s/", path.Join(link, p.Year(), p.Slug()))
|
||||
}
|
||||
|
||||
func (p *Post) FullLink() string {
|
||||
return fmt.Sprintf("https://erikwinter.nl%s", p.Link())
|
||||
return fmt.Sprintf("%s%s", p.baseURL, p.Link())
|
||||
}
|
||||
|
||||
func (p *Post) HTMLSummary() *HTMLSummary {
|
||||
|
|
|
@ -11,29 +11,7 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
const dirMode = os.ModeDir | 0755
|
||||
|
||||
func resetTarget(targetPath string) error {
|
||||
if err := os.RemoveAll(targetPath); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return os.Mkdir(targetPath, dirMode)
|
||||
}
|
||||
|
||||
func moveResources(targetPath, resourcesPath string) error {
|
||||
for _, dir := range []string{"css", "font"} {
|
||||
srcPath := filepath.Join(resourcesPath, dir)
|
||||
destPath := filepath.Join(targetPath, dir)
|
||||
if err := copyFiles(filepath.Join(srcPath, "*"), destPath); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func renderStaticPages(targetPath string, tpl *template.Template, _ Posts, statics []*StaticPage) error {
|
||||
func renderEWNLStaticPages(targetPath string, tpl *template.Template, _ Posts, statics []*StaticPage) error {
|
||||
for _, static := range statics {
|
||||
destPath := filepath.Join(targetPath, static.Name)
|
||||
if err := os.MkdirAll(destPath, dirMode); err != nil {
|
||||
|
@ -68,7 +46,7 @@ func renderStaticPages(targetPath string, tpl *template.Template, _ Posts, stati
|
|||
return nil
|
||||
}
|
||||
|
||||
func renderHome(targetPath string, tpl *template.Template, posts Posts, _ []*StaticPage) error {
|
||||
func renderEWNLHome(targetPath string, tpl *template.Template, posts Posts, _ []*StaticPage) error {
|
||||
var summaries []*HTMLSummary
|
||||
for _, p := range posts.RemoveKind(KIND_NOTE).Limit(10) {
|
||||
summaries = append(summaries, p.HTMLSummary())
|
||||
|
@ -91,7 +69,7 @@ func renderHome(targetPath string, tpl *template.Template, posts Posts, _ []*Sta
|
|||
return tpl.Execute(homeFile, data)
|
||||
}
|
||||
|
||||
func renderArchive(targetPath string, tpl *template.Template, posts Posts, _ []*StaticPage) error {
|
||||
func renderEWNLArchive(targetPath string, tpl *template.Template, posts Posts, _ []*StaticPage) error {
|
||||
archPath := filepath.Join(targetPath, "archive")
|
||||
if err := os.MkdirAll(archPath, dirMode); err != nil {
|
||||
return err
|
||||
|
@ -145,7 +123,7 @@ func renderArchive(targetPath string, tpl *template.Template, posts Posts, _ []*
|
|||
return tpl.Execute(archFile, data)
|
||||
}
|
||||
|
||||
func renderListings(targetPath string, tpl *template.Template, posts Posts, _ []*StaticPage) error {
|
||||
func renderEWNLListings(targetPath string, tpl *template.Template, posts Posts, _ []*StaticPage) error {
|
||||
for _, kind := range []Kind{KIND_NOTE, KIND_STORY, KIND_ARTICLE} {
|
||||
for _, year := range posts.SelectKind(kind).YearList() {
|
||||
title := fmt.Sprintf("%s in %s", strings.Title(pluralKind[kind]), year)
|
||||
|
@ -155,7 +133,7 @@ func renderListings(targetPath string, tpl *template.Template, posts Posts, _ []
|
|||
summaries = append(summaries, p.HTMLSummary())
|
||||
}
|
||||
path := filepath.Join(targetPath, pluralKind[kind], year)
|
||||
if err := renderListing(path, tpl, title, summaries); err != nil {
|
||||
if err := renderEWNLListing(path, tpl, title, summaries); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -169,7 +147,7 @@ func renderListings(targetPath string, tpl *template.Template, posts Posts, _ []
|
|||
summaries = append(summaries, p.HTMLSummary())
|
||||
}
|
||||
path := filepath.Join(targetPath, "tags", tag)
|
||||
if err := renderListing(path, tpl, title, summaries); err != nil {
|
||||
if err := renderEWNLListing(path, tpl, title, summaries); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -177,7 +155,7 @@ func renderListings(targetPath string, tpl *template.Template, posts Posts, _ []
|
|||
return nil
|
||||
}
|
||||
|
||||
func renderListing(path string, tpl *template.Template, title string, summaries []*HTMLSummary) error {
|
||||
func renderEWNLListing(path string, tpl *template.Template, title string, summaries []*HTMLSummary) error {
|
||||
data := struct {
|
||||
Title string
|
||||
Summaries []*HTMLSummary
|
||||
|
@ -198,7 +176,7 @@ func renderListing(path string, tpl *template.Template, title string, summaries
|
|||
return tpl.Execute(f, data)
|
||||
}
|
||||
|
||||
func renderPosts(targetPath string, tpl *template.Template, posts Posts, _ []*StaticPage) error {
|
||||
func renderEWNLPosts(targetPath string, tpl *template.Template, posts Posts, _ []*StaticPage) error {
|
||||
for _, post := range posts {
|
||||
data := post.HTMLPost()
|
||||
if data.Slug == "" {
|
||||
|
@ -225,7 +203,7 @@ func renderPosts(targetPath string, tpl *template.Template, posts Posts, _ []*St
|
|||
return nil
|
||||
}
|
||||
|
||||
func renderRSS(targetPath string, tpl *template.Template, posts Posts, _ []*StaticPage) error {
|
||||
func renderEWNLRSS(targetPath string, tpl *template.Template, posts Posts, _ []*StaticPage) error {
|
||||
rssPath := filepath.Join(targetPath, "index.xml")
|
||||
rssFile, err := os.Create(rssPath)
|
||||
if err != nil {
|
|
@ -0,0 +1,91 @@
|
|||
package site
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"text/template"
|
||||
"time"
|
||||
)
|
||||
|
||||
func renderVKVNLPosts(targetPath string, tpl *template.Template, posts Posts, _ []*StaticPage) error {
|
||||
last, first := 0, len(posts)-1 // posts are sorted in reverse order
|
||||
for i, post := range posts {
|
||||
pData := post.HTMLPost()
|
||||
if pData.Slug == "" {
|
||||
return ErrInvalidPost
|
||||
}
|
||||
|
||||
data := struct {
|
||||
Slug string
|
||||
Title string
|
||||
DateLong string
|
||||
DateShort string
|
||||
Content string
|
||||
PreviousLink string
|
||||
NextLink string
|
||||
}{
|
||||
Slug: pData.Slug,
|
||||
Title: pData.Title,
|
||||
DateLong: pData.DateLong,
|
||||
DateShort: pData.DateShort,
|
||||
Content: pData.Content,
|
||||
}
|
||||
|
||||
path := targetPath
|
||||
if i != first {
|
||||
data.PreviousLink = posts[i+1].Link()
|
||||
}
|
||||
if i != last {
|
||||
data.NextLink = posts[i-1].Link()
|
||||
fmt.Printf("first %d, last %d, i %d\n", first, last, i)
|
||||
if i == last+1 {
|
||||
fmt.Println(data.Title)
|
||||
data.NextLink = "/"
|
||||
}
|
||||
path = filepath.Join(targetPath, post.Year(), data.Slug)
|
||||
}
|
||||
if i == last-1 {
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(path, dirMode); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
nPath := filepath.Join(path, "index.html")
|
||||
f, err := os.Create(nPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
if err := tpl.Execute(f, data); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func renderVKVNLRSS(targetPath string, tpl *template.Template, posts Posts, _ []*StaticPage) error {
|
||||
rssPath := filepath.Join(targetPath, "index.xml")
|
||||
rssFile, err := os.Create(rssPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer rssFile.Close()
|
||||
|
||||
var xmlPosts []*XMLPost
|
||||
for _, p := range posts.RemoveKind(KIND_NOTE).Limit(10) {
|
||||
xmlPosts = append(xmlPosts, p.XMLPost())
|
||||
}
|
||||
|
||||
data := struct {
|
||||
DateFormal string
|
||||
Posts []*XMLPost
|
||||
}{
|
||||
DateFormal: time.Now().Format(time.RFC1123Z),
|
||||
Posts: xmlPosts,
|
||||
}
|
||||
return tpl.Execute(rssFile, data)
|
||||
}
|
|
@ -2,11 +2,14 @@ package site
|
|||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"git.sr.ht/~ewintr/shitty-ssg/pkg/adoc"
|
||||
)
|
||||
|
||||
const dirMode = os.ModeDir | 0755
|
||||
|
||||
type StaticPage struct {
|
||||
Name string
|
||||
Path string
|
||||
|
@ -70,3 +73,23 @@ func (s *Site) RenderHTML(targetPath string) error {
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resetTarget(targetPath string) error {
|
||||
if err := os.RemoveAll(targetPath); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return os.Mkdir(targetPath, dirMode)
|
||||
}
|
||||
|
||||
func moveResources(targetPath, resourcesPath string) error {
|
||||
for _, dir := range []string{"css", "font"} {
|
||||
srcPath := filepath.Join(resourcesPath, dir)
|
||||
destPath := filepath.Join(targetPath, dir)
|
||||
if err := copyFiles(filepath.Join(srcPath, "*"), destPath); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -4,44 +4,45 @@ import "git.sr.ht/~ewintr/shitty-ssg/pkg/adoc"
|
|||
|
||||
var (
|
||||
SITE_CONFIG_EWNL = &SiteConfig{
|
||||
ID: SITE_EWNL,
|
||||
BaseURL: "https://erikwinter.nl",
|
||||
ID: SITE_EWNL,
|
||||
BaseURL: "https://erikwinter.nl",
|
||||
PathsWithKind: true,
|
||||
TemplateConfigs: []*TemplateConfig{
|
||||
{
|
||||
Name: "home",
|
||||
TemplateNames: []string{"list", "head", "menu"},
|
||||
TemplateExt: "gohtml",
|
||||
Render: renderHome,
|
||||
Render: renderEWNLHome,
|
||||
},
|
||||
{
|
||||
Name: "listings",
|
||||
TemplateNames: []string{"list", "head", "menu"},
|
||||
TemplateExt: "gohtml",
|
||||
Render: renderListings,
|
||||
Render: renderEWNLListings,
|
||||
},
|
||||
{
|
||||
Name: "archive",
|
||||
TemplateNames: []string{"archive", "head", "menu"},
|
||||
TemplateExt: "gohtml",
|
||||
Render: renderArchive,
|
||||
Render: renderEWNLArchive,
|
||||
},
|
||||
{
|
||||
Name: "static",
|
||||
TemplateNames: []string{"static", "head", "menu"},
|
||||
TemplateExt: "gohtml",
|
||||
Render: renderStaticPages,
|
||||
Render: renderEWNLStaticPages,
|
||||
},
|
||||
{
|
||||
Name: "posts",
|
||||
TemplateNames: []string{"post", "head", "menu"},
|
||||
TemplateExt: "gohtml",
|
||||
Render: renderPosts,
|
||||
Render: renderEWNLPosts,
|
||||
},
|
||||
{
|
||||
Name: "rss",
|
||||
TemplateNames: []string{"rss"},
|
||||
TemplateExt: "goxml",
|
||||
Render: renderRSS,
|
||||
Render: renderEWNLRSS,
|
||||
},
|
||||
},
|
||||
KindMap: map[adoc.Kind]Kind{
|
||||
|
@ -52,5 +53,27 @@ var (
|
|||
adoc.KIND_ARTICLE: KIND_ARTICLE,
|
||||
},
|
||||
}
|
||||
SITE_CONFIG_VKVNL = &SiteConfig{}
|
||||
|
||||
SITE_CONFIG_VKVNL = &SiteConfig{
|
||||
ID: SITE_VKVNL,
|
||||
BaseURL: "https://vrijkorteverhalen.nl",
|
||||
PathsWithKind: false,
|
||||
TemplateConfigs: []*TemplateConfig{
|
||||
{
|
||||
Name: "post",
|
||||
TemplateNames: []string{"post"},
|
||||
TemplateExt: "gohtml",
|
||||
Render: renderVKVNLPosts,
|
||||
},
|
||||
{
|
||||
Name: "rss",
|
||||
TemplateNames: []string{"rss"},
|
||||
TemplateExt: "goxml",
|
||||
Render: renderVKVNLRSS,
|
||||
},
|
||||
},
|
||||
KindMap: map[adoc.Kind]Kind{
|
||||
adoc.KIND_VKV: KIND_STORY,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="alternate" type="application/rss+xml" title="vrijkorteverhalen.nl" href="/index.xml"/>
|
||||
<title>{{ .Title }}</title>
|
||||
<style type="text/css">
|
||||
body { margin: 40px auto; max-width: 650px; line-height: 1.6; font-size: 18px; color: #000; padding:0 10px; }
|
||||
h1, h2, h3 { line-height:1.2; }
|
||||
a { color: #000; }
|
||||
#footer { text-align: center; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<article>
|
||||
<h1>{{ .Title }}</h1>
|
||||
<a rel="author" href="https://erikwinter.nl/about">Erik Winter</a> -
|
||||
<time pubdate="" datetime="{{ .DateShort }}">{{ .DateLong }}</time>.
|
||||
{{ .Content }}
|
||||
<hr>
|
||||
<p id="footer">
|
||||
{{ if ne "" .PreviousLink -}}<a href="{{ .PreviousLink }}">Vorige</a>{{ end }}
|
||||
{{ if ne "" .NextLink }}<a href="{{ .NextLink }}">Volgende</a>{{ end }}
|
||||
</p>
|
||||
</article>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>ErikWinter.nl</title>
|
||||
<link>https://erikwinter.nl/</link>
|
||||
<description>Activity on ErikWinter.nl</description>
|
||||
<language>en-us</language>
|
||||
<lastBuildDate>{{ .DateFormal }}</lastBuildDate>
|
||||
<atom:link href="https://erikwinter.nl/index.xml" rel="self" type="application/rss+xml" />
|
||||
{{- range .Posts -}}
|
||||
<item>
|
||||
<title>{{ .Title }}</title>
|
||||
<link>{{ .Link }}</link>
|
||||
<pubDate>{{ .DateFormal }}</pubDate>
|
||||
<guid>{{ .Link }}</guid>
|
||||
<description>{{ .Content }}</description>
|
||||
</item>
|
||||
{{- end -}}
|
||||
</channel>
|
||||
</rss>
|
Loading…
Reference in New Issue