1
0
mirror of https://github.com/danog/gojekyll.git synced 2024-11-27 12:44:54 +01:00
gojekyll/page.go

140 lines
3.4 KiB
Go
Raw Normal View History

package gojekyll
import (
"fmt"
2017-06-12 02:51:01 +02:00
"io"
"io/ioutil"
2017-06-17 06:16:59 +02:00
"os"
2017-06-17 06:12:09 +02:00
"path"
"path/filepath"
"reflect"
"regexp"
2017-06-17 06:16:59 +02:00
"time"
2017-06-17 02:11:52 +02:00
"github.com/osteele/gojekyll/helpers"
)
var (
2017-06-15 16:17:21 +02:00
frontMatterMatcher = regexp.MustCompile(`(?s)^---\n(.+?\n)---\n`)
emptyFontMatterMatcher = regexp.MustCompile(`(?s)^---\n+---\n`)
)
2017-06-15 13:19:49 +02:00
// Page is a Jekyll page.
type Page interface {
Path() string
Site() *Site
Source() string
Static() bool
Published() bool
Permalink() string
2017-06-15 13:19:49 +02:00
TemplateObject() VariableMap
Write(io.Writer) error
DebugVariables() VariableMap
initPermalink() error
}
type pageFields struct {
2017-06-17 06:16:59 +02:00
relpath string // relative to site source, e.g. "_post/base.ext"
permalink string // cached permalink
modTime time.Time
2017-06-17 02:06:55 +02:00
frontMatter VariableMap // page front matter, merged with defaults
2017-06-17 02:19:46 +02:00
collection *Collection
site *Site
}
func (p *pageFields) String() string {
2017-06-17 02:06:55 +02:00
return fmt.Sprintf("%s{Path=%v, Permalink=%v}", reflect.TypeOf(p).Name(), p.relpath, p.permalink)
}
2017-06-17 02:06:55 +02:00
func (p *pageFields) Path() string { return p.relpath }
func (p *pageFields) Permalink() string { return p.permalink }
2017-06-17 02:06:55 +02:00
func (p *pageFields) Published() bool { return p.frontMatter.Bool("published", true) }
func (p *pageFields) Site() *Site { return p.site }
2017-06-15 15:07:06 +02:00
// ReadPage reads a Page from a file, using defaults as the default front matter.
2017-06-17 02:19:46 +02:00
func ReadPage(site *Site, collection *Collection, relpath string, defaults VariableMap) (p Page, err error) {
2017-06-17 06:16:59 +02:00
abspath := filepath.Join(site.Source, relpath)
magic, err := helpers.ReadFileMagic(abspath)
if err != nil {
return
}
info, err := os.Stat(abspath)
2017-06-15 15:07:06 +02:00
if err != nil {
2017-06-16 19:47:11 +02:00
return
2017-06-15 15:07:06 +02:00
}
2017-06-17 06:16:59 +02:00
fields := pageFields{
site: site,
collection: collection,
modTime: info.ModTime(),
relpath: relpath,
frontMatter: defaults,
}
2017-06-16 19:47:11 +02:00
if string(magic) == "---\n" {
p, err = NewDynamicPage(fields)
if err != nil {
return
}
2017-06-15 15:07:06 +02:00
} else {
2017-06-16 19:47:11 +02:00
p = &StaticPage{fields}
}
// Compute this after creating the page, in order to pick up the front matter.
err = p.initPermalink()
if err != nil {
return
2017-06-15 15:07:06 +02:00
}
return
}
func (p *StaticPage) Write(w io.Writer) error {
source, err := ioutil.ReadFile(p.Source())
if err != nil {
return err
}
_, err = w.Write(source)
return err
}
// TemplateObject returns the attributes of the template page object.
// See https://jekyllrb.com/docs/variables/#page-variables
func (p *pageFields) TemplateObject() VariableMap {
var (
2017-06-17 06:12:09 +02:00
relpath = "/" + filepath.ToSlash(p.relpath)
base = path.Base(relpath)
ext = path.Ext(relpath)
2017-06-15 15:07:06 +02:00
)
return VariableMap{
2017-06-17 06:12:09 +02:00
"path": relpath,
2017-06-17 06:16:59 +02:00
"modified_time": p.modTime,
2017-06-15 15:07:06 +02:00
"name": base,
2017-06-17 02:11:52 +02:00
"basename": helpers.PathWithoutExtension(base),
2017-06-15 15:07:06 +02:00
"extname": ext,
}
}
// DebugVariables returns a map that's useful to present during diagnostics.
// For a static page, this is just the page's template object attributes.
func (p *pageFields) DebugVariables() VariableMap {
return p.TemplateObject()
}
// Source returns the file path of the page source.
func (p *pageFields) Source() string {
2017-06-17 02:06:55 +02:00
return filepath.Join(p.site.Source, p.relpath)
2017-06-15 15:07:06 +02:00
}
2017-06-15 13:19:49 +02:00
// StaticPage is a static page.
type StaticPage struct {
pageFields
}
2017-06-15 15:07:06 +02:00
// Static returns a bool indicating that the page is a static page.
func (p *StaticPage) Static() bool { return true }
// TemplateObject returns metadata for use in the representation of the page as a collection item
func (p *StaticPage) TemplateObject() VariableMap {
return MergeVariableMaps(p.frontMatter, p.pageFields.TemplateObject())
2017-06-15 15:07:06 +02:00
}