mirror of
https://github.com/gohugoio/hugo.git
synced 2025-04-26 21:51:02 +03:00
create: Use archetype template as-is as a Go template
This commit removes the fragile front matter decoding, and takes the provided archetype file as-is and processes it as a template. This also means that we no longer will attempt to fill in default values for `title` and `date`. The upside is that it is now easy to create these values in a dynamic way: ```toml +++ title = {{ .BaseFileName | title }} date = {{ .Date }} draft = true +++ ``` You can currently use all of Hugo's template funcs, but the data context is currently very shallow: * `.Type` gives the archetype kind provided * `.Name` gives the target file name without extension. * `.Path` gives the target file name * `.Date` gives the current time as RFC3339 formatted string The above will probably be extended in #1629. Fixes #452 Updates #1629
This commit is contained in:
parent
4aa1239070
commit
422057f607
5 changed files with 116 additions and 100 deletions
|
@ -19,68 +19,40 @@ import (
|
|||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gohugoio/hugo/helpers"
|
||||
"github.com/gohugoio/hugo/hugolib"
|
||||
"github.com/gohugoio/hugo/parser"
|
||||
"github.com/spf13/afero"
|
||||
"github.com/spf13/cast"
|
||||
jww "github.com/spf13/jwalterweatherman"
|
||||
)
|
||||
|
||||
// NewContent creates a new content file in the content directory based upon the
|
||||
// given kind, which is used to lookup an archetype.
|
||||
func NewContent(s *hugolib.Site, kind, name string) (err error) {
|
||||
jww.INFO.Println("attempting to create ", name, "of", kind)
|
||||
func NewContent(s *hugolib.Site, kind, targetPath string) error {
|
||||
jww.INFO.Println("attempting to create ", targetPath, "of", kind)
|
||||
|
||||
location := FindArchetype(s, kind)
|
||||
archetypeFilename := findArchetype(s, kind)
|
||||
|
||||
var by []byte
|
||||
var (
|
||||
content []byte
|
||||
err error
|
||||
)
|
||||
|
||||
if location != "" {
|
||||
by, err = afero.ReadFile(s.Fs.Source, location)
|
||||
if err != nil {
|
||||
jww.ERROR.Println(err)
|
||||
}
|
||||
}
|
||||
if location == "" || err != nil {
|
||||
by = []byte("+++\ndraft = true \n+++\n")
|
||||
}
|
||||
|
||||
psr, err := parser.ReadFrom(bytes.NewReader(by))
|
||||
content, err = executeArcheTypeAsTemplate(s, kind, targetPath, archetypeFilename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
metadata, err := createMetadata(psr, name)
|
||||
if err != nil {
|
||||
jww.ERROR.Printf("Error processing archetype file %s: %s\n", location, err)
|
||||
contentPath := s.PathSpec.AbsPathify(filepath.Join(s.Cfg.GetString("contentDir"), targetPath))
|
||||
|
||||
if err := helpers.SafeWriteToDisk(contentPath, bytes.NewReader(content), s.Fs.Source); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
page, err := s.NewPage(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = page.SetSourceMetaData(metadata, parser.FormatToLeadRune(s.Cfg.GetString("metaDataFormat"))); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
page.SetSourceContent(psr.Content())
|
||||
|
||||
contentPath := s.PathSpec.AbsPathify(filepath.Join(s.Cfg.GetString("contentDir"), name))
|
||||
|
||||
if err = page.SafeSaveSourceAs(contentPath); err != nil {
|
||||
return
|
||||
}
|
||||
jww.FEEDBACK.Println(contentPath, "created")
|
||||
|
||||
editor := s.Cfg.GetString("newContentEditor")
|
||||
if editor != "" {
|
||||
jww.FEEDBACK.Printf("Editing %s with %q ...\n", name, editor)
|
||||
jww.FEEDBACK.Printf("Editing %s with %q ...\n", targetPath, editor)
|
||||
|
||||
cmd := exec.Command(editor, contentPath)
|
||||
cmd.Stdin = os.Stdin
|
||||
|
@ -93,59 +65,10 @@ func NewContent(s *hugolib.Site, kind, name string) (err error) {
|
|||
return nil
|
||||
}
|
||||
|
||||
// createMetadata generates Metadata for a new page based upon the metadata
|
||||
// found in an archetype.
|
||||
func createMetadata(archetype parser.Page, name string) (map[string]interface{}, error) {
|
||||
archMetadata, err := archetype.Metadata()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
metadata, err := cast.ToStringMapE(archMetadata)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var date time.Time
|
||||
|
||||
for k, v := range metadata {
|
||||
if v == "" {
|
||||
continue
|
||||
}
|
||||
lk := strings.ToLower(k)
|
||||
switch lk {
|
||||
case "date":
|
||||
date, err = cast.ToTimeE(v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case "title":
|
||||
// Use the archetype title as is
|
||||
metadata[lk] = v
|
||||
}
|
||||
}
|
||||
|
||||
if metadata == nil {
|
||||
metadata = make(map[string]interface{})
|
||||
}
|
||||
|
||||
if date.IsZero() {
|
||||
date = time.Now()
|
||||
}
|
||||
|
||||
if _, ok := metadata["title"]; !ok {
|
||||
metadata["title"] = helpers.MakeTitle(helpers.Filename(name))
|
||||
}
|
||||
|
||||
metadata["date"] = date.Format(time.RFC3339)
|
||||
|
||||
return metadata, nil
|
||||
}
|
||||
|
||||
// FindArchetype takes a given kind/archetype of content and returns an output
|
||||
// path for that archetype. If no archetype is found, an empty string is
|
||||
// returned.
|
||||
func FindArchetype(s *hugolib.Site, kind string) (outpath string) {
|
||||
func findArchetype(s *hugolib.Site, kind string) (outpath string) {
|
||||
search := []string{s.PathSpec.AbsPathify(s.Cfg.GetString("archetypeDir"))}
|
||||
|
||||
if s.Cfg.GetString("theme") != "" {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue