mirror of
https://git.sr.ht/~adnano/kiln
synced 2024-12-28 14:40:16 +00:00
parent
762fe469c4
commit
7013fe9fb9
|
@ -1,9 +1,10 @@
|
||||||
title = "Example website"
|
title = "Example website"
|
||||||
|
|
||||||
[permalinks]
|
[permalinks]
|
||||||
"/" = "/{{ .Date.Format `2006/01/02` }}/{{ path.Base .Permalink }}/"
|
"/" = "/{{ .Date.Format `2006/01/02` }}/{{ path.Base .Path }}/"
|
||||||
|
|
||||||
[[tasks]]
|
[[tasks]]
|
||||||
|
url = "gemini://example.com"
|
||||||
input = [".gmi"]
|
input = [".gmi"]
|
||||||
output = ".gmi"
|
output = ".gmi"
|
||||||
template = ".gmi"
|
template = ".gmi"
|
||||||
|
|
106
docs/kiln.1.scd
106
docs/kiln.1.scd
|
@ -195,7 +195,7 @@ content/blog/2021-05-12-hello-world.gmi will have a path of
|
||||||
|
|
||||||
```
|
```
|
||||||
[permalinks]
|
[permalinks]
|
||||||
"/blog/" = "/{{ .Date.Format `2006/01/02` }}/{{ path.Base .Permalink }}"
|
"/blog/" = "/{{ .Date.Format `2006/01/02` }}/{{ path.Base .Path }}"
|
||||||
```
|
```
|
||||||
|
|
||||||
For more information on templates, see *TEMPLATES*.
|
For more information on templates, see *TEMPLATES*.
|
||||||
|
@ -292,9 +292,13 @@ The following configuration options are supported per task:
|
||||||
output_dir = "public"
|
output_dir = "public"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
*url*
|
||||||
|
The base URL to use for page URLs. The base URL should not have trailing
|
||||||
|
forward slashes.
|
||||||
|
|
||||||
*ugly_urls*
|
*ugly_urls*
|
||||||
Specifies whether page permalinks will contain file extensions. By default,
|
Specifies whether page paths will contain file extensions. By default,
|
||||||
clean URLs without any extension are used.
|
clean paths without any extension are used.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
|
@ -624,14 +628,14 @@ All templates have the following functions available to them:
|
||||||
|
|
||||||
Site metadata contains the following data:
|
Site metadata contains the following data:
|
||||||
|
|
||||||
[[ *Variable*
|
*Title*
|
||||||
:[ *Description*
|
The title of the site.
|
||||||
| Title
|
|
||||||
: The title of the site.
|
*Params*
|
||||||
| Params
|
Extra parameters specified in configuration.
|
||||||
: Extra parameters specified in configuration.
|
|
||||||
| Generated
|
*Generated*
|
||||||
: Site generation time.
|
Site generation time.
|
||||||
|
|
||||||
To configure these variables, see *CONFIGURATION*.
|
To configure these variables, see *CONFIGURATION*.
|
||||||
|
|
||||||
|
@ -639,51 +643,63 @@ To configure these variables, see *CONFIGURATION*.
|
||||||
|
|
||||||
Page templates are provided with the following data:
|
Page templates are provided with the following data:
|
||||||
|
|
||||||
[[ *Variable*
|
*Title*
|
||||||
:[ *Description*
|
The title of the page
|
||||||
| Title
|
|
||||||
: The title of the page
|
*Date*
|
||||||
| Date
|
The date of the page
|
||||||
: The date of the page
|
|
||||||
| Weight
|
*Weight*
|
||||||
: The weight of the page
|
The weight of the page
|
||||||
| Permalink
|
|
||||||
: The permanent link to this page
|
*Path*
|
||||||
| FilePath
|
The path to the page
|
||||||
: The path of the page file relative to the content directory
|
|
||||||
| Content
|
*URL*
|
||||||
: The contents of the page
|
The URL of the page. If no base URL is configured, it is equivalent to
|
||||||
| Params
|
*Path*.
|
||||||
: Extra parameters specified in frontmatter
|
|
||||||
| Prev
|
*FilePath*
|
||||||
: The previous page in this directory
|
The path of the page file relative to the content directory
|
||||||
| Next
|
|
||||||
: The next page in this directory
|
*Content*
|
||||||
|
The contents of the page
|
||||||
|
|
||||||
|
*Params*
|
||||||
|
Extra parameters specified in frontmatter
|
||||||
|
|
||||||
|
*Prev*
|
||||||
|
The previous page in this directory
|
||||||
|
|
||||||
|
*Next*
|
||||||
|
The next page in this directory
|
||||||
|
|
||||||
## INDEX TEMPLATES
|
## INDEX TEMPLATES
|
||||||
|
|
||||||
Index templates are provided with all the data that page templates are provided,
|
Index templates are provided with all the data that page templates are provided,
|
||||||
plus the following data:
|
plus the following data:
|
||||||
|
|
||||||
[[ *Variable*
|
*Pages*
|
||||||
:[ *Description*
|
List of pages in this directory
|
||||||
| Pages
|
|
||||||
: List of pages in this directory
|
*Dirs*
|
||||||
| Dirs
|
List of subdirectories
|
||||||
: List of subdirectories
|
|
||||||
|
|
||||||
## FEED TEMPLATES
|
## FEED TEMPLATES
|
||||||
|
|
||||||
Feed templates are provided with the following data:
|
Feed templates are provided with the following data:
|
||||||
|
|
||||||
[[ *Variable*
|
*Title*
|
||||||
:[ *Description*
|
Title of the feed
|
||||||
| Title
|
|
||||||
: Title of the feed
|
*Path*
|
||||||
| Permalink
|
The path to the feed directory
|
||||||
: The permanent link to the feed directory
|
|
||||||
| Pages
|
*URL*
|
||||||
: List of pages in this feed
|
The URL of the feed directory
|
||||||
|
|
||||||
|
*Pages*
|
||||||
|
List of pages in this feed
|
||||||
|
|
||||||
## PARTIAL TEMPLATES
|
## PARTIAL TEMPLATES
|
||||||
|
|
||||||
|
|
2
main.go
2
main.go
|
@ -71,7 +71,7 @@ func (site *Site) run() error {
|
||||||
|
|
||||||
func (s *Site) runTask(task *Task) error {
|
func (s *Site) runTask(task *Task) error {
|
||||||
// Read content
|
// Read content
|
||||||
s.root = &Page{Permalink: "/", FilePath: ""}
|
s.root = &Page{Path: "/", FilePath: ""}
|
||||||
if err := s.root.read("content", task, s); err != nil {
|
if err := s.root.read("content", task, s); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
71
page.go
71
page.go
|
@ -18,19 +18,20 @@ import (
|
||||||
|
|
||||||
// Page represents a page.
|
// Page represents a page.
|
||||||
type Page struct {
|
type Page struct {
|
||||||
Title string
|
Title string
|
||||||
Date time.Time
|
Date time.Time
|
||||||
Weight int
|
Weight int
|
||||||
Params map[string]interface{}
|
Params map[string]interface{}
|
||||||
FilePath string `yaml:"-"`
|
Path string `yaml:"-"`
|
||||||
Permalink string `yaml:"-"`
|
FilePath string `yaml:"-"`
|
||||||
Content string `yaml:"-"`
|
URL string `yaml:"-"`
|
||||||
Prev *Page `yaml:"-"`
|
Content string `yaml:"-"`
|
||||||
Next *Page `yaml:"-"`
|
Prev *Page `yaml:"-"`
|
||||||
Pages []*Page `yaml:"-"`
|
Next *Page `yaml:"-"`
|
||||||
Dirs []*Page `yaml:"-"`
|
Pages []*Page `yaml:"-"`
|
||||||
feeds map[string][]byte
|
Dirs []*Page `yaml:"-"`
|
||||||
index bool
|
feeds map[string][]byte
|
||||||
|
index bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// read reads from a directory and indexes the files and directories within it.
|
// read reads from a directory and indexes the files and directories within it.
|
||||||
|
@ -52,7 +53,12 @@ func (p *Page) _read(srcDir, path string, task *Task, cfg *Site) error {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// Gather directory data
|
// Gather directory data
|
||||||
dir := &Page{Permalink: "/" + path + "/", FilePath: path}
|
dirPath := "/" + path + "/"
|
||||||
|
dir := &Page{
|
||||||
|
Path: dirPath,
|
||||||
|
FilePath: path,
|
||||||
|
URL: task.URL + dirPath,
|
||||||
|
}
|
||||||
if err := dir._read(srcDir, path, task, cfg); err != nil {
|
if err := dir._read(srcDir, path, task, cfg); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -134,12 +140,13 @@ func (p *Page) _read(srcDir, path string, task *Task, cfg *Site) error {
|
||||||
path += "/"
|
path += "/"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
page.Permalink = path
|
page.Path = path
|
||||||
if permalink, ok := cfg.permalinks[p.Permalink]; ok {
|
if permalink, ok := cfg.permalinks[p.Path]; ok {
|
||||||
var b strings.Builder
|
var b strings.Builder
|
||||||
permalink.Execute(&b, page)
|
permalink.Execute(&b, page)
|
||||||
page.Permalink = b.String()
|
page.Path = b.String()
|
||||||
}
|
}
|
||||||
|
page.URL = task.URL + page.Path
|
||||||
p.Pages = append(p.Pages, page)
|
p.Pages = append(p.Pages, page)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -161,7 +168,7 @@ func (p *Page) process(cfg *Site, task *Task) error {
|
||||||
if task.TemplateExt != "" {
|
if task.TemplateExt != "" {
|
||||||
// Create index
|
// Create index
|
||||||
if p.index {
|
if p.index {
|
||||||
tmpl, ok := cfg.templates.FindTemplate(p.Permalink, "index"+task.TemplateExt)
|
tmpl, ok := cfg.templates.FindTemplate(p.Path, "index"+task.TemplateExt)
|
||||||
if ok {
|
if ok {
|
||||||
var b strings.Builder
|
var b strings.Builder
|
||||||
if err := tmpl.Execute(&b, p); err != nil {
|
if err := tmpl.Execute(&b, p); err != nil {
|
||||||
|
@ -174,7 +181,7 @@ func (p *Page) process(cfg *Site, task *Task) error {
|
||||||
// Process pages
|
// Process pages
|
||||||
for i := range p.Pages {
|
for i := range p.Pages {
|
||||||
var b strings.Builder
|
var b strings.Builder
|
||||||
tmpl, ok := cfg.templates.FindTemplate(p.Permalink, "page"+task.TemplateExt)
|
tmpl, ok := cfg.templates.FindTemplate(p.Path, "page"+task.TemplateExt)
|
||||||
if ok {
|
if ok {
|
||||||
if err := tmpl.Execute(&b, p.Pages[i]); err != nil {
|
if err := tmpl.Execute(&b, p.Pages[i]); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -197,21 +204,23 @@ func (p *Page) process(cfg *Site, task *Task) error {
|
||||||
func (p *Page) buildFeed(cfg *Site, feed Feed) ([]byte, error) {
|
func (p *Page) buildFeed(cfg *Site, feed Feed) ([]byte, error) {
|
||||||
// Feed represents a feed.
|
// Feed represents a feed.
|
||||||
type Feed struct {
|
type Feed struct {
|
||||||
Title string
|
Title string
|
||||||
Permalink string
|
Path string
|
||||||
Pages []*Page
|
URL string
|
||||||
|
Pages []*Page
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpl, ok := cfg.templates.FindTemplate(p.Permalink, feed.Template)
|
tmpl, ok := cfg.templates.FindTemplate(p.Path, feed.Template)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("failed to generate feed %q: missing feed template %q", feed.Title, feed.Template)
|
return nil, fmt.Errorf("failed to generate feed %q: missing feed template %q", feed.Title, feed.Template)
|
||||||
}
|
}
|
||||||
|
|
||||||
var b bytes.Buffer
|
var b bytes.Buffer
|
||||||
data := Feed{
|
data := Feed{
|
||||||
Title: feed.Title,
|
Title: feed.Title,
|
||||||
Permalink: p.Permalink,
|
Path: p.Path,
|
||||||
Pages: p.Pages,
|
URL: p.URL,
|
||||||
|
Pages: p.Pages,
|
||||||
}
|
}
|
||||||
if err := tmpl.Execute(&b, data); err != nil {
|
if err := tmpl.Execute(&b, data); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -228,11 +237,11 @@ func (p *Page) addFeed(name string, content []byte) {
|
||||||
|
|
||||||
// write writes the directory's contents to the provided destination path.
|
// write writes the directory's contents to the provided destination path.
|
||||||
func (p *Page) write(dstDir string, task *Task) error {
|
func (p *Page) write(dstDir string, task *Task) error {
|
||||||
dirPath := pathpkg.Join(dstDir, p.Permalink)
|
dirPath := pathpkg.Join(dstDir, p.Path)
|
||||||
|
|
||||||
// Write pages
|
// Write pages
|
||||||
for _, page := range p.Pages {
|
for _, page := range p.Pages {
|
||||||
dstPath := pathpkg.Join(dstDir, page.Permalink)
|
dstPath := pathpkg.Join(dstDir, page.Path)
|
||||||
if !task.UglyURLs {
|
if !task.UglyURLs {
|
||||||
dstPath = pathpkg.Join(dstPath, "index"+task.OutputExt)
|
dstPath = pathpkg.Join(dstPath, "index"+task.OutputExt)
|
||||||
}
|
}
|
||||||
|
@ -242,7 +251,7 @@ func (p *Page) write(dstDir string, task *Task) error {
|
||||||
}
|
}
|
||||||
// Write index page
|
// Write index page
|
||||||
if p.index {
|
if p.index {
|
||||||
dstPath := pathpkg.Join(dstDir, p.Permalink, "index"+task.OutputExt)
|
dstPath := pathpkg.Join(dstDir, p.Path, "index"+task.OutputExt)
|
||||||
if err := p.writeTo(dstPath, task); err != nil {
|
if err := p.writeTo(dstPath, task); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -337,7 +346,7 @@ func execute(command string, input io.Reader, output io.Writer) error {
|
||||||
|
|
||||||
func (p *Page) getPage(path string) *Page {
|
func (p *Page) getPage(path string) *Page {
|
||||||
// XXX: This is inefficient
|
// XXX: This is inefficient
|
||||||
if p.Permalink == path {
|
if p.Path == path {
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
for _, page := range p.Pages {
|
for _, page := range p.Pages {
|
||||||
|
@ -346,7 +355,7 @@ func (p *Page) getPage(path string) *Page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, dir := range p.Dirs {
|
for _, dir := range p.Dirs {
|
||||||
if dir.Permalink == path {
|
if dir.Path == path {
|
||||||
return dir
|
return dir
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
17
site.go
17
site.go
|
@ -23,14 +23,15 @@ type Site struct {
|
||||||
|
|
||||||
// Task represents a site build task.
|
// Task represents a site build task.
|
||||||
type Task struct {
|
type Task struct {
|
||||||
Input []string `toml:"input"` // input file suffixes
|
Input []string `toml:"input"`
|
||||||
OutputExt string `toml:"output"` // output file suffix
|
OutputExt string `toml:"output"`
|
||||||
TemplateExt string `toml:"template"` // template file suffix
|
TemplateExt string `toml:"template"`
|
||||||
Preprocess map[string]string `toml:"preprocess"` // preprocess commands
|
Preprocess map[string]string `toml:"preprocess"`
|
||||||
Postprocess string `toml:"postprocess"` // postprocess command
|
Postprocess string `toml:"postprocess"`
|
||||||
StaticDir string `toml:"static_dir"` // static file directory
|
StaticDir string `toml:"static_dir"`
|
||||||
OutputDir string `toml:"output_dir"` // output directory
|
OutputDir string `toml:"output_dir"`
|
||||||
UglyURLs bool `toml:"ugly_urls"` // whether to use ugly URLs
|
URL string `toml:"url"`
|
||||||
|
UglyURLs bool `toml:"ugly_urls"`
|
||||||
Feeds []Feed `toml:"feeds"`
|
Feeds []Feed `toml:"feeds"`
|
||||||
feeds map[string][]Feed
|
feeds map[string][]Feed
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
{{ `<?xml version="1.0" encoding="utf-8"?>` | safeHTML }}
|
{{ `<?xml version="1.0" encoding="utf-8"?>` | safeHTML }}
|
||||||
<feed xmlns="http://www.w3.org/2005/Atom">
|
<feed xmlns="http://www.w3.org/2005/Atom">
|
||||||
<id>{{ .Permalink }}</id>
|
<id>{{ .URL }}</id>
|
||||||
<title>{{ .Title }}</title>
|
<title>{{ .Title }}</title>
|
||||||
<updated>{{ site.Generated.Format "2006-01-02T15:04:05Z07:00" }}</updated>
|
<updated>{{ site.Generated.Format "2006-01-02T15:04:05Z07:00" }}</updated>
|
||||||
<link href="{{ .Permalink }}" rel="alternate"/>
|
<link href="{{ .URL }}" rel="alternate"/>
|
||||||
{{ range .Pages }}<entry>
|
{{ range .Pages }}<entry>
|
||||||
<id>{{ .Permalink }}</id>
|
<id>{{ .URL }}</id>
|
||||||
<title>{{ .Title }}</title>
|
<title>{{ .Title }}</title>
|
||||||
<updated>{{ .Date.Format "2006-01-02T15:04:05Z07:00" }}</updated>
|
<updated>{{ .Date.Format "2006-01-02T15:04:05Z07:00" }}</updated>
|
||||||
</entry>
|
</entry>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# {{ .Title }}
|
# {{ .Title }}
|
||||||
{{ if .Content }}
|
{{ if .Content }}
|
||||||
{{ .Content }}{{ end }}
|
{{ .Content }}{{ end }}
|
||||||
{{ range .Pages }}=> {{ .Permalink }} {{ if not .Date.IsZero -}}
|
{{ range .Pages }}=> {{ .Path }} {{ if not .Date.IsZero -}}
|
||||||
{{.Date.Format "2006-01-02"}} {{end}}{{.Title}}
|
{{.Date.Format "2006-01-02"}} {{end}}{{.Title}}
|
||||||
{{ end -}}
|
{{ end -}}
|
||||||
|
|
Loading…
Reference in a new issue