hugo/resources/page/site.go
Bjørn Erik Pedersen 4ef9baf5bd Only invoke a given cached partial once
Note that this is backed by a LRU cache (which we soon shall see more usage of), so if you're a heavy user of cached partials it may be evicted and
refreshed if needed. But in most cases every partial is only invoked once.

This commit also adds a timeout (the global `timeout` config option) to make infinite recursion in partials
easier to reason about.

```
name              old time/op    new time/op    delta
IncludeCached-10    8.92ms ± 0%    8.48ms ± 1%   -4.87%  (p=0.016 n=4+5)

name              old alloc/op   new alloc/op   delta
IncludeCached-10    6.65MB ± 0%    5.17MB ± 0%  -22.32%  (p=0.002 n=6+6)

name              old allocs/op  new allocs/op  delta
IncludeCached-10      117k ± 0%       71k ± 0%  -39.44%  (p=0.002 n=6+6)
```

Closes #4086
Updates #9588
2023-01-25 17:35:23 +01:00

175 lines
3.5 KiB
Go

// Copyright 2019 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 page
import (
"html/template"
"time"
"github.com/gohugoio/hugo/common/maps"
"github.com/gohugoio/hugo/identity"
"github.com/gohugoio/hugo/config"
"github.com/gohugoio/hugo/common/hugo"
"github.com/gohugoio/hugo/langs"
"github.com/gohugoio/hugo/navigation"
)
// Site represents a site. There can be multople sites in a multilingual setup.
type Site interface {
// Returns the Language configured for this Site.
Language() *langs.Language
// Returns all the regular Pages in this Site.
RegularPages() Pages
// Returns all Pages in this Site.
Pages() Pages
// A shortcut to the home page.
Home() Page
// Returns true if we're running in a server.
IsServer() bool
// Returns the server port.
ServerPort() int
// Returns the configured title for this Site.
Title() string
// Returns all Sites for all languages.
Sites() Sites
// Returns Site currently rendering.
Current() Site
// Returns a struct with some information about the build.
Hugo() hugo.Info
// Returns the BaseURL for this Site.
BaseURL() template.URL
// Retuns a taxonomy map.
Taxonomies() TaxonomyList
// Returns the last modification date of the content.
LastChange() time.Time
// Returns the Menus for this site.
Menus() navigation.Menus
// Returns the Params configured for this site.
Params() maps.Params
// Returns a map of all the data inside /data.
Data() map[string]any
// Returns the identity of this site.
GetIdentity() identity.Identity
}
// Sites represents an ordered list of sites (languages).
type Sites []Site
// First is a convenience method to get the first Site, i.e. the main language.
func (s Sites) First() Site {
if len(s) == 0 {
return nil
}
return s[0]
}
type testSite struct {
h hugo.Info
l *langs.Language
}
func (t testSite) Hugo() hugo.Info {
return t.h
}
func (t testSite) ServerPort() int {
return 1313
}
func (testSite) LastChange() (t time.Time) {
return
}
func (t testSite) Title() string {
return "foo"
}
func (t testSite) Sites() Sites {
return nil
}
func (t testSite) Current() Site {
return t
}
func (t testSite) GetIdentity() identity.Identity {
return identity.KeyValueIdentity{Key: "site", Value: t.l.Lang}
}
func (t testSite) IsServer() bool {
return false
}
func (t testSite) Language() *langs.Language {
return t.l
}
func (t testSite) Home() Page {
return nil
}
func (t testSite) Pages() Pages {
return nil
}
func (t testSite) RegularPages() Pages {
return nil
}
func (t testSite) Menus() navigation.Menus {
return nil
}
func (t testSite) Taxonomies() TaxonomyList {
return nil
}
func (t testSite) BaseURL() template.URL {
return ""
}
func (t testSite) Params() maps.Params {
return nil
}
func (t testSite) Data() map[string]any {
return nil
}
// NewDummyHugoSite creates a new minimal test site.
func NewDummyHugoSite(cfg config.Provider) Site {
return testSite{
h: hugo.NewInfo(hugo.EnvironmentProduction, nil),
l: langs.NewLanguage("en", cfg),
}
}