summaryrefslogtreecommitdiffstats
path: root/hugolib/site.go
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2019-11-27 13:42:36 +0100
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2019-12-18 11:44:40 +0100
commite625088ef5a970388ad50e464e87db56b358dac4 (patch)
treef7b26dec1f3695411558d05ca7d0995817a42250 /hugolib/site.go
parent67f3aa72cf9aaf3d6e447fa6bc12de704d46adf7 (diff)
Add render template hooks for links and images
This commit also * revises the change detection for templates used by content files in server mode. * Adds a Page.RenderString method Fixes #6545 Fixes #4663 Closes #6043
Diffstat (limited to 'hugolib/site.go')
-rw-r--r--hugolib/site.go120
1 files changed, 63 insertions, 57 deletions
diff --git a/hugolib/site.go b/hugolib/site.go
index 67ddff4d9..866ff5624 100644
--- a/hugolib/site.go
+++ b/hugolib/site.go
@@ -28,6 +28,12 @@ import (
"strings"
"time"
+ "github.com/gohugoio/hugo/resources"
+
+ "github.com/gohugoio/hugo/identity"
+
+ "github.com/gohugoio/hugo/markup/converter/hooks"
+
"github.com/gohugoio/hugo/resources/resource"
"github.com/gohugoio/hugo/markup/converter"
@@ -60,7 +66,6 @@ import (
"github.com/gohugoio/hugo/navigation"
"github.com/gohugoio/hugo/output"
"github.com/gohugoio/hugo/related"
- "github.com/gohugoio/hugo/resources"
"github.com/gohugoio/hugo/resources/page/pagemeta"
"github.com/gohugoio/hugo/source"
"github.com/gohugoio/hugo/tpl"
@@ -801,7 +806,6 @@ func (s *Site) multilingual() *Multilingual {
type whatChanged struct {
source bool
- other bool
files map[string]bool
}
@@ -888,10 +892,11 @@ func (s *Site) translateFileEvents(events []fsnotify.Event) []fsnotify.Event {
// It returns whetever the content source was changed.
// TODO(bep) clean up/rewrite this method.
func (s *Site) processPartial(config *BuildCfg, init func(config *BuildCfg) error, events []fsnotify.Event) error {
-
events = s.filterFileEvents(events)
events = s.translateFileEvents(events)
+ changeIdentities := make(identity.Identities)
+
s.Log.DEBUG.Printf("Rebuild for events %q", events)
h := s.h
@@ -902,11 +907,12 @@ func (s *Site) processPartial(config *BuildCfg, init func(config *BuildCfg) erro
sourceChanged = []fsnotify.Event{}
sourceReallyChanged = []fsnotify.Event{}
contentFilesChanged []string
- tmplChanged = []fsnotify.Event{}
- dataChanged = []fsnotify.Event{}
- i18nChanged = []fsnotify.Event{}
- shortcodesChanged = make(map[string]bool)
- sourceFilesChanged = make(map[string]bool)
+
+ tmplChanged bool
+ dataChanged bool
+ i18nChanged bool
+
+ sourceFilesChanged = make(map[string]bool)
// prevent spamming the log on changes
logger = helpers.NewDistinctFeedbackLogger()
@@ -919,33 +925,30 @@ func (s *Site) processPartial(config *BuildCfg, init func(config *BuildCfg) erro
cachePartitions = append(cachePartitions, resources.ResourceKeyPartitions(assetsFilename)...)
}
- if s.isContentDirEvent(ev) {
- logger.Println("Source changed", ev)
- sourceChanged = append(sourceChanged, ev)
- }
- if s.isLayoutDirEvent(ev) {
- logger.Println("Template changed", ev)
- tmplChanged = append(tmplChanged, ev)
-
- if strings.Contains(ev.Name, "shortcodes") {
- shortcode := filepath.Base(ev.Name)
- shortcode = strings.TrimSuffix(shortcode, filepath.Ext(shortcode))
- shortcodesChanged[shortcode] = true
+ id, found := s.eventToIdentity(ev)
+ if found {
+ changeIdentities[id] = id
+
+ switch id.Type {
+ case files.ComponentFolderContent:
+ logger.Println("Source changed", ev)
+ sourceChanged = append(sourceChanged, ev)
+ case files.ComponentFolderLayouts:
+ logger.Println("Template changed", ev)
+ tmplChanged = true
+ case files.ComponentFolderData:
+ logger.Println("Data changed", ev)
+ dataChanged = true
+ case files.ComponentFolderI18n:
+ logger.Println("i18n changed", ev)
+ i18nChanged = true
+
}
}
- if s.isDataDirEvent(ev) {
- logger.Println("Data changed", ev)
- dataChanged = append(dataChanged, ev)
- }
- if s.isI18nEvent(ev) {
- logger.Println("i18n changed", ev)
- i18nChanged = append(dataChanged, ev)
- }
}
changed := &whatChanged{
- source: len(sourceChanged) > 0 || len(shortcodesChanged) > 0,
- other: len(tmplChanged) > 0 || len(i18nChanged) > 0 || len(dataChanged) > 0,
+ source: len(sourceChanged) > 0,
files: sourceFilesChanged,
}
@@ -960,7 +963,7 @@ func (s *Site) processPartial(config *BuildCfg, init func(config *BuildCfg) erro
s.ResourceSpec.ResourceCache.DeletePartitions(cachePartitions...)
}
- if len(tmplChanged) > 0 || len(i18nChanged) > 0 {
+ if tmplChanged || i18nChanged {
sites := s.h.Sites
first := sites[0]
@@ -989,7 +992,7 @@ func (s *Site) processPartial(config *BuildCfg, init func(config *BuildCfg) erro
}
}
- if len(dataChanged) > 0 {
+ if dataChanged {
s.h.init.data.Reset()
}
@@ -1018,18 +1021,7 @@ func (s *Site) processPartial(config *BuildCfg, init func(config *BuildCfg) erro
sourceFilesChanged[ev.Name] = true
}
- for shortcode := range shortcodesChanged {
- // There are certain scenarios that, when a shortcode changes,
- // it isn't sufficient to just rerender the already parsed shortcode.
- // One example is if the user adds a new shortcode to the content file first,
- // and then creates the shortcode on the file system.
- // To handle these scenarios, we must do a full reprocessing of the
- // pages that keeps a reference to the changed shortcode.
- pagesWithShortcode := h.findPagesByShortcode(shortcode)
- for _, p := range pagesWithShortcode {
- contentFilesChanged = append(contentFilesChanged, p.File().Filename())
- }
- }
+ h.resetPageStateFromEvents(changeIdentities)
if len(sourceReallyChanged) > 0 || len(contentFilesChanged) > 0 {
var filenamesChanged []string
@@ -1218,20 +1210,14 @@ func (s *Site) initializeSiteInfo() error {
return nil
}
-func (s *Site) isI18nEvent(e fsnotify.Event) bool {
- return s.BaseFs.SourceFilesystems.IsI18n(e.Name)
-}
-
-func (s *Site) isDataDirEvent(e fsnotify.Event) bool {
- return s.BaseFs.SourceFilesystems.IsData(e.Name)
-}
-
-func (s *Site) isLayoutDirEvent(e fsnotify.Event) bool {
- return s.BaseFs.SourceFilesystems.IsLayout(e.Name)
-}
+func (s *Site) eventToIdentity(e fsnotify.Event) (identity.PathIdentity, bool) {
+ for _, fs := range s.BaseFs.SourceFilesystems.FileSystems() {
+ if p := fs.Path(e.Name); p != "" {
+ return identity.NewPathIdentity(fs.Name, p), true
+ }
+ }
-func (s *Site) isContentDirEvent(e fsnotify.Event) bool {
- return s.BaseFs.IsContent(e.Name)
+ return identity.PathIdentity{}, false
}
func (s *Site) readAndProcessContent(filenames ...string) error {
@@ -1562,6 +1548,26 @@ var infoOnMissingLayout = map[string]bool{
"404": true,
}
+type contentLinkRenderer struct {
+ templateHandler tpl.TemplateHandler
+ identity.Provider
+ templ tpl.Template
+}
+
+func (r contentLinkRenderer) Render(w io.Writer, ctx hooks.LinkContext) error {
+ return r.templateHandler.Execute(r.templ, w, ctx)
+}
+
+func (s *Site) lookupTemplate(layouts ...string) (tpl.Template, bool) {
+ for _, l := range layouts {
+ if templ, found := s.Tmpl.Lookup(l); found {
+ return templ, true
+ }
+ }
+
+ return nil, false
+}
+
func (s *Site) renderForLayouts(name, outputFormat string, d interface{}, w io.Writer, layouts ...string) (err error) {
templ := s.findFirstTemplate(layouts...)
if templ == nil {