Skip to content

Reimplement and simplify Hugo's template system #13541

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions commands/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"errors"
"fmt"
"io"
"maps"
"net"
"net/http"
_ "net/http/pprof"
Expand All @@ -48,6 +49,7 @@ import (
"github.com/fsnotify/fsnotify"
"github.com/gohugoio/hugo/common/herrors"
"github.com/gohugoio/hugo/common/hugo"
"github.com/gohugoio/hugo/tpl/tplimpl"

"github.com/gohugoio/hugo/common/types"
"github.com/gohugoio/hugo/common/urls"
Expand All @@ -57,15 +59,13 @@ import (
"github.com/gohugoio/hugo/hugolib"
"github.com/gohugoio/hugo/hugolib/filesystems"
"github.com/gohugoio/hugo/livereload"
"github.com/gohugoio/hugo/tpl"
"github.com/gohugoio/hugo/transform"
"github.com/gohugoio/hugo/transform/livereloadinject"
"github.com/spf13/afero"
"github.com/spf13/cobra"
"github.com/spf13/fsync"
"golang.org/x/sync/errgroup"
"golang.org/x/sync/semaphore"
"maps"
)

var (
Expand Down Expand Up @@ -897,16 +897,16 @@ func (c *serverCommand) serve() error {
// To allow the en user to change the error template while the server is running, we use
// the freshest template we can provide.
var (
errTempl tpl.Template
templHandler tpl.TemplateHandler
errTempl *tplimpl.TemplInfo
templHandler *tplimpl.TemplateStore
)
getErrorTemplateAndHandler := func(h *hugolib.HugoSites) (tpl.Template, tpl.TemplateHandler) {
getErrorTemplateAndHandler := func(h *hugolib.HugoSites) (*tplimpl.TemplInfo, *tplimpl.TemplateStore) {
if h == nil {
return errTempl, templHandler
}
templHandler := h.Tmpl()
errTempl, found := templHandler.Lookup("_server/error.html")
if !found {
templHandler := h.GetTemplateStore()
errTempl := templHandler.LookupByPath("/_server/error.html")
if errTempl == nil {
panic("template server/error.html not found")
}
return errTempl, templHandler
Expand Down
1 change: 1 addition & 0 deletions common/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const (
WarnFrontMatterParamsOverrides = "warning-frontmatter-params-overrides"
WarnRenderShortcodesInHTML = "warning-rendershortcodes-in-html"
WarnGoldmarkRawHTML = "warning-goldmark-raw-html"
WarnPartialSuperfluousPrefix = "warning-partial-superfluous-prefix"
)

// Field/method names with special meaning.
Expand Down
10 changes: 5 additions & 5 deletions common/hstrings/strings.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ package hstrings
import (
"fmt"
"regexp"
"slices"
"strings"
"sync"

"github.com/gohugoio/hugo/compare"
"slices"
)

var _ compare.Eqer = StringEqualFold("")
Expand Down Expand Up @@ -128,7 +128,7 @@ func ToString(v any) (string, bool) {
return "", false
}

type Tuple struct {
First string
Second string
}
type (
Strings2 [2]string
Strings3 [3]string
)
19 changes: 19 additions & 0 deletions common/maps/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,14 @@ func (c *Cache[K, T]) GetOrCreate(key K, create func() (T, error)) (T, error) {
return v, nil
}

// Contains returns whether the given key exists in the cache.
func (c *Cache[K, T]) Contains(key K) bool {
c.RLock()
_, found := c.m[key]
c.RUnlock()
return found
}

// InitAndGet initializes the cache if not already done and returns the value for the given key.
// The init state will be reset on Reset or Drain.
func (c *Cache[K, T]) InitAndGet(key K, init func(get func(key K) (T, bool), set func(key K, value T)) error) (T, error) {
Expand Down Expand Up @@ -108,6 +116,17 @@ func (c *Cache[K, T]) Set(key K, value T) {
c.Unlock()
}

// SetIfAbsent sets the given key to the given value if the key does not already exist in the cache.
func (c *Cache[K, T]) SetIfAbsent(key K, value T) {
c.RLock()
if _, found := c.get(key); !found {
c.RUnlock()
c.Set(key, value)
} else {
c.RUnlock()
}
}

func (c *Cache[K, T]) set(key K, value T) {
c.m[key] = value
}
Expand Down
12 changes: 11 additions & 1 deletion common/maps/ordered.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@
package maps

import (
"github.com/gohugoio/hugo/common/hashing"
"slices"

"github.com/gohugoio/hugo/common/hashing"
)

// Ordered is a map that can be iterated in the order of insertion.
Expand Down Expand Up @@ -57,6 +58,15 @@ func (m *Ordered[K, T]) Get(key K) (T, bool) {
return value, found
}

// Has returns whether the given key exists in the map.
func (m *Ordered[K, T]) Has(key K) bool {
if m == nil {
return false
}
_, found := m.values[key]
return found
}

// Delete deletes the value for the given key.
func (m *Ordered[K, T]) Delete(key K) {
if m == nil {
Expand Down
Loading