mirror of
https://github.com/gohugoio/hugo.git
synced 2025-08-30 22:39:58 +02:00
Create a struct with all of Hugo's config options
Primary motivation is documentation, but it will also hopefully simplify the code. Also, * Lower case the default output format names; this is in line with the custom ones (map keys) and how it's treated all the places. This avoids doing `stringds.EqualFold` everywhere. Closes #10896 Closes #10620
This commit is contained in:
@@ -31,6 +31,7 @@ import (
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/gohugoio/hugo/common/types"
|
||||
"github.com/gohugoio/hugo/output/layouts"
|
||||
|
||||
"github.com/gohugoio/hugo/helpers"
|
||||
|
||||
@@ -131,7 +132,7 @@ func newStandaloneTextTemplate(funcs map[string]any) tpl.TemplateParseFinder {
|
||||
}
|
||||
}
|
||||
|
||||
func newTemplateExec(d *deps.Deps) (*templateExec, error) {
|
||||
func newTemplateHandlers(d *deps.Deps) (*tpl.TemplateHandlers, error) {
|
||||
exec, funcs := newTemplateExecuter(d)
|
||||
funcMap := make(map[string]any)
|
||||
for k, v := range funcs {
|
||||
@@ -139,7 +140,7 @@ func newTemplateExec(d *deps.Deps) (*templateExec, error) {
|
||||
}
|
||||
|
||||
var templateUsageTracker map[string]templateInfo
|
||||
if d.Cfg.GetBool("printUnusedTemplates") {
|
||||
if d.Conf.PrintUnusedTemplates() {
|
||||
templateUsageTracker = make(map[string]templateInfo)
|
||||
}
|
||||
|
||||
@@ -156,7 +157,7 @@ func newTemplateExec(d *deps.Deps) (*templateExec, error) {
|
||||
main: newTemplateNamespace(funcMap),
|
||||
|
||||
Deps: d,
|
||||
layoutHandler: output.NewLayoutHandler(),
|
||||
layoutHandler: layouts.NewLayoutHandler(),
|
||||
layoutsFs: d.BaseFs.Layouts.Fs,
|
||||
layoutTemplateCache: make(map[layoutCacheKey]layoutCacheEntry),
|
||||
|
||||
@@ -178,16 +179,15 @@ func newTemplateExec(d *deps.Deps) (*templateExec, error) {
|
||||
templateHandler: h,
|
||||
}
|
||||
|
||||
d.SetTmpl(e)
|
||||
d.SetTextTmpl(newStandaloneTextTemplate(funcMap))
|
||||
|
||||
if d.WithTemplate != nil {
|
||||
if err := d.WithTemplate(e); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := e.postTransform(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return e, nil
|
||||
return &tpl.TemplateHandlers{
|
||||
Tmpl: e,
|
||||
TxtTmpl: newStandaloneTextTemplate(funcMap),
|
||||
}, nil
|
||||
|
||||
}
|
||||
|
||||
func newTemplateNamespace(funcs map[string]any) *templateNamespace {
|
||||
@@ -211,7 +211,7 @@ func newTemplateState(templ tpl.Template, info templateInfo) *templateState {
|
||||
}
|
||||
|
||||
type layoutCacheKey struct {
|
||||
d output.LayoutDescriptor
|
||||
d layouts.LayoutDescriptor
|
||||
f string
|
||||
}
|
||||
|
||||
@@ -232,10 +232,6 @@ func (t templateExec) Clone(d *deps.Deps) *templateExec {
|
||||
}
|
||||
|
||||
func (t *templateExec) Execute(templ tpl.Template, wr io.Writer, data any) error {
|
||||
// TOD1
|
||||
if true {
|
||||
//panic("not implemented")
|
||||
}
|
||||
return t.ExecuteWithContext(context.Background(), templ, wr, data)
|
||||
}
|
||||
|
||||
@@ -250,6 +246,7 @@ func (t *templateExec) ExecuteWithContext(ctx context.Context, templ tpl.Templat
|
||||
|
||||
if t.templateUsageTracker != nil {
|
||||
if ts, ok := templ.(*templateState); ok {
|
||||
|
||||
t.templateUsageTrackerMu.Lock()
|
||||
if _, found := t.templateUsageTracker[ts.Name()]; !found {
|
||||
t.templateUsageTracker[ts.Name()] = ts.info
|
||||
@@ -335,7 +332,7 @@ type templateHandler struct {
|
||||
// stored in the root of this filesystem.
|
||||
layoutsFs afero.Fs
|
||||
|
||||
layoutHandler *output.LayoutHandler
|
||||
layoutHandler *layouts.LayoutHandler
|
||||
|
||||
layoutTemplateCache map[layoutCacheKey]layoutCacheEntry
|
||||
layoutTemplateCacheMu sync.RWMutex
|
||||
@@ -392,7 +389,7 @@ func (t *templateHandler) Lookup(name string) (tpl.Template, bool) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (t *templateHandler) LookupLayout(d output.LayoutDescriptor, f output.Format) (tpl.Template, bool, error) {
|
||||
func (t *templateHandler) LookupLayout(d layouts.LayoutDescriptor, f output.Format) (tpl.Template, bool, error) {
|
||||
key := layoutCacheKey{d, f.Name}
|
||||
t.layoutTemplateCacheMu.RLock()
|
||||
if cacheVal, found := t.layoutTemplateCache[key]; found {
|
||||
@@ -459,8 +456,10 @@ func (t *templateHandler) HasTemplate(name string) bool {
|
||||
return found
|
||||
}
|
||||
|
||||
func (t *templateHandler) findLayout(d output.LayoutDescriptor, f output.Format) (tpl.Template, bool, error) {
|
||||
layouts, _ := t.layoutHandler.For(d, f)
|
||||
func (t *templateHandler) findLayout(d layouts.LayoutDescriptor, f output.Format) (tpl.Template, bool, error) {
|
||||
d.OutputFormatName = f.Name
|
||||
d.Suffix = f.MediaType.FirstSuffix.Suffix
|
||||
layouts, _ := t.layoutHandler.For(d)
|
||||
for _, name := range layouts {
|
||||
templ, found := t.main.Lookup(name)
|
||||
if found {
|
||||
@@ -474,7 +473,7 @@ func (t *templateHandler) findLayout(d output.LayoutDescriptor, f output.Format)
|
||||
}
|
||||
|
||||
d.Baseof = true
|
||||
baseLayouts, _ := t.layoutHandler.For(d, f)
|
||||
baseLayouts, _ := t.layoutHandler.For(d)
|
||||
var base templateInfo
|
||||
found = false
|
||||
for _, l := range baseLayouts {
|
||||
@@ -813,7 +812,8 @@ func (t *templateHandler) loadTemplates() error {
|
||||
|
||||
name := strings.TrimPrefix(filepath.ToSlash(path), "/")
|
||||
filename := filepath.Base(path)
|
||||
outputFormat, found := t.OutputFormatsConfig.FromFilename(filename)
|
||||
outputFormats := t.Conf.GetConfigSection("outputFormats").(output.Formats)
|
||||
outputFormat, found := outputFormats.FromFilename(filename)
|
||||
|
||||
if found && outputFormat.IsPlainText {
|
||||
name = textTmplNamePrefix + name
|
||||
|
@@ -15,6 +15,7 @@ package tplimpl
|
||||
|
||||
import (
|
||||
"github.com/gohugoio/hugo/deps"
|
||||
"github.com/gohugoio/hugo/tpl"
|
||||
)
|
||||
|
||||
// TemplateProvider manages templates.
|
||||
@@ -25,17 +26,26 @@ var DefaultTemplateProvider *TemplateProvider
|
||||
|
||||
// Update updates the Hugo Template System in the provided Deps
|
||||
// with all the additional features, templates & functions.
|
||||
func (*TemplateProvider) Update(d *deps.Deps) error {
|
||||
tmpl, err := newTemplateExec(d)
|
||||
func (*TemplateProvider) NewResource(dst *deps.Deps) error {
|
||||
handlers, err := newTemplateHandlers(dst)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return tmpl.postTransform()
|
||||
dst.SetTempl(handlers)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Clone clones.
|
||||
func (*TemplateProvider) Clone(d *deps.Deps) error {
|
||||
t := d.Tmpl().(*templateExec)
|
||||
d.SetTmpl(t.Clone(d))
|
||||
func (*TemplateProvider) CloneResource(dst, src *deps.Deps) error {
|
||||
t := src.Tmpl().(*templateExec)
|
||||
c := t.Clone(dst)
|
||||
funcMap := make(map[string]any)
|
||||
for k, v := range c.funcs {
|
||||
funcMap[k] = v.Interface()
|
||||
}
|
||||
dst.SetTempl(&tpl.TemplateHandlers{
|
||||
Tmpl: c,
|
||||
TxtTmpl: newStandaloneTextTemplate(funcMap),
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
@@ -71,8 +71,10 @@ var (
|
||||
)
|
||||
|
||||
type templateExecHelper struct {
|
||||
running bool // whether we're in server mode.
|
||||
funcs map[string]reflect.Value
|
||||
running bool // whether we're in server mode.
|
||||
site reflect.Value
|
||||
siteParams reflect.Value
|
||||
funcs map[string]reflect.Value
|
||||
}
|
||||
|
||||
func (t *templateExecHelper) GetFunc(ctx context.Context, tmpl texttemplate.Preparer, name string) (fn reflect.Value, firstArg reflect.Value, found bool) {
|
||||
@@ -111,6 +113,8 @@ func (t *templateExecHelper) GetMapValue(ctx context.Context, tmpl texttemplate.
|
||||
return v, v.IsValid()
|
||||
}
|
||||
|
||||
var typeParams = reflect.TypeOf(maps.Params{})
|
||||
|
||||
func (t *templateExecHelper) GetMethod(ctx context.Context, tmpl texttemplate.Preparer, receiver reflect.Value, name string) (method reflect.Value, firstArg reflect.Value) {
|
||||
if t.running {
|
||||
switch name {
|
||||
@@ -123,6 +127,13 @@ func (t *templateExecHelper) GetMethod(ctx context.Context, tmpl texttemplate.Pr
|
||||
}
|
||||
}
|
||||
|
||||
if strings.EqualFold(name, "mainsections") && receiver.Type() == typeParams && receiver.Pointer() == t.siteParams.Pointer() {
|
||||
// MOved to site.MainSections in Hugo 0.112.0.
|
||||
receiver = t.site
|
||||
name = "MainSections"
|
||||
|
||||
}
|
||||
|
||||
fn := hreflect.GetMethodByName(receiver, name)
|
||||
if !fn.IsValid() {
|
||||
return zero, zero
|
||||
@@ -167,8 +178,10 @@ func newTemplateExecuter(d *deps.Deps) (texttemplate.Executer, map[string]reflec
|
||||
}
|
||||
|
||||
exeHelper := &templateExecHelper{
|
||||
running: d.Running,
|
||||
funcs: funcsv,
|
||||
running: d.Conf.Running(),
|
||||
funcs: funcsv,
|
||||
site: reflect.ValueOf(d.Site),
|
||||
siteParams: reflect.ValueOf(d.Site.Params()),
|
||||
}
|
||||
|
||||
return texttemplate.NewExecuter(
|
||||
|
Reference in New Issue
Block a user