summaryrefslogtreecommitdiffstats
path: root/create/content_template_handler.go
diff options
context:
space:
mode:
Diffstat (limited to 'create/content_template_handler.go')
-rw-r--r--create/content_template_handler.go148
1 files changed, 148 insertions, 0 deletions
diff --git a/create/content_template_handler.go b/create/content_template_handler.go
new file mode 100644
index 000000000..02598d4d3
--- /dev/null
+++ b/create/content_template_handler.go
@@ -0,0 +1,148 @@
+// Copyright 2017 The Hugo Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package create
+
+import (
+ "bytes"
+ "fmt"
+ "path/filepath"
+ "strings"
+ "time"
+
+ "github.com/gohugoio/hugo/helpers"
+ "github.com/gohugoio/hugo/source"
+
+ "github.com/gohugoio/hugo/hugolib"
+ "github.com/gohugoio/hugo/tpl"
+ "github.com/spf13/afero"
+)
+
+// ArchetypeFileData represents the data available to an archetype template.
+type ArchetypeFileData struct {
+ // The archetype content type, either given as --kind option or extracted
+ // from the target path's section, i.e. "blog/mypost.md" will resolve to
+ // "blog".
+ Type string
+
+ // The current date and time as a RFC3339 formatted string, suitable for use in front matter.
+ Date string
+
+ // The Site, fully equipped with all the pages etc. Note: This will only be set if it is actually
+ // used in the archetype template. Also, if this is a multilingual setup,
+ // this site is the site that best matches the target content file, based
+ // on the presence of language code in the filename.
+ Site *hugolib.SiteInfo
+
+ // Name will in most cases be the same as TranslationBaseName, e.g. "my-post".
+ // But if that value is "index" (bundles), the Name is instead the owning folder.
+ // This is the value you in most cases would want to use to construct the title in your
+ // archetype template.
+ Name string
+
+ // The target content file. Note that the .Content will be empty, as that
+ // has not been created yet.
+ source.File
+}
+
+const (
+ // ArchetypeTemplateTemplate is used as initial template when adding an archetype template.
+ ArchetypeTemplateTemplate = `---
+title: "{{ replace .Name "-" " " | title }}"
+date: {{ .Date }}
+draft: true
+---
+
+`
+)
+
+var (
+ archetypeShortcodeReplacementsPre = strings.NewReplacer(
+ "{{<", "{x{<",
+ "{{%", "{x{%",
+ ">}}", ">}x}",
+ "%}}", "%}x}")
+
+ archetypeShortcodeReplacementsPost = strings.NewReplacer(
+ "{x{<", "{{<",
+ "{x{%", "{{%",
+ ">}x}", ">}}",
+ "%}x}", "%}}")
+)
+
+func executeArcheTypeAsTemplate(s *hugolib.Site, kind, targetPath, archetypeFilename string) ([]byte, error) {
+
+ var (
+ archetypeContent []byte
+ archetypeTemplate []byte
+ err error
+ )
+
+ ps, err := helpers.NewPathSpec(s.Deps.Fs, s.Deps.Cfg)
+ if err != nil {
+ return nil, err
+ }
+ sp := source.NewSourceSpec(ps, ps.Fs.Source)
+
+ f := sp.NewFileInfo("", targetPath, false, nil)
+
+ name := f.TranslationBaseName()
+
+ if name == "index" || name == "_index" {
+ // Page bundles; the directory name will hopefully have a better name.
+ dir := strings.TrimSuffix(f.Dir(), helpers.FilePathSeparator)
+ _, name = filepath.Split(dir)
+ }
+
+ data := ArchetypeFileData{
+ Type: kind,
+ Date: time.Now().Format(time.RFC3339),
+ Name: name,
+ File: f,
+ Site: &s.Info,
+ }
+
+ if archetypeFilename == "" {
+ // TODO(bep) archetype revive the issue about wrong tpl funcs arg order
+ archetypeTemplate = []byte(ArchetypeTemplateTemplate)
+ } else {
+ archetypeTemplate, err = afero.ReadFile(s.BaseFs.Archetypes.Fs, archetypeFilename)
+ if err != nil {
+ return nil, fmt.Errorf("failed to read archetype file %s", err)
+ }
+
+ }
+
+ // The archetype template may contain shortcodes, and these does not play well
+ // with the Go templates. Need to set some temporary delimiters.
+ archetypeTemplate = []byte(archetypeShortcodeReplacementsPre.Replace(string(archetypeTemplate)))
+
+ // Reuse the Hugo template setup to get the template funcs properly set up.
+ templateHandler := s.Deps.Tmpl.(tpl.TemplateHandler)
+ templateName := "_text/" + helpers.Filename(archetypeFilename)
+ if err := templateHandler.AddTemplate(templateName, string(archetypeTemplate)); err != nil {
+ return nil, fmt.Errorf("Failed to parse archetype file %q: %s", archetypeFilename, err)
+ }
+
+ templ, _ := templateHandler.Lookup(templateName)
+
+ var buff bytes.Buffer
+ if err := templ.Execute(&buff, data); err != nil {
+ return nil, fmt.Errorf("Failed to process archetype file %q: %s", archetypeFilename, err)
+ }
+
+ archetypeContent = []byte(archetypeShortcodeReplacementsPost.Replace(buff.String()))
+
+ return archetypeContent, nil
+
+}