diff options
193 files changed, 2134 insertions, 2592 deletions
diff --git a/config/allconfig/allconfig.go b/config/allconfig/allconfig.go index 0db0be1d8..3366defd7 100644 --- a/config/allconfig/allconfig.go +++ b/config/allconfig/allconfig.go @@ -20,6 +20,7 @@ import ( "fmt" "reflect" "regexp" + "slices" "sort" "strconv" "strings" @@ -32,7 +33,6 @@ import ( "github.com/gohugoio/hugo/common/loggers" "github.com/gohugoio/hugo/common/maps" "github.com/gohugoio/hugo/common/paths" - "github.com/gohugoio/hugo/common/types" "github.com/gohugoio/hugo/common/urls" "github.com/gohugoio/hugo/config" "github.com/gohugoio/hugo/config/privacy" @@ -42,6 +42,7 @@ import ( "github.com/gohugoio/hugo/helpers" "github.com/gohugoio/hugo/hugolib/segments" "github.com/gohugoio/hugo/langs" + gc "github.com/gohugoio/hugo/markup/goldmark/goldmark_config" "github.com/gohugoio/hugo/markup/markup_config" "github.com/gohugoio/hugo/media" "github.com/gohugoio/hugo/minifiers" @@ -399,7 +400,6 @@ func (c *Config) CompileConfig(logger loggers.Logger) error { hugo.DeprecateWithLogger("site config key paginate", "Use pagination.pagerSize instead.", "v0.128.0", logger.Logger()) c.Pagination.PagerSize = c.Paginate } - if c.PaginatePath != "" { hugo.DeprecateWithLogger("site config key paginatePath", "Use pagination.path instead.", "v0.128.0", logger.Logger()) c.Pagination.Path = c.PaginatePath @@ -410,12 +410,10 @@ func (c *Config) CompileConfig(logger loggers.Logger) error { hugo.DeprecateWithLogger("site config key privacy.twitter.disable", "Use privacy.x.disable instead.", "v0.141.0", logger.Logger()) c.Privacy.X.Disable = c.Privacy.Twitter.Disable } - if c.Privacy.Twitter.EnableDNT { hugo.DeprecateWithLogger("site config key privacy.twitter.enableDNT", "Use privacy.x.enableDNT instead.", "v0.141.0", logger.Logger()) c.Privacy.X.EnableDNT = c.Privacy.Twitter.EnableDNT } - if c.Privacy.Twitter.Simple { hugo.DeprecateWithLogger("site config key privacy.twitter.simple", "Use privacy.x.simple instead.", "v0.141.0", logger.Logger()) c.Privacy.X.Simple = c.Privacy.Twitter.Simple @@ -436,6 +434,45 @@ func (c *Config) CompileConfig(logger loggers.Logger) error { hugo.DeprecateWithLogger("the \":slugorfilename\" permalink token", "Use \":slugorcontentbasename\" instead.", "0.144.0", logger.Logger()) } + // Legacy render hook values. + alternativeDetails := fmt.Sprintf( + "Set to %q if previous value was false, or set to %q if previous value was true.", + gc.RenderHookUseEmbeddedNever, + gc.RenderHookUseEmbeddedFallback, + ) + if c.Markup.Goldmark.RenderHooks.Image.EnableDefault != nil { + alternative := "Use markup.goldmark.renderHooks.image.useEmbedded instead." + " " + alternativeDetails + hugo.DeprecateWithLogger("site config key markup.goldmark.renderHooks.image.enableDefault", alternative, "0.148.0", logger.Logger()) + if *c.Markup.Goldmark.RenderHooks.Image.EnableDefault { + c.Markup.Goldmark.RenderHooks.Image.UseEmbedded = gc.RenderHookUseEmbeddedFallback + } else { + c.Markup.Goldmark.RenderHooks.Image.UseEmbedded = gc.RenderHookUseEmbeddedNever + } + } + if c.Markup.Goldmark.RenderHooks.Link.EnableDefault != nil { + alternative := "Use markup.goldmark.renderHooks.link.useEmbedded instead." + " " + alternativeDetails + hugo.DeprecateWithLogger("site config key markup.goldmark.renderHooks.link.enableDefault", alternative, "0.148.0", logger.Logger()) + if *c.Markup.Goldmark.RenderHooks.Link.EnableDefault { + c.Markup.Goldmark.RenderHooks.Link.UseEmbedded = gc.RenderHookUseEmbeddedFallback + } else { + c.Markup.Goldmark.RenderHooks.Link.UseEmbedded = gc.RenderHookUseEmbeddedNever + } + } + + // Validate render hook configuration. + renderHookUseEmbeddedModes := []string{ + gc.RenderHookUseEmbeddedAlways, + gc.RenderHookUseEmbeddedAuto, + gc.RenderHookUseEmbeddedFallback, + gc.RenderHookUseEmbeddedNever, + } + if !slices.Contains(renderHookUseEmbeddedModes, c.Markup.Goldmark.RenderHooks.Image.UseEmbedded) { + return fmt.Errorf("site config markup.goldmark.renderHooks.image must be one of %s", helpers.StringSliceToList(renderHookUseEmbeddedModes, "or")) + } + if !slices.Contains(renderHookUseEmbeddedModes, c.Markup.Goldmark.RenderHooks.Link.UseEmbedded) { + return fmt.Errorf("site config markup.goldmark.renderHooks.link must be one of %s", helpers.StringSliceToList(renderHookUseEmbeddedModes, "or")) + } + c.C = &ConfigCompiled{ Timeout: timeout, BaseURL: baseURL, @@ -1082,13 +1119,11 @@ func fromLoadConfigResult(fs afero.Fs, logger loggers.Logger, res config.LoadCon // Adjust Goldmark config defaults for multilingual, single-host sites. if len(languagesConfig) > 1 && !isMultihost && !clone.Markup.Goldmark.DuplicateResourceFiles { - if !clone.Markup.Goldmark.DuplicateResourceFiles { - if clone.Markup.Goldmark.RenderHooks.Link.EnableDefault == nil { - clone.Markup.Goldmark.RenderHooks.Link.EnableDefault = types.NewBool(true) - } - if clone.Markup.Goldmark.RenderHooks.Image.EnableDefault == nil { - clone.Markup.Goldmark.RenderHooks.Image.EnableDefault = types.NewBool(true) - } + if clone.Markup.Goldmark.RenderHooks.Image.UseEmbedded == gc.RenderHookUseEmbeddedAuto { + clone.Markup.Goldmark.RenderHooks.Image.UseEmbedded = gc.RenderHookUseEmbeddedFallback + } + if clone.Markup.Goldmark.RenderHooks.Link.UseEmbedded == gc.RenderHookUseEmbeddedAuto { + clone.Markup.Goldmark.RenderHooks.Link.UseEmbedded = gc.RenderHookUseEmbeddedFallback } } diff --git a/config/allconfig/allconfig_integration_test.go b/config/allconfig/allconfig_integration_test.go index 8f6cacf84..79d2299de 100644 --- a/config/allconfig/allconfig_integration_test.go +++ b/config/allconfig/allconfig_integration_test.go @@ -2,12 +2,14 @@ package allconfig_test import ( "path/filepath" + "strings" "testing" qt "github.com/frankban/quicktest" "github.com/gohugoio/hugo/common/hugo" "github.com/gohugoio/hugo/config/allconfig" "github.com/gohugoio/hugo/hugolib" + gc "github.com/gohugoio/hugo/markup/goldmark/goldmark_config" "github.com/gohugoio/hugo/media" ) @@ -379,3 +381,28 @@ weight = 3 b.Assert(len(b.H.Sites), qt.Equals, 1) } + +// Issue 13535 +// We changed enablement of the embedded link and image render hooks from +// booleans to enums in v0.148.0. +func TestLegacyEmbeddedRenderHookEnablement(t *testing.T) { + files := ` +-- hugo.toml -- +[markup.goldmark.renderHooks.image] +#KEY_VALUE + +[markup.goldmark.renderHooks.link] +#KEY_VALUE +` + f := strings.ReplaceAll(files, "#KEY_VALUE", "enableDefault = false") + b := hugolib.Test(t, f) + c := b.H.Configs.Base.Markup.Goldmark.RenderHooks + b.Assert(c.Link.UseEmbedded, qt.Equals, gc.RenderHookUseEmbeddedNever) + b.Assert(c.Image.UseEmbedded, qt.Equals, gc.RenderHookUseEmbeddedNever) + + f = strings.ReplaceAll(files, "#KEY_VALUE", "enableDefault = true") + b = hugolib.Test(t, f) + c = b.H.Configs.Base.Markup.Goldmark.RenderHooks + b.Assert(c.Link.UseEmbedded, qt.Equals, gc.RenderHookUseEmbeddedFallback) + b.Assert(c.Image.UseEmbedded, qt.Equals, gc.RenderHookUseEmbeddedFallback) +} diff --git a/config/configLoader_test.go b/config/configLoader_test.go index 546031334..a2d16fba7 100644 --- a/config/configLoader_test.go +++ b/config/configLoader_test.go @@ -14,6 +14,7 @@ package config import ( + "regexp" "strings" "testing" @@ -32,3 +33,13 @@ func TestIsValidConfigFileName(t *testing.T) { c.Assert(IsValidConfigFilename(""), qt.Equals, false) c.Assert(IsValidConfigFilename("config.toml.swp"), qt.Equals, false) } + +func TestFromTOMLConfigString(t *testing.T) { + c := qt.New(t) + + c.Assert( + func() { FromTOMLConfigString("cfg") }, + qt.PanicMatches, + regexp.MustCompile("_stream.toml:.*"), + ) +} diff --git a/config/defaultConfigProvider_test.go b/config/defaultConfigProvider_test.go index cd6247e60..204861216 100644 --- a/config/defaultConfigProvider_test.go +++ b/config/defaultConfigProvider_test.go @@ -17,6 +17,7 @@ import ( "context" "errors" "fmt" + "slices" "strconv" "strings" "testing" @@ -353,6 +354,90 @@ func TestDefaultConfigProvider(t *testing.T) { c.Assert(r.Wait(), qt.IsNil) }) + + c.Run("GetBool", func(c *qt.C) { + cfg := New() + + var k string + var v bool + + k, v = "foo", true + + cfg.Set(k, v) + c.Assert(cfg.Get(k), qt.Equals, v) + c.Assert(cfg.GetBool(k), qt.Equals, v) + }) + + c.Run("GetParams", func(c *qt.C) { + cfg := New() + k := "foo" + + cfg.Set(k, maps.Params{k: true}) + c.Assert(cfg.GetParams(k), qt.DeepEquals, maps.Params{ + k: true, + }) + + c.Assert(cfg.GetParams("bar"), qt.IsNil) + }) + + c.Run("Keys", func(c *qt.C) { + cfg := New() + k := "foo" + k2 := "bar" + + cfg.Set(k, maps.Params{k: struct{}{}}) + cfg.Set(k2, maps.Params{k2: struct{}{}}) + + c.Assert(len(cfg.Keys()), qt.Equals, 2) + + got := cfg.Keys() + slices.Sort(got) + + want := []string{k, k2} + slices.Sort(want) + + c.Assert(got, qt.DeepEquals, want) + }) + + c.Run("WalkParams", func(c *qt.C) { + cfg := New() + + cfg.Set("x", maps.Params{}) + cfg.Set("y", maps.Params{}) + + var got []string + cfg.WalkParams(func(params ...maps.KeyParams) bool { + got = append(got, params[len(params)-1].Key) + return false + }) + + want := []string{"", "x", "y"} + slices.Sort(got) + slices.Sort(want) + + c.Assert(got, qt.DeepEquals, want) + + cfg = New() + cfg.WalkParams(func(params ...maps.KeyParams) bool { + return true + }) + + got = []string{""} + want = []string{""} + c.Assert(got, qt.DeepEquals, want) + }) + + c.Run("SetDefaults", func(c *qt.C) { + cfg := New() + + cfg.SetDefaults(maps.Params{ + "foo": "bar", + "bar": "baz", + }) + + c.Assert(cfg.Get("foo"), qt.Equals, "bar") + c.Assert(cfg.Get("bar"), qt.Equals, "baz") + }) } func BenchmarkDefaultConfigProvider(b *testing.B) { diff --git a/docs/.cspell.json b/docs/.cspell.json index bf61489da..16f9bd9f2 100644 --- a/docs/.cspell.json +++ b/docs/.cspell.json @@ -70,6 +70,7 @@ "# cspell: ignore hugo terminology", "# ----------------------------------------------------------------------", "alignx", + "aligny", "attrlink", "canonify", "codeowners", diff --git a/docs/.prettierignore b/docs/.prettierignore index f24bbcef0..56e7b90fb 100644 --- a/docs/.prettierignore +++ b/docs/.prettierignore @@ -2,16 +2,16 @@ **/icons.html # These are whitespace sensitive. -layouts/_default/_markup/render-code* -layouts/_default/_markup/render-table* -layouts/shortcodes/glossary-term.html -layouts/shortcodes/glossary.html -layouts/shortcodes/highlighting-styles.html -layouts/shortcodes/list-pages-in-section.html -layouts/shortcodes/quick-reference.html +layouts/_markup/render-code* +layouts/_markup/render-table* +layouts/_shortcodes/glossary-term.html +layouts/_shortcodes/glossary.html +layouts/_shortcodes/highlighting-styles.html +layouts/_shortcodes/list-pages-in-section.html +layouts/_shortcodes/quick-reference.html # No root node. -layouts/partials/layouts/head/head.html +layouts/_partials/layouts/head/head.html # Auto generated. assets/css/components/chroma*.css diff --git a/docs/assets/images/sponsors/logo-pinme.svg b/docs/assets/images/sponsors/logo-pinme.svg new file mode 100644 index 000000000..fc807beda --- /dev/null +++ b/docs/assets/images/sponsors/logo-pinme.svg @@ -0,0 +1,100 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Generator: Adobe Illustrator 24.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> +<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" + viewBox="0 0 299 118" height="100%" width="100%" style="enable-background:new 0 0 299 118;" xml:space="preserve"> +<style type="text/css"> + .st0{clip-path:url(#SVGID_2_);} + .st1{fill:#414141;} + .st2{fill:#3D4DF4;} +</style> +<g> + <defs> + <rect id="SVGID_1_" x="0.4" y="0" width="66.5" height="67.8"/> + </defs> + <clipPath id="SVGID_2_"> + <use xlink:href="#SVGID_1_" style="overflow:visible;"/> + </clipPath> + <g class="st0"> + <path class="st1" d="M34.2,28l31.4,18.3c0.9,0.5,1.1,1.6,0.6,2.4c-0.2,0.3-0.4,0.5-0.6,0.6L35.6,66.9c-1.4,0.8-3.1,0.8-4.5,0 + L1.3,49.6c-0.9-0.5-1.1-1.6-0.6-2.4c0.2-0.3,0.4-0.5,0.6-0.6l23-13.4l7.9,13.6c0.5,0.8,1.5,1.1,2.4,0.7l0.1,0l0.1,0 + c0.6-0.4,0.9-1.2,0.7-2l-5-15.7l2.5-1.5C33.3,27.8,33.8,27.8,34.2,28z M36,58.6c-1.4-0.8-3.9-0.7-5.5,0.3l-3,1.7l7,4.1l2-1.2 + l-2-1.1l1-0.6C37.1,60.9,37.3,59.4,36,58.6z M32.1,59.9c0.6-0.3,1.4-0.4,1.8-0.1c0.5,0.3,0.4,0.7-0.2,1.1l-1,0.6l-1.7-1L32.1,59.9 + z M36.2,55.6l-2,1.2l7,4.1l2-1.2L36.2,55.6z M42.6,51.9l-2,1.2l2.9,1.7l-4.5-0.8L37,55.1l7,4.1l2-1.2L43,56.3l4.5,0.8l2.1-1.2 + L42.6,51.9z M56.3,43.8l-6,3.5l2.5,1.4l-3.7-0.7L47,49.3l2.9,1.7l-4.5-0.8l-2.1,1.2l7,4.1l2-1.2l-2.9-1.7l4.5,0.8l2.1-1.2 + l-2.9-1.7l4,0.7l0.2,0.1l2-1.2l4-2.3l-1.7-1l-4,2.3l-1-0.6l4-2.3l-1.7-1l-4,2.3L54,47.1l4-2.3L56.3,43.8z"/> + <path class="st2" d="M41.7,0c0.1,0,0.2,0,0.3,0c1,0.2,1.6,1.1,1.5,2.1l-2.3,13.5c3.9,2.5,6.5,6.9,6.5,11.9v0.7l-10.3,0l-2,17.9 + c-0.1,0.8-0.7,1.4-1.5,1.5l-0.1,0c-1,0.1-1.9-0.6-2-1.5l-2-17.9H19.6v-0.7c0-5,2.6-9.4,6.5-11.9L23.8,2.1c0-0.1,0-0.2,0-0.3 + c0-1,0.8-1.8,1.8-1.8H41.7z"/> + </g> +</g> +<path class="st1" d="M277.4,61c-3.7,0-7.1-0.8-10-2.4c-2.8-1.6-5.1-3.9-6.7-6.8c-1.6-2.9-2.4-6.4-2.4-10.3v-0.9 + c0-4,0.8-7.4,2.4-10.3c1.6-2.9,3.8-5.2,6.6-6.8c2.8-1.6,6.1-2.4,9.9-2.4c3.7,0,6.9,0.8,9.7,2.5c2.7,1.6,4.9,3.9,6.4,6.8 + c1.5,2.9,2.3,6.3,2.3,10.1v3.3h-27.4c0.1,2.6,1.1,4.7,2.9,6.3c1.8,1.6,4.1,2.4,6.7,2.4c2.7,0,4.7-0.6,5.9-1.7 + c1.3-1.2,2.2-2.5,2.9-3.9l7.8,4.1c-0.7,1.3-1.7,2.8-3.1,4.3c-1.3,1.5-3.1,2.8-5.3,4C283.6,60.5,280.8,61,277.4,61z M268.2,36.8h17.6 + c-0.2-2.2-1.1-3.9-2.7-5.2c-1.5-1.3-3.5-2-6-2c-2.6,0-4.6,0.7-6.2,2C269.5,32.9,268.5,34.6,268.2,36.8z"/> +<path class="st1" d="M192.9,60V6.8h18.6l9.2,46.4h1.4l9.2-46.4h18.6V60h-9.7V14.1h-1.4L229.6,60h-16.6L204,14.1h-1.4V60H192.9z"/> +<path class="st1" d="M146.3,60V22.3h9.4v4.9h1.4c0.6-1.3,1.7-2.6,3.4-3.7c1.7-1.2,4.2-1.8,7.6-1.8c2.9,0,5.5,0.7,7.7,2.1 + c2.2,1.3,4,3.2,5.2,5.5c1.2,2.3,1.8,5.1,1.8,8.2V60h-9.6V38.2c0-2.8-0.7-5-2.1-6.4c-1.4-1.4-3.3-2.1-5.9-2.1c-2.9,0-5.2,1-6.8,3 + c-1.6,1.9-2.4,4.6-2.4,8.1V60H146.3z"/> +<path class="st1" d="M126.1,60V22.3h9.6V60H126.1z M130.9,17.9c-1.7,0-3.2-0.6-4.4-1.7c-1.2-1.1-1.7-2.6-1.7-4.4 + c0-1.8,0.6-3.3,1.7-4.4c1.2-1.1,2.7-1.7,4.4-1.7c1.8,0,3.2,0.6,4.4,1.7c1.2,1.1,1.7,2.6,1.7,4.4c0,1.8-0.6,3.3-1.7,4.4 + C134.2,17.3,132.7,17.9,130.9,17.9z"/> +<path class="st1" d="M79.9,60V6.8h21.9c3.3,0,6.3,0.7,8.8,2.1c2.6,1.3,4.6,3.2,6,5.6c1.5,2.4,2.2,5.3,2.2,8.7v1.1 + c0,3.3-0.8,6.2-2.3,8.7c-1.5,2.4-3.5,4.3-6.1,5.7c-2.5,1.3-5.4,2-8.7,2H89.9V60H79.9z M89.9,31.4h10.9c2.4,0,4.3-0.7,5.8-2 + c1.5-1.3,2.2-3.1,2.2-5.4v-0.8c0-2.3-0.7-4.1-2.2-5.4c-1.5-1.3-3.4-2-5.8-2H89.9V31.4z"/> +<path class="st2" d="M285.3,112V91h13.5v3.6h-9.5v5h8.7v3.6h-8.7v5.2h9.7v3.6H285.3z"/> +<path class="st2" d="M268.7,112V91h13.5v3.6h-9.5v5h8.7v3.6h-8.7v5.2h9.7v3.6H268.7z"/> +<path class="st2" d="M249.7,112V91h9.1c1.3,0,2.5,0.2,3.4,0.7c1,0.5,1.7,1.1,2.3,1.9c0.5,0.8,0.8,1.8,0.8,3v0.4 + c0,1.3-0.3,2.3-0.9,3.1c-0.6,0.8-1.3,1.4-2.2,1.7v0.5c0.8,0,1.4,0.3,1.9,0.8c0.4,0.5,0.7,1.2,0.7,2v6.9h-4v-6.3 + c0-0.5-0.1-0.9-0.4-1.2c-0.2-0.3-0.6-0.4-1.2-0.4h-5.5v7.9H249.7z M253.7,100.4h4.7c0.9,0,1.7-0.2,2.2-0.8c0.5-0.5,0.8-1.2,0.8-2 + v-0.3c0-0.8-0.3-1.5-0.8-2c-0.5-0.5-1.3-0.8-2.2-0.8h-4.7V100.4z"/> +<path class="st2" d="M233.7,112V91h13.2v3.6h-9.2v5.1h8.5v3.6h-8.5v8.7H233.7z"/> +<path class="st1" d="M214.3,112V97.1h3.7v1.7h0.5c0.2-0.6,0.6-1,1.1-1.3c0.5-0.3,1.1-0.4,1.8-0.4h1.8v3.4h-1.9c-1,0-1.8,0.3-2.4,0.8 + c-0.6,0.5-0.9,1.3-0.9,2.3v8.5H214.3z"/> +<path class="st1" d="M203,112.4c-1.5,0-2.8-0.3-4-0.9c-1.2-0.6-2.1-1.5-2.8-2.6c-0.7-1.1-1-2.5-1-4.1v-0.5c0-1.6,0.3-3,1-4.1 + c0.7-1.1,1.6-2,2.8-2.6c1.2-0.6,2.5-0.9,4-0.9c1.5,0,2.8,0.3,4,0.9c1.2,0.6,2.1,1.5,2.8,2.6c0.7,1.1,1,2.5,1,4.1v0.5 + c0,1.6-0.3,3-1,4.1c-0.7,1.1-1.6,2-2.8,2.6C205.8,112.1,204.5,112.4,203,112.4z M203,109c1.2,0,2.1-0.4,2.9-1.1 + c0.8-0.8,1.1-1.8,1.1-3.2v-0.3c0-1.4-0.4-2.5-1.1-3.2c-0.7-0.8-1.7-1.1-2.9-1.1c-1.2,0-2.1,0.4-2.9,1.1c-0.8,0.7-1.1,1.8-1.1,3.2 + v0.3c0,1.4,0.4,2.5,1.1,3.2C200.9,108.7,201.8,109,203,109z"/> +<path class="st1" d="M185.8,112v-11.8H182v-3.1h3.8v-2.8c0-1,0.3-1.8,0.9-2.4c0.6-0.6,1.4-0.9,2.4-0.9h3.9v3.1h-2.6 + c-0.6,0-0.8,0.3-0.8,0.9v2.1h3.9v3.1h-3.9V112H185.8z"/> +<path class="st1" d="M155.9,104.6v-0.5c0-1.6,0.3-2.9,0.9-4c0.6-1.1,1.4-2,2.5-2.5c1-0.6,2.2-0.9,3.4-0.9c1.4,0,2.4,0.2,3.1,0.7 + c0.7,0.5,1.2,1,1.5,1.5h0.5v-1.8h3.7v17.5c0,1-0.3,1.8-0.9,2.4c-0.6,0.6-1.4,0.9-2.4,0.9h-10v-3.3h8.6c0.6,0,0.8-0.3,0.8-0.9v-3.9 + h-0.5c-0.2,0.3-0.5,0.7-0.8,1c-0.4,0.3-0.8,0.6-1.4,0.8c-0.6,0.2-1.4,0.3-2.3,0.3c-1.2,0-2.3-0.3-3.4-0.9c-1-0.6-1.8-1.4-2.5-2.6 + C156.2,107.5,155.9,106.1,155.9,104.6z M163.7,108.7c1.2,0,2.1-0.4,2.9-1.1s1.2-1.8,1.2-3.1v-0.3c0-1.4-0.4-2.4-1.2-3.1 + c-0.8-0.7-1.7-1.1-2.9-1.1c-1.2,0-2.1,0.4-2.9,1.1c-0.8,0.7-1.2,1.8-1.2,3.1v0.3c0,1.3,0.4,2.4,1.2,3.1S162.6,108.7,163.7,108.7z"/> +<path class="st1" d="M145.3,112.4c-1.5,0-2.8-0.3-4-0.9c-1.2-0.6-2.1-1.5-2.8-2.6s-1-2.5-1-4.1v-0.5c0-1.6,0.3-3,1-4.1 + c0.7-1.1,1.6-2,2.8-2.6c1.2-0.6,2.5-0.9,4-0.9s2.8,0.3,4,0.9c1.2,0.6,2.1,1.5,2.8,2.6c0.7,1.1,1,2.5,1,4.1v0.5c0,1.6-0.3,3-1,4.1 + c-0.7,1.1-1.6,2-2.8,2.6C148.1,112.1,146.8,112.4,145.3,112.4z M145.3,109c1.2,0,2.1-0.4,2.9-1.1c0.8-0.8,1.1-1.8,1.1-3.2v-0.3 + c0-1.4-0.4-2.5-1.1-3.2c-0.7-0.8-1.7-1.1-2.9-1.1c-1.2,0-2.1,0.4-2.9,1.1c-0.8,0.7-1.1,1.8-1.1,3.2v0.3c0,1.4,0.4,2.5,1.1,3.2 + C143.2,108.7,144.1,109,145.3,109z"/> +<path class="st1" d="M130.3,112V91h3.8v21H130.3z"/> +<path class="st1" d="M109.6,112v-3.5h2.8v-14h-2.8V91h10.8c1.3,0,2.4,0.2,3.3,0.7c1,0.4,1.7,1,2.2,1.8c0.5,0.8,0.8,1.7,0.8,2.8v0.3 + c0,1-0.2,1.8-0.5,2.4c-0.4,0.6-0.8,1.1-1.3,1.4c-0.5,0.3-0.9,0.6-1.4,0.7v0.5c0.4,0.1,0.9,0.3,1.4,0.7c0.5,0.3,1,0.8,1.3,1.4 + c0.4,0.6,0.6,1.4,0.6,2.4v0.3c0,1.2-0.3,2.2-0.8,3c-0.5,0.8-1.3,1.4-2.2,1.9c-0.9,0.4-2,0.7-3.3,0.7H109.6z M116.3,108.4h3.7 + c0.9,0,1.6-0.2,2.1-0.6c0.5-0.4,0.8-1,0.8-1.8v-0.3c0-0.8-0.3-1.4-0.8-1.8c-0.5-0.4-1.2-0.6-2.1-0.6h-3.7V108.4z M116.3,99.6h3.7 + c0.8,0,1.5-0.2,2-0.6c0.5-0.4,0.8-1,0.8-1.7v-0.3c0-0.8-0.3-1.3-0.8-1.7c-0.5-0.4-1.2-0.6-2-0.6h-3.7V99.6z"/> +<path class="st1" d="M85.9,118v-3.3H94c0.6,0,0.8-0.3,0.8-0.9V110h-0.5c-0.2,0.3-0.4,0.7-0.8,1c-0.3,0.3-0.8,0.6-1.4,0.8 + c-0.6,0.2-1.3,0.3-2.2,0.3c-1.2,0-2.2-0.3-3.1-0.8c-0.9-0.5-1.5-1.3-2-2.2c-0.5-0.9-0.7-2-0.7-3.2v-8.9h3.8v8.6c0,1.1,0.3,2,0.8,2.5 + c0.6,0.6,1.4,0.8,2.4,0.8c1.2,0,2.1-0.4,2.7-1.1c0.6-0.8,1-1.9,1-3.2v-7.6h3.8v17.5c0,1-0.3,1.8-0.9,2.4c-0.6,0.6-1.4,0.9-2.4,0.9 + H85.9z"/> +<path class="st1" d="M72.9,112.4c-1.5,0-2.8-0.3-4-0.9s-2.1-1.5-2.8-2.6s-1-2.5-1-4.1v-0.5c0-1.6,0.3-3,1-4.1c0.7-1.1,1.6-2,2.8-2.6 + s2.5-0.9,4-0.9c1.5,0,2.8,0.3,4,0.9s2.1,1.5,2.8,2.6c0.7,1.1,1,2.5,1,4.1v0.5c0,1.6-0.3,3-1,4.1s-1.6,2-2.8,2.6 + S74.4,112.4,72.9,112.4z M72.9,109c1.2,0,2.1-0.4,2.9-1.1c0.8-0.8,1.1-1.8,1.1-3.2v-0.3c0-1.4-0.4-2.5-1.1-3.2 + c-0.7-0.8-1.7-1.1-2.9-1.1c-1.2,0-2.1,0.4-2.9,1.1c-0.8,0.7-1.1,1.8-1.1,3.2v0.3c0,1.4,0.4,2.5,1.1,3.2 + C70.8,108.7,71.8,109,72.9,109z"/> +<path class="st1" d="M57.9,112V91h3.8v21H57.9z"/> +<path class="st1" d="M38.8,118V97.1h3.7v1.8H43c0.3-0.6,0.9-1.1,1.6-1.5c0.7-0.5,1.8-0.7,3.1-0.7c1.2,0,2.3,0.3,3.3,0.9 + c1,0.6,1.8,1.4,2.5,2.6c0.6,1.1,0.9,2.5,0.9,4.1v0.5c0,1.6-0.3,3-0.9,4.1c-0.6,1.1-1.4,2-2.5,2.6c-1,0.6-2.1,0.9-3.3,0.9 + c-0.9,0-1.7-0.1-2.3-0.3c-0.6-0.2-1.1-0.5-1.5-0.8c-0.4-0.3-0.7-0.7-0.9-1h-0.5v7.7H38.8z M46.6,109.1c1.2,0,2.1-0.4,2.9-1.1 + c0.8-0.8,1.2-1.9,1.2-3.3v-0.3c0-1.4-0.4-2.5-1.2-3.3c-0.8-0.8-1.8-1.1-2.9-1.1s-2.1,0.4-2.9,1.1c-0.8,0.7-1.2,1.8-1.2,3.3v0.3 + c0,1.4,0.4,2.5,1.2,3.3C44.4,108.7,45.4,109.1,46.6,109.1z"/> +<path class="st1" d="M28.2,112.4c-1.5,0-2.8-0.3-3.9-0.9c-1.1-0.6-2-1.5-2.6-2.7c-0.6-1.2-0.9-2.5-0.9-4.1v-0.4 + c0-1.6,0.3-2.9,0.9-4.1c0.6-1.2,1.5-2,2.6-2.7c1.1-0.6,2.4-1,3.9-1c1.5,0,2.7,0.3,3.8,1c1.1,0.6,1.9,1.5,2.5,2.7 + c0.6,1.1,0.9,2.5,0.9,4v1.3H24.6c0,1,0.4,1.8,1.1,2.5c0.7,0.6,1.6,1,2.6,1c1.1,0,1.8-0.2,2.3-0.7s0.9-1,1.1-1.5l3.1,1.6 + c-0.3,0.5-0.7,1.1-1.2,1.7c-0.5,0.6-1.2,1.1-2.1,1.6C30.7,112.2,29.6,112.4,28.2,112.4z M24.6,102.8h7c-0.1-0.9-0.4-1.6-1-2.1 + c-0.6-0.5-1.4-0.8-2.4-0.8c-1,0-1.8,0.3-2.4,0.8C25.1,101.3,24.7,102,24.6,102.8z"/> +<path class="st1" d="M0.8,112v-3.5h2.8v-14H0.8V91h8.6c2.8,0,5,0.7,6.4,2.2c1.5,1.4,2.2,3.5,2.2,6.4v4c0,2.8-0.7,4.9-2.2,6.4 + c-1.5,1.4-3.6,2.1-6.4,2.1H0.8z M7.5,108.4h2c1.6,0,2.8-0.4,3.5-1.3c0.7-0.8,1.1-2,1.1-3.5v-4.2c0-1.5-0.4-2.7-1.1-3.5 + c-0.7-0.8-1.9-1.3-3.5-1.3h-2V108.4z"/> +</svg> diff --git a/docs/content/en/_common/methods/page/next-and-prev.md b/docs/content/en/_common/methods/page/next-and-prev.md index f859961a4..27b069ddc 100644 --- a/docs/content/en/_common/methods/page/next-and-prev.md +++ b/docs/content/en/_common/methods/page/next-and-prev.md @@ -32,13 +32,13 @@ content/ And these templates: -```go-html-template {file="layouts/_default/list.html"} +```go-html-template {file="layouts/section.html"} {{ range .Pages.ByWeight }} <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2> {{ end }} ``` -```go-html-template {file="layouts/_default/single.html"} +```go-html-template {file="layouts/page.html"} {{ with .Prev }} <a href="{{ .RelPermalink }}">Previous</a> {{ end }} diff --git a/docs/content/en/_common/methods/page/nextinsection-and-previnsection.md b/docs/content/en/_common/methods/page/nextinsection-and-previnsection.md index 54d240eb4..005953324 100644 --- a/docs/content/en/_common/methods/page/nextinsection-and-previnsection.md +++ b/docs/content/en/_common/methods/page/nextinsection-and-previnsection.md @@ -32,13 +32,13 @@ content/ And these templates: -```go-html-template {file="layouts/_default/list.html"} +```go-html-template {file="layouts/section.html"} {{ range .Pages.ByWeight }} <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2> {{ end }} ``` -```go-html-template {file="layouts/_default/single.html"} +```go-html-template {file="layouts/page.html"} {{ with .PrevInSection }} <a href="{{ .RelPermalink }}">Previous</a> {{ end }} diff --git a/docs/content/en/_common/methods/pages/next-and-prev.md b/docs/content/en/_common/methods/pages/next-and-prev.md index 462545c3f..5a92a7cb1 100644 --- a/docs/content/en/_common/methods/pages/next-and-prev.md +++ b/docs/content/en/_common/methods/pages/next-and-prev.md @@ -32,13 +32,13 @@ content/ And these templates: -```go-html-template {file="layouts/_default/list.html"} +```go-html-template {file="layouts/section.html"} {{ range .Pages.ByWeight }} <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2> {{ end }} ``` -```go-html-template {file="layouts/_default/single.html"} +```go-html-template {file="layouts/page.html"} {{ $pages := .CurrentSection.Pages.ByWeight }} {{ with $pages.Prev . }} @@ -57,7 +57,7 @@ When you visit page-2: To reverse the meaning of _next_ and _previous_ you can chain the [`Reverse`] method to the page collection definition: -```go-html-template {file="layouts/_default/single.html"} +```go-html-template {file="layouts/page.html"} {{ $pages := .CurrentSection.Pages.ByWeight.Reverse }} {{ with $pages.Prev . }} diff --git a/docs/content/en/_common/methods/taxonomy/get-a-taxonomy-object.md b/docs/content/en/_common/methods/taxonomy/get-a-taxonomy-object.md index 6fb729c17..a6c46b8b7 100644 --- a/docs/content/en/_common/methods/taxonomy/get-a-taxonomy-object.md +++ b/docs/content/en/_common/methods/taxonomy/get-a-taxonomy-object.md @@ -34,7 +34,7 @@ To capture the "genres" `Taxonomy` object from within any template, use the [`Ta To capture the "genres" `Taxonomy` object when rendering its page with a taxonomy template, use the [`Terms`] method on the page's [`Data`] object: -```go-html-template {file="layouts/_default/taxonomy.html"} +```go-html-template {file="layouts/taxonomy.html"} {{ $taxonomyObject := .Data.Terms }} ``` diff --git a/docs/content/en/_common/render-hooks/pageinner.md b/docs/content/en/_common/render-hooks/pageinner.md index a598b880a..e5c0afb79 100644 --- a/docs/content/en/_common/render-hooks/pageinner.md +++ b/docs/content/en/_common/render-hooks/pageinner.md @@ -8,7 +8,7 @@ _comment: Do not remove front matter. The primary use case for `PageInner` is to resolve links and [page resources](g) relative to an included `Page`. For example, create an "include" shortcode to compose a page from multiple content files, while preserving a global context for footnotes and the table of contents: -```go-html-template {file="layouts/shortcodes/include.html" copy=true} +```go-html-template {file="layouts/_shortcodes/include.html" copy=true} {{ with .Get 0 }} {{ with $.Page.GetPage . }} {{- .RenderShortcodes }} diff --git a/docs/content/en/configuration/all.md b/docs/content/en/configuration/all.md index 9bc05057f..c64638499 100644 --- a/docs/content/en/configuration/all.md +++ b/docs/content/en/configuration/all.md @@ -84,7 +84,7 @@ disableKinds : (`[]string`) A slice of page [kinds](g) to disable during the build process, any of `404`, `home`, `page`, `robotstxt`, `rss`, `section`, `sitemap`, `taxonomy`, or `term`. disableLanguages -: (`[]string]`) A slice of language keys representing the languages to disable during the build process. Although this is functional, consider using the [`disabled`] key under each language instead. +: (`[]string`) A slice of language keys representing the languages to disable during the build process. Although this is functional, consider using the [`disabled`] key under each language instead. disableLiveReload : (`bool`) Whether to disable automatic live reloading of the browser window. Default is `false`. @@ -123,7 +123,7 @@ ignoreCache : (`bool`) Whether to ignore the cache directory. Default is `false`. ignoreFiles -: (`[]string]`) A slice of [regular expressions](g) used to exclude specific files from a build. These expressions are matched against the absolute file path and apply to files within the `content`, `data`, and `i18n` directories. For more advanced file exclusion options, see the section on [module mounts]. +: (`[]string`) A slice of [regular expressions](g) used to exclude specific files from a build. These expressions are matched against the absolute file path and apply to files within the `content`, `data`, and `i18n` directories. For more advanced file exclusion options, see the section on [module mounts]. ignoreLogs : (`[]string`) A slice of message identifiers corresponding to warnings and errors you wish to suppress. See [`erroridf`] and [`warnidf`]. @@ -280,7 +280,7 @@ themesDir : (`string`) The designated directory for themes. Default is `themes`. timeout -: (`string`) The timeout for generating page content, either as a [duration] or in seconds. This timeout is used to prevent infinite recursion during content generation. You may need to increase this value if your pages take a long time to generate, for example, due to extensive image processing or reliance on remote content. Default is `30s`. +: (`string`) The timeout for generating page content, either as a [duration] or in seconds. This timeout is used to prevent infinite recursion during content generation. You may need to increase this value if your pages take a long time to generate, for example, due to extensive image processing or reliance on remote content. Default is `60s`. timeZone : (`string`) The time zone used to parse dates without time zone offsets, including front matter date fields and values passed to the [`time.AsTime`] and [`time.Format`] template functions. The list of valid values may be system dependent, but should include `UTC`, `Local`, and any location in the [IANA Time Zone Database]. For example, `America/Los_Angeles` and `Europe/Oslo` are valid time zones. diff --git a/docs/content/en/configuration/introduction.md b/docs/content/en/configuration/introduction.md index 8f8ad4c1e..77fce4e8a 100644 --- a/docs/content/en/configuration/introduction.md +++ b/docs/content/en/configuration/introduction.md @@ -79,6 +79,11 @@ my-project/ The root configuration keys are {{< root-configuration-keys >}}. +> [!note] +> You must define `cascade` tables in the root configuration file. You cannot define `cascade` tables in a dedicated file. See issue [#12899] for details. + +[#12899]: https://github.com/gohugoio/hugo/issues/12899 + ### Omit the root key When splitting the configuration by root key, omit the root key in the component file. For example, these are equivalent: diff --git a/docs/content/en/configuration/markup.md b/docs/content/en/configuration/markup.md index b6135cee5..4a2efb5e8 100644 --- a/docs/content/en/configuration/markup.md +++ b/docs/content/en/configuration/markup.md @@ -247,7 +247,7 @@ rougify style monokai.sublime > assets/css/syntax.css In your base template add a link to the CSS file: -```go-html-template {file="layouts/_default/baseof.html"} +```go-html-template {file="layouts/baseof.html"} <head> ... {{ with resources.Get "css/syntax.css" }} @@ -337,5 +337,5 @@ ordered [superscript]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/sup [AsciiDoc]: https://asciidoc.org/ [Emacs Org Mode]: https://orgmode.org/ -[Pandoc]: https://www.pandoc.org/ +[Pandoc]: https://pandoc.org/ [reStructuredText]: https://docutils.sourceforge.io/rst.html diff --git a/docs/content/en/configuration/output-formats.md b/docs/content/en/configuration/output-formats.md index 2627c6df4..f3dbceec5 100644 --- a/docs/content/en/configuration/output-formats.md +++ b/docs/content/en/configuration/output-formats.md @@ -135,7 +135,7 @@ See [configure outputs] for more information. Create a template to render the output format. Since Atom feeds are lists, you need to create a list template. Consult the [template lookup order] to find the correct template path: ```text -layouts/_default/list.atom.atom +layouts/list.atom.atom ``` We leave writing the template code as an exercise for you. Aim for a result similar to the [embedded RSS template]. @@ -154,7 +154,7 @@ To access output formats, each `Page` object provides two methods: [`OutputForma By default, a `Page` object's [`Permalink`] and [`RelPermalink`] methods return the URL of the [primary output format](g), typically `html`. This behavior remains consistent regardless of the template used. -For example, in `single.json.json`, you'll see: +For example, in `page.json.json`, you'll see: ```go-html-template {{ .RelPermalink }} → /that-page/ @@ -165,7 +165,7 @@ For example, in `single.json.json`, you'll see: To make these methods return the URL of the _current_ template's output format, you must set the [`permalinkable`] setting to `true` for that format. -With `permalinkable` set to true for `json` in the same `single.json.json` template: +With `permalinkable` set to true for `json` in the same `page.json.json` template: ```go-html-template {{ .RelPermalink }} → /that-page/index.json @@ -188,9 +188,9 @@ For example, for section pages: Output format|Template path :--|:-- -`html`|`layouts/_default/section.html.html` -`json`|`layouts/_default/section.json.json` -`rss`|`layouts/_default/section.rss.xml` +`html`|`layouts/section.html.html` +`json`|`layouts/section.json.json` +`rss`|`layouts/section.rss.xml` [`AlternativeOutputFormats`]: /methods/page/alternativeoutputformats/ [`OutputFormats`]: /methods/page/outputformats/ diff --git a/docs/content/en/configuration/related-content.md b/docs/content/en/configuration/related-content.md index c6e182fae..7f2aa9831 100644 --- a/docs/content/en/configuration/related-content.md +++ b/docs/content/en/configuration/related-content.md @@ -97,7 +97,7 @@ We've configured the `authors` index with a weight of `2` and the `genres` index Then render a list of 5 related reviews with a partial template like this: -```go-html-template {file="layouts/partials/related.html" copy=true} +```go-html-template {file="layouts/_partials/related.html" copy=true} {{ with site.RegularPages.Related . | first 5 }} <p>Related content:</p> <ul> diff --git a/docs/content/en/configuration/taxonomies.md b/docs/content/en/configuration/taxonomies.md index 4b5ba97a5..3cf6497bc 100644 --- a/docs/content/en/configuration/taxonomies.md +++ b/docs/content/en/configuration/taxonomies.md @@ -58,7 +58,7 @@ taxonomies: To disable the taxonomy system, use the [`disableKinds`] setting in the root of your site configuration to disable the `taxonomy` and `term` page [kinds](g). {{< code-toggle file=hugo >}} -disableKinds = ['categories','tags'] +disableKinds = ['taxonomy','term'] {{< /code-toggle >}} [`disableKinds`]: /configuration/all/#disablekinds diff --git a/docs/content/en/content-management/build-options.md b/docs/content/en/content-management/build-options.md index 8c29a19b9..0e4d4020b 100644 --- a/docs/content/en/content-management/build-options.md +++ b/docs/content/en/content-management/build-options.md @@ -69,7 +69,7 @@ title = 'Headless page' To include the content and images on the home page: -```go-html-template {file="layouts/_default/home.html"} +```go-html-template {file="layouts/home.html"} {{ with .Site.GetPage "/headless" }} {{ .Content }} {{ range .Resources.ByType "image" }} @@ -127,7 +127,7 @@ In the front matter above, note that we have set `list` to `local` to include th To include the content and images on the home page: -```go-html-template {file="layouts/_default/home.html"} +```go-html-template {file="layouts/home.html"} {{ with .Site.GetPage "/headless" }} {{ range .Pages }} {{ .Content }} @@ -186,7 +186,7 @@ render = 'always' To render the glossary: -```go-html-template {file="layouts/glossary/list.html"} +```go-html-template {file="layouts/glossary/section.html"} <dl> {{ range .Pages }} <dt>{{ .Title }}</dt> diff --git a/docs/content/en/content-management/comments.md b/docs/content/en/content-management/comments.md index fee4fb372..f0e4a9ae1 100644 --- a/docs/content/en/content-management/comments.md +++ b/docs/content/en/content-management/comments.md @@ -34,7 +34,7 @@ For many websites, this is enough configuration. However, you also have the opti Disqus has its own [internal template](/templates/embedded/#disqus) available, to render it add the following code where you want comments to appear: ```go-html-template -{{ template "_internal/disqus.html" . }} +{{ partial "disqus.html" . }} ``` ## Alternatives diff --git a/docs/content/en/content-management/content-adapters.md b/docs/content/en/content-management/content-adapters.md index 3468bb728..e22962531 100644 --- a/docs/content/en/content-management/content-adapters.md +++ b/docs/content/en/content-management/content-adapters.md @@ -27,7 +27,7 @@ content/ └── _index.md ``` -Each content adapter is named _content.gotmpl and uses the same [syntax] as templates in the `layouts` directory. You can use any of the [template functions] within a content adapter, as well as the methods described below. +Each content adapter is named `_content.gotmpl` and uses the same [syntax] as templates in the `layouts` directory. You can use any of the [template functions] within a content adapter, as well as the methods described below. ## Methods @@ -71,7 +71,7 @@ Adds a page resource to the site. Then retrieve the new page resource with something like: -```go-html-template {file="layouts/_default/single.html"} +```go-html-template {file="layouts/page.html"} {{ with .Resources.Get "cover.jpg" }} <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt=""> {{ end }} @@ -90,7 +90,7 @@ Returns the `Site` to which the pages will be added. ### Store -Returns a persistent “scratch pad” to store and manipulate data. The main use case for this is to transfer values between executions when [EnableAllLanguages](#enablealllanguages) is set. See [examples](/methods/page/store/). +Returns a persistent "scratch pad" to store and manipulate data. The main use case for this is to transfer values between executions when [EnableAllLanguages](#enablealllanguages) is set. See [examples](/methods/page/store/). ```go-html-template {file="content/books/_content.gotmpl"} {{ .Store.Set "key" "value" }} @@ -99,7 +99,7 @@ Returns a persistent “scratch pad” to store and manipulate data. The main us ### EnableAllLanguages -By default, Hugo executes the content adapter for the language defined by the _content.gotmpl file. Use this method to activate the content adapter for all languages. +By default, Hugo executes the content adapter for the language defined by the `_content.gotmpl` file. Use this method to activate the content adapter for all languages. ```go-html-template {file="content/books/_content.gotmpl"} {{ .EnableAllLanguages }} @@ -153,7 +153,7 @@ Key|Description|Required `title`|The resource title.| > [!note] -> If the `content.value` is a string Hugo creates a new resource. If the `content.value` is a resource, Hugo obtains the value from the existing resource. +> When `content.value` is a string, Hugo generates a new resource with a publication path relative to the page. However, if `content.value` is already a resource, Hugo directly uses its value and publishes it relative to the site root. This latter method is more efficient. > > When setting the `path`, Hugo transforms the given string to a logical path. For example, setting `path` to `A B C/cover.jpg` produces a logical path of `/section/a-b-c/cover.jpg`. @@ -237,9 +237,9 @@ Create the content adapter. ### Step 4 -Create a single template to render each book review. +Create a page template to render each book review. -```go-html-template {file="layouts/books/single.html" copy=true} +```go-html-template {file="layouts/books/page.html" copy=true} {{ define "main" }} <h1>{{ .Title }}</h1> @@ -338,7 +338,7 @@ content/ └── the-hunchback-of-notre-dame.md ``` -If the content adapter also creates books/the-hunchback-of-notre-dame, the content of the published page is indeterminate. You can not define the processing order. +If the content adapter also creates `books/the-hunchback-of-notre-dame`, the content of the published page is indeterminate. You can not define the processing order. To detect page collisions, use the `--printPathWarnings` flag when building your site. diff --git a/docs/content/en/content-management/data-sources.md b/docs/content/en/content-management/data-sources.md index 3fc98b36a..0395266e0 100644 --- a/docs/content/en/content-management/data-sources.md +++ b/docs/content/en/content-management/data-sources.md @@ -65,7 +65,7 @@ Use data sources to augment existing content. For example, create a shortcode to {{</* csv-to-table "pets.csv" */>}} ``` -```go-html-template {file="layouts/shortcodes/csv-to-table.html"} +```go-html-template {file="layouts/_shortcodes/csv-to-table.html"} {{ with $file := .Get 0 }} {{ with resources.Get $file }} {{ with . | transform.Unmarshal }} diff --git a/docs/content/en/content-management/diagrams.md b/docs/content/en/content-management/diagrams.md index 0070ced59..3bcecb60b 100644 --- a/docs/content/en/content-management/diagrams.md +++ b/docs/content/en/content-management/diagrams.md @@ -39,7 +39,7 @@ Will be rendered as: Hugo does not provide a built-in template for Mermaid diagrams. Create your own using a [code block render hook]: -```go-html-template {file="layouts/_default/_markup/render-codeblock-mermaid.html" copy=true} +```go-html-template {file="layouts/_markup/render-codeblock-mermaid.html" copy=true} <pre class="mermaid"> {{ .Inner | htmlEscape | safeHTML }} </pre> @@ -48,7 +48,7 @@ Hugo does not provide a built-in template for Mermaid diagrams. Create your own Then include this snippet at the _bottom_ of your base template, before the closing `body` tag: -```go-html-template {file="layouts/_default/baseof.html" copy=true} +```go-html-template {file="layouts/baseof.html" copy=true} {{ if .Store.Get "hasMermaid" }} <script type="module"> import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.esm.min.mjs'; diff --git a/docs/content/en/content-management/formats.md b/docs/content/en/content-management/formats.md index 1acaae063..c82329ab2 100644 --- a/docs/content/en/content-management/formats.md +++ b/docs/content/en/content-management/formats.md @@ -75,7 +75,7 @@ Create your content in the [Emacs Org Mode] format preceded by front matter. You ### AsciiDoc -Create your content in the [AsciiDoc] format preceded by front matter. Hugo renders AsciiDoc content to HTML using the Asciidoctor executable. You must install Asciidoctor and its dependencies (Ruby) to use the AsciiDoc content format. +Create your content in the [AsciiDoc] format preceded by front matter. Hugo renders AsciiDoc content to HTML using the Asciidoctor executable. You must install Asciidoctor and its dependencies (Ruby) to render the AsciiDoc content format. You can configure the AsciiDoc renderer in your [site configuration][configure asciidoc]. @@ -97,7 +97,9 @@ hugo --logLevel info ### Pandoc -Create your content in the [Pandoc] format preceded by front matter. Hugo renders Pandoc content to HTML using the Pandoc executable. You must install Pandoc to use the Pandoc content format. +Create your content in the [Pandoc] format[^1] preceded by front matter. Hugo renders Pandoc content to HTML using the Pandoc executable. You must install Pandoc to render the Pandoc content format. + +[^1]: This is a derivation of the Markdown format as described by the CommonMark specification. Hugo passes these CLI flags when calling the Pandoc executable: @@ -105,11 +107,11 @@ Hugo passes these CLI flags when calling the Pandoc executable: --mathjax ``` -[Pandoc]: https://pandoc.org/ +[Pandoc]: https://pandoc.org/MANUAL.html#pandocs-markdown ### reStructuredText -Create your content in the [reStructuredText] format preceded by front matter. Hugo renders reStructuredText content to HTML using [Docutils], specifically rst2html. You must install Docutils and its dependencies (Python) to use the reStructuredText content format. +Create your content in the [reStructuredText] format preceded by front matter. Hugo renders reStructuredText content to HTML using [Docutils], specifically rst2html. You must install Docutils and its dependencies (Python) to render the reStructuredText content format. Hugo passes these CLI flags when calling the rst2html executable: diff --git a/docs/content/en/content-management/front-matter.md b/docs/content/en/content-management/front-matter.md index 8bfbd1acc..d99475f4c 100644 --- a/docs/content/en/content-management/front-matter.md +++ b/docs/content/en/content-management/front-matter.md @@ -237,7 +237,7 @@ You can add taxonomy terms to the front matter of any these [page kinds](g): Access taxonomy terms from a template using the [`Params`] or [`GetTerms`] method on a `Page` object. For example: -```go-html-template {file="layouts/_default/single.html"} +```go-html-template {file="layouts/page.html"} {{ with .GetTerms "tags" }} <p>Tags</p> <ul> diff --git a/docs/content/en/content-management/mathematics.md b/docs/content/en/content-management/mathematics.md index e0c8ba4d0..dc47cbde4 100644 --- a/docs/content/en/content-management/mathematics.md +++ b/docs/content/en/content-management/mathematics.md @@ -64,7 +64,7 @@ math = true The configuration above enables mathematical rendering on every page unless you set the `math` parameter to `false` in front matter. To enable mathematical rendering as needed, set the `math` parameter to `false` in your site configuration, and set the `math` parameter to `true` in front matter. Use this parameter in your base template as shown in [Step 3]. > [!note] -> The configuration above precludes the use of the `$...$` delimiter pair for inline equations. Although you can add this delimiter pair to the configuration and JavaScript, you will need to double-escape the `$` symbol when used outside of math contexts to avoid unintended formatting. +> The configuration above precludes the use of the `$...$` delimiter pair for inline equations. Although you can add this delimiter pair to the configuration and JavaScript, you must double-escape the `$` symbol when used outside of math contexts to avoid unintended formatting. > > See the [inline delimiters](#inline-delimiters) section for details. @@ -87,7 +87,7 @@ inline = [['@', '@']] Create a partial template to load MathJax or KaTeX. The example below loads MathJax, or you can use KaTeX as described in the [engines](#engines) section. -```go-html-template {file="layouts/partials/math.html" copy=true} +```go-html-template {file="layouts/_partials/math.html" copy=true} <script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js"></script> <script> MathJax = { @@ -108,7 +108,7 @@ The delimiters above must match the delimiters in your site configuration. Conditionally call the partial template from the base template. -```go-html-template {file="layouts/_default/baseof.html"} +```go-html-template {file="layouts/baseof.html"} <head> ... {{ if .Param "math" }} @@ -161,10 +161,10 @@ math = true The configuration, JavaScript, and examples above use the `\(...\)` delimiter pair for inline equations. The `$...$` delimiter pair is a common alternative, but using it may result in unintended formatting if you use the `$` symbol outside of math contexts. -If you add the `$...$` delimiter pair to your configuration and JavaScript, you must double-escape the `$` when outside of math contexts, regardless of whether mathematical rendering is enabled on the page. For example: +If you add the `$...$` delimiter pair to your configuration and JavaScript, you must double-escape the `$` symbol when used outside of math contexts to avoid unintended formatting. For example: ```text -A \\$5 bill _saved_ is a \\$5 bill _earned_. +I will give you \\$2 if you can solve $y = x^2$. ``` > [!note] @@ -181,7 +181,7 @@ MathJax and KaTeX are open-source JavaScript display engines. Both engines are f To use KaTeX instead of MathJax, replace the partial template from [Step 2] with this: -```go-html-template {file="layouts/partials/math.html" copy=true} +```go-html-template {file="layouts/_partials/math.html" copy=true} <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.21/dist/katex.min.css" diff --git a/docs/content/en/content-management/multilingual.md b/docs/content/en/content-management/multilingual.md index d419f4381..a22f0b50e 100644 --- a/docs/content/en/content-management/multilingual.md +++ b/docs/content/en/content-management/multilingual.md @@ -114,7 +114,7 @@ If, across the linked bundles, two or more files share the same basename, only o To create a list of links to translated content, use a template similar to the following: -```go-html-template {file="layouts/partials/i18nlist.html"} +```go-html-template {file="layouts/_partials/i18nlist.html"} {{ if .IsTranslated }} <h4>{{ i18n "translations" }}</h4> <ul> @@ -127,7 +127,7 @@ To create a list of links to translated content, use a template similar to the f {{ end }} ``` -The above can be put in a `partial` (i.e., inside `layouts/partials/`) and included in any template. It will not print anything if there are no translations for a given page. +The above can be put in a partial template then included in any template. It will not print anything if there are no translations for a given page. The above also uses the [`i18n` function][i18func] described in the next section. @@ -135,7 +135,7 @@ The above also uses the [`i18n` function][i18func] described in the next section `.AllTranslations` on a `Page` can be used to list all translations, including the page itself. On the home page it can be used to build a language navigator: -```go-html-template {file="layouts/partials/allLanguages.html"} +```go-html-template {file="layouts/_partials/allLanguages.html"} <ul> {{ range $.Site.Home.AllTranslations }} <li><a href="{{ .RelPermalink }}">{{ .Language.LanguageName }}</a></li> diff --git a/docs/content/en/content-management/organization/index.md b/docs/content/en/content-management/organization/index.md index a7682bfad..4a8fcb6fc 100644 --- a/docs/content/en/content-management/organization/index.md +++ b/docs/content/en/content-management/organization/index.md @@ -99,7 +99,7 @@ The [sections] can be nested as deeply as you want. The important thing to under ### Single pages in sections -Single content files in each of your sections will be rendered by a [single template]. Here is an example of a single `post` within `posts`: +Single content files in each of your sections will be rendered by a [page template]. Here is an example of a single `post` within `posts`: ```txt path ("posts/my-first-hugo-post.md") @@ -148,4 +148,4 @@ The `url` is the entire URL path, defined by the file path and optionally overri [config]: /configuration/ [pretty]: /content-management/urls/#appearance [sections]: /content-management/sections/ -[single template]: /templates/types/#single +[page template]: /templates/types/#page diff --git a/docs/content/en/content-management/related-content.md b/docs/content/en/content-management/related-content.md index d7b18dab0..b58a52f20 100644 --- a/docs/content/en/content-management/related-content.md +++ b/docs/content/en/content-management/related-content.md @@ -12,7 +12,7 @@ Hugo uses a set of factors to identify a page's related content based on front m To list up to 5 related pages (which share the same _date_ or _keyword_ parameters) is as simple as including something similar to this partial in your template: -```go-html-template {file="layouts/partials/related.html" copy=true} +```go-html-template {file="layouts/_partials/related.html" copy=true} {{ with site.RegularPages.Related . | first 5 }} <p>Related content:</p> <ul> diff --git a/docs/content/en/content-management/sections.md b/docs/content/en/content-management/sections.md index f7a2296f5..d21aca71b 100644 --- a/docs/content/en/content-management/sections.md +++ b/docs/content/en/content-management/sections.md @@ -63,7 +63,7 @@ With the file structure from the [example above](#overview): 1. The list page for the articles section includes all articles, regardless of directory structure; none of the subdirectories are sections. 1. The articles/2022 and articles/2023 directories do not have list pages; they are not sections. -1. The list page for the products section, by default, includes product-1 and product-2, but not their descendant pages. To include descendant pages, use the `RegularPagesRecursive` method instead of the `Pages` method in the list template. +1. The list page for the products section, by default, includes product-1 and product-2, but not their descendant pages. To include descendant pages, use the `RegularPagesRecursive` method instead of the `Pages` method in the section template. 1. All directories in the products section have list pages; each directory is a section. ## Template selection @@ -74,15 +74,15 @@ With the file structure from the [example above](#overview): Content directory|Section template :--|:-- -`content/products`|`layouts/products/list.html` -`content/products/product-1`|`layouts/products/list.html` -`content/products/product-1/benefits`|`layouts/products/list.html` +`content/products`|`layouts/products/section.html` +`content/products/product-1`|`layouts/products/section.html` +`content/products/product-1/benefits`|`layouts/products/section.html` -Content directory|Single template +Content directory|Page template :--|:-- -`content/products`|`layouts/products/single.html` -`content/products/product-1`|`layouts/products/single.html` -`content/products/product-1/benefits`|`layouts/products/single.html` +`content/products`|`layouts/products/page.html` +`content/products/product-1`|`layouts/products/page.html` +`content/products/product-1/benefits`|`layouts/products/page.html` If you need to use a different template for a subsection, specify `type` and/or `layout` in front matter. @@ -98,7 +98,7 @@ The content file (benefit-1.md) has four ancestors: benefits, product-1, product For example, use the `.Ancestors` method to render breadcrumb navigation. -```go-html-template {file="layouts/partials/breadcrumb.html"} +```go-html-template {file="layouts/_partials/breadcrumb.html"} <nav aria-label="breadcrumb" class="breadcrumb"> <ol> {{ range .Ancestors.Reverse }} diff --git a/docs/content/en/content-management/shortcodes.md b/docs/content/en/content-management/shortcodes.md index 2de387f39..2c3f1e29f 100644 --- a/docs/content/en/content-management/shortcodes.md +++ b/docs/content/en/content-management/shortcodes.md @@ -22,7 +22,7 @@ Hugo's embedded shortcodes are pre-defined templates within the application. Ref Create custom shortcodes to simplify and standardize content creation. For example, the following shortcode template generates an audio player using a [global resource](g): -```go-html-template {file="layouts/shortcodes/audio.html"} +```go-html-template {file="layouts/_shortcodes/audio.html"} {{ with resources.Get (.Get "src") }} <audio controls preload="auto" src="{{ .RelPermalink }}"></audio> {{ end }} @@ -181,7 +181,7 @@ With standard notation, Hugo processes the shortcode separately, merging the out By way of example, with this shortcode template: -```go-html-template {file="layouts/shortcodes/foo.html"} +```go-html-template {file="layouts/_shortcodes/foo.html"} {{ .Inner }} ``` diff --git a/docs/content/en/content-management/taxonomies.md b/docs/content/en/content-management/taxonomies.md index e8ba04c28..6caf70b0c 100644 --- a/docs/content/en/content-management/taxonomies.md +++ b/docs/content/en/content-management/taxonomies.md @@ -108,18 +108,73 @@ categories_weight = 44 By using taxonomic weight, the same piece of content can appear in different positions in different taxonomies. -## Add custom metadata to a taxonomy or term +## Metadata -If you need to add custom metadata to your taxonomy terms, you will need to create a page for that term at `/content/<TAXONOMY>/<TERM>/_index.md` and add your metadata in its front matter. Continuing with our 'Actors' example, let's say you want to add a Wikipedia page link to each actor. Your terms pages would be something like this: +Display metadata about each term by creating a corresponding branch bundle in the `content` directory. -{{< code-toggle file=content/actors/bruce-willis/_index.md fm=true >}} -title: "Bruce Willis" -wikipedia: "https://en.wikipedia.org/wiki/Bruce_Willis" +For example, create an "authors" taxonomy: + +{{< code-toggle file=hugo >}} +[taxonomies] +author = 'authors' {{< /code-toggle >}} -[content section]: /content-management/sections/ -[content type]: /content-management/types/ -[documentation on archetypes]: /content-management/archetypes/ -[front matter]: /content-management/front-matter/ -[taxonomy templates]: /templates/types/#taxonomy -[site configuration]: /configuration/ +Then create content with one [branch bundle](g) for each term: + +```text +content/ +└── authors/ + ├── jsmith/ + │ ├── _index.md + │ └── portrait.jpg + └── rjones/ + ├── _index.md + └── portrait.jpg +``` + +Then add front matter to each term page: + +{{< code-toggle file=content/authors/jsmith/_index.md fm=true >}} +title = "John Smith" +affiliation = "University of Chicago" +{{< /code-toggle >}} + +Then create a taxonomy template specific to the "authors" taxonomy: + +```go-html-template {file="layouts/authors/taxonomy.html"} +{{ define "main" }} + <h1>{{ .Title }}</h1> + {{ .Content }} + {{ range .Data.Terms.Alphabetical }} + <h2><a href="{{ .Page.RelPermalink }}">{{ .Page.LinkTitle }}</a></h2> + <p>Affiliation: {{ .Page.Params.Affiliation }}</p> + {{ with .Page.Resources.Get "portrait.jpg" }} + {{ with .Fill "100x100" }} + <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="portrait"> + {{ end }} + {{ end }} + {{ end }} +{{ end }} +``` + +In the example above we list each author including their affiliation and portrait. + +Or create a term template specific to the "authors" taxonomy: + +```go-html-template {file="layouts/authors/term.html"} +{{ define "main" }} + <h1>{{ .Title }}</h1> + <p>Affiliation: {{ .Params.affiliation }}</p> + {{ with .Resources.Get "portrait.jpg" }} + {{ with .Fill "100x100" }} + <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="portrait"> + {{ end }} + {{ end }} + {{ .Content }} + {{ range .Pages }} + <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2> + {{ end }} +{{ end }} +``` + +In the example above we display the author including their affiliation and portrait, then a list of associated content. diff --git a/docs/content/en/content-management/types.md b/docs/content/en/content-management/types.md deleted file mode 100644 index 08e9adda2..000000000 --- a/docs/content/en/content-management/types.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -title: Content types -description: Hugo is built around content organized in sections. -categories: [] -keywords: [] -aliases: [/content/types] ---- - -A **content type** is a way to organize your content. Hugo resolves the content type from either the `type` in front matter or, if not set, the first directory in the file path. E.g. `content/blog/my-first-event.md` will be of type `blog` if no `type` is set. - -A content type is used to - -- Determine how the content is rendered. See [Template Lookup Order](/templates/lookup-order/) and [Content Views](/templates/content-view) for more. -- Determine which [archetype](/content-management/archetypes/) template to use for new content. diff --git a/docs/content/en/content-management/urls.md b/docs/content/en/content-management/urls.md index 2630105e5..a39afa6ef 100644 --- a/docs/content/en/content-management/urls.md +++ b/docs/content/en/content-management/urls.md @@ -108,7 +108,7 @@ multilingual|`about`|`https://example.org/de/about/` {{< new-in 0.131.0 />}} -You can also usetokens when setting the `url` value. This is typically used in `cascade` sections: +You can also use tokens when setting the `url` value. This is typically used in `cascade` sections: {{< code-toggle file=content/foo/bar/_index.md fm=true >}} title ="Bar" diff --git a/docs/content/en/contribute/development.md b/docs/content/en/contribute/development.md index 78ca5ec5c..e2cfee4ff 100644 --- a/docs/content/en/contribute/development.md +++ b/docs/content/en/contribute/development.md @@ -153,7 +153,7 @@ CGO_ENABLED=1 go install -tags extended github.com/gohugoio/hugo@latest To build and install a specific release: ```sh -CGO_ENABLED=1 go install -tags extended github.com/gohugoio/hugo@v0.144.2 +CGO_ENABLED=1 go install -tags extended github.com/gohugoio/hugo@v0.147.1 ``` To build and install at the latest commit on the master branch: diff --git a/docs/content/en/contribute/documentation.md b/docs/content/en/contribute/documentation.md index 68129912a..c72ddd03f 100644 --- a/docs/content/en/contribute/documentation.md +++ b/docs/content/en/contribute/documentation.md @@ -152,26 +152,27 @@ This example demonstrates the minimum required front matter fields. If quotation marks are required, prefer single quotes to double quotes when possible. -Seq|Field|Description|Required ---:|:--|:--|:-- -1|`title`|The page title|:heavy_check_mark:| -2|`linkTitle`|A short version of the page title|| -3|`description`|A complete sentence describing the page|:heavy_check_mark:| -4|`categories`|An array of terms in the categories taxonomy|:heavy_check_mark: [^1]| -5|`keywords`|An array of keywords used to identify related content|:heavy_check_mark: [^1]| -6|`publishDate`|Applicable to news items: the publication date|| -7|`params.altTitle`|An alternate title: used in the "see also" panel if provided|| -8|`params.functions_and_methods.aliases`|Applicable to function and method pages: an array of alias names|| -9|`params.functions_and_methods.returnType`|Applicable to function and method pages: the data type returned|| -10|`params.functions_and_methods.signatures`|Applicable to function and method pages: an array of signatures|| -11|`params.hide_in_this_section`|Whether to hide the "in this section" panel|| -12|`params.minversion`|Applicable to the quick start page: the minimum Hugo version required|| -13|`params.permalink`|Reserved for use by the news content adapter|| -14|`params.reference (used in glossary term)`|Applicable to glossary entries: a URL for additional information|| -15|`params.show_publish_date`|Whether to show the `publishDate` when rendering the page|| -16|`weight`|The page weight|| -17|`aliases`|Previous URLs used to access this page|| -18|`expirydate`|The expiration date|| +Field|Description|Required +:--|:--|:-- +`title`|The page title|:heavy_check_mark:| +`linkTitle`|A short version of the page title|| +`description`|A complete sentence describing the page|:heavy_check_mark:| +`categories`|An array of terms in the categories taxonomy|:heavy_check_mark: [^1]| +`keywords`|An array of keywords used to identify related content|:heavy_check_mark: [^1]| +`publishDate`|Applicable to news items: the publication date|| +`params.alt_title`|An alternate title: used in the "see also" panel if provided|| +`params.functions_and_methods.aliases`|Applicable to function and method pages: an array of alias names|| +`params.functions_and_methods.returnType`|Applicable to function and method pages: the data type returned|| +`params.functions_and_methods.signatures`|Applicable to function and method pages: an array of signatures|| +`params.hide_in_this_section`|Whether to hide the "in this section" panel|| +`params.minversion`|Applicable to the quick start page: the minimum Hugo version required|| +`params.permalink`|Reserved for use by the news content adapter|| +`params.reference (used in glossary term)`|Applicable to glossary entries: a URL for additional information|| +`params.searchable`|Whether to add the content of this page to the search index. The default value is cascaded down from the site configuration; `true` if the page kind is `page`, and `false` if the page kind is one of `home`, `section`, `taxonomy`, or `term`. Add this field to override the default value.|| +`params.show_publish_date`|Whether to show the `publishDate` when rendering the page|| +`weight`|The page weight|| +`aliases`|Previous URLs used to access this page|| +`expirydate`|The expiration date|| [^1]: The field is required, but its data is not. @@ -185,13 +186,13 @@ If the title in the "See also" sidebar is ambiguous or the same as another page, title = "Long descriptive title" linkTitle = "Short title" [params] -altTitle = "Whatever you want" +alt_title = "Whatever you want" {{< /code-toggle >}} Use of the alternate title is limited to the "See also" sidebar. > [!note] -> Think carefully before setting the `altTitle`. Use it only when absolutely necessary. +> Think carefully before setting the `alt_title`. Use it only when absolutely necessary. ## Code examples @@ -223,10 +224,10 @@ erroneous lexing/highlighting of shortcode calls. ``` ```` -To include a filename header and copy-to-clipboard button: +To include a file name header and copy-to-clipboard button: ````text -```go-html-template {file="layouts/partials/foo.html" copy=true} +```go-html-template {file="layouts/_partials/foo.html" copy=true} {{ if eq $foo "bar" }} {{ print "foo is bar" }} {{ end }} @@ -236,7 +237,7 @@ To include a filename header and copy-to-clipboard button: To wrap the code block within an initially-opened `details` element using a non-default summary: ````text -```go-html-template {details=true open=true summary="layouts/partials/foo.html" copy=true} +```go-html-template {details=true open=true summary="layouts/_partials/foo.html" copy=true} {{ if eq $foo "bar" }} {{ print "foo is bar" }} {{ end }} @@ -427,7 +428,7 @@ Use the [new-in shortcode](#new-in) to indicate a new feature: {{</* new-in 0.144.0 */>}} ``` -The "new in" label will be hidden if the specified version is older than a predefined threshold, based on differences in major and minor versions. See [details](https://github.com/gohugoio/hugoDocs/blob/master/_vendor/github.com/gohugoio/gohugoioTheme/layouts/shortcodes/new-in.html). +The "new in" label will be hidden if the specified version is older than a predefined threshold, based on differences in major and minor versions. See [details](https://github.com/gohugoio/hugoDocs/blob/master/_vendor/github.com/gohugoio/gohugoioTheme/layouts/_shortcodes/new-in.html). ## Deprecated features @@ -514,17 +515,17 @@ Visit the [documentation repository] and create a pull request (PR). A project maintainer will review your PR and may request changes. You may delete your branch after the maintainer merges your PR. -[ATX]: https://spec.commonmark.org/0.30/#atx-headings +[ATX]: https://spec.commonmark.org/current/#atx-headings [basic english]: https://simple.wikipedia.org/wiki/Basic_English [basic english]: https://simple.wikipedia.org/wiki/Basic_English [developer documentation style guide]: https://developers.google.com/style [documentation repository]: https://github.com/gohugoio/hugoDocs/ -[fenced code blocks]: https://spec.commonmark.org/0.30/#fenced-code-blocks +[fenced code blocks]: https://spec.commonmark.org/current/#fenced-code-blocks [glossary]: /quick-reference/glossary/ -[indented code blocks]: https://spec.commonmark.org/0.30/#indented-code-blocks +[indented code blocks]: https://spec.commonmark.org/current/#indented-code-blocks [issues]: https://github.com/gohugoio/hugoDocs/issues -[list items]: https://spec.commonmark.org/0.30/#list-items +[list items]: https://spec.commonmark.org/current/#list-items [project repository]: https://github.com/gohugoio/hugo -[raw HTML]: https://spec.commonmark.org/0.30/#raw-html +[raw HTML]: https://spec.commonmark.org/current/#raw-html [related content]: /content-management/related-content/ -[setext]: https://spec.commonmark.org/0.30/#setext-heading +[setext]: https://spec.commonmark.org/current/#setext-heading diff --git a/docs/content/en/documentation.md b/docs/content/en/documentation.md index 6f96c1f9c..9bd3421e9 100644 --- a/docs/content/en/documentation.md +++ b/docs/content/en/documentation.md @@ -3,6 +3,8 @@ title: Hugo Documentation linkTitle: Docs description: Hugo is the world's fastest static website engine. It's written in Go (aka Golang) and developed by bep, spf13 and friends. layout: list +params: + searchable: false --- <!-- diff --git a/docs/content/en/functions/collections/Shuffle.md b/docs/content/en/functions/collections/Shuffle.md index 3a27c099a..60af0a1ba 100644 --- a/docs/content/en/functions/collections/Shuffle.md +++ b/docs/content/en/functions/collections/Shuffle.md @@ -12,8 +12,18 @@ aliases: [/functions/shuffle] --- ```go-html-template -{{ shuffle (seq 1 2 3) }} → [3 1 2] -{{ shuffle (slice "a" "b" "c") }} → [b a c] +{{ collections.Shuffle (slice "a" "b" "c") }} → [b a c] ``` The result will vary from one build to the next. + +To render an unordered list of 5 random pages from a page collection: + +```go-html-template +<ul> + {{ $p := site.RegularPages }} + {{ range $p | collections.Shuffle | first 5 }} + <li><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></li> + {{ end }} +</ul> +``` diff --git a/docs/content/en/functions/css/Sass.md b/docs/content/en/functions/css/Sass.md index 03a4c7451..ae628a15f 100644 --- a/docs/content/en/functions/css/Sass.md +++ b/docs/content/en/functions/css/Sass.md @@ -66,20 +66,20 @@ vars ```go-html-template {copy=true} {{ with resources.Get "sass/main.scss" }} {{ $opts := dict - "enableSourceMap" (not hugo.IsProduction) - "outputStyle" (cond hugo.IsProduction "compressed" "expanded") + "enableSourceMap" hugo.IsDevelopment + "outputStyle" (cond hugo.IsDevelopment "expanded" "compressed") "targetPath" "css/main.css" "transpiler" "dartsass" "vars" site.Params.styles "includePaths" (slice "node_modules/bootstrap/scss") }} {{ with . | toCSS $opts }} - {{ if hugo.IsProduction }} + {{ if hugo.IsDevelopment }} + <link rel="stylesheet" href="{{ .RelPermalink }}"> + {{ else }} {{ with . | fingerprint }} <link rel="stylesheet" href="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous"> {{ end }} - {{ else }} - <link rel="stylesheet" href="{{ .RelPermalink }}"> {{ end }} {{ end }} {{ end }} @@ -113,7 +113,7 @@ macOS|Homebrew|[brew.sh]|`brew install sass/sass/sass` Windows|Chocolatey|[chocolatey.org]|`choco install sass` Windows|Scoop|[scoop.sh]|`scoop install sass` -You may also install [prebuilt binaries] for Linux, macOS, and Windows. +You may also install [prebuilt binaries] for Linux, macOS, and Windows. You must install the prebuilt binary outside of your project directory and ensure its path is included in your system's PATH environment variable. Run `hugo env` to list the active transpilers. @@ -141,8 +141,8 @@ To install Dart Sass for your builds on GitLab Pages, the `.gitlab-ci.yml` file ```yaml variables: - HUGO_VERSION: 0.144.2 - DART_SASS_VERSION: 1.85.0 + HUGO_VERSION: 0.147.9 + DART_SASS_VERSION: 1.89.2 GIT_DEPTH: 0 GIT_STRATEGY: clone GIT_SUBMODULE_STRATEGY: recursive @@ -175,8 +175,8 @@ To install Dart Sass for your builds on Netlify, the `netlify.toml` file should ```toml [build.environment] -HUGO_VERSION = "0.144.2" -DART_SASS_VERSION = "1.85.0" +HUGO_VERSION = "0.147.9" +DART_SASS_VERSION = "1.89.2" NODE_VERSION = "22" TZ = "America/Los_Angeles" diff --git a/docs/content/en/functions/css/TailwindCSS.md b/docs/content/en/functions/css/TailwindCSS.md index 6add7373a..9d40ad0aa 100644 --- a/docs/content/en/functions/css/TailwindCSS.md +++ b/docs/content/en/functions/css/TailwindCSS.md @@ -18,8 +18,10 @@ Use the `css.TailwindCSS` function to process your Tailwind CSS files. This func 1. Compile those utility classes into standard CSS. 1. Generate an optimized CSS output file. -> [!caution] -> Tailwind CSS v4.0 and later requires a relatively [modern browser](https://tailwindcss.com/docs/compatibility#browser-support) to render correctly. +> [!note] +> Use this function with Tailwind CSS v4.0 and later, which require a relatively [modern browser] to render correctly. + +[modern browser]: https://tailwindcss.com/docs/compatibility#browser-support ## Setup @@ -27,11 +29,12 @@ Use the `css.TailwindCSS` function to process your Tailwind CSS files. This func Install the Tailwind CSS CLI v4.0 or later: -```sh +```sh {copy=true} npm install --save-dev tailwindcss @tailwindcss/cli ``` -The TailwindCSS CLI is also available as a [standalone executable] if you want to use it without installing Node.js. +The Tailwind CSS CLI is also available as a [standalone executable]. You must install it outside of your project directory and ensure its path is included in your system's `PATH` environment variable. + [standalone executable]: https://github.com/tailwindlabs/tailwindcss/releases/latest @@ -40,21 +43,23 @@ The TailwindCSS CLI is also available as a [standalone executable] if you want t Add this to your site configuration: {{< code-toggle file=hugo copy=true >}} -[[module.mounts]] -source = "assets" -target = "assets" -[[module.mounts]] -source = "hugo_stats.json" -target = "assets/notwatching/hugo_stats.json" -disableWatch = true -[build.buildStats] -enable = true -[[build.cachebusters]] -source = "assets/notwatching/hugo_stats\\.json" -target = "css" -[[build.cachebusters]] -source = "(postcss|tailwind)\\.config\\.js" -target = "css" +[build] + [build.buildStats] + enable = true + [[build.cachebusters]] + source = 'assets/notwatching/hugo_stats\.json' + target = 'css' + [[build.cachebusters]] + source = '(postcss|tailwind)\.config\.js' + target = 'css' +[module] + [[module.mounts]] + source = 'assets' + target = 'assets' + [[module.mounts]] + disableWatch = true + source = 'hugo_stats.json' + target = 'assets/notwatching/hugo_stats.json' {{< /code-toggle >}} ### Step 3 @@ -72,20 +77,15 @@ Tailwind CSS respects `.gitignore` files. This means that if `hugo_stats.json` i Create a partial template to process the CSS with the Tailwind CSS CLI: -```go-html-template {file="layouts/partials/css.html" copy=true} -{{ with (templates.Defer (dict "key" "global")) }} - {{ with resources.Get "css/main.css" }} - {{ $opts := dict - "minify" hugo.IsProduction - "inlineImports" true - }} - {{ with . | css.TailwindCSS $opts }} - {{ if hugo.IsProduction }} - {{ with . | fingerprint }} - <link rel="stylesheet" href="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous"> - {{ end }} - {{ else }} - <link rel="stylesheet" href="{{ .RelPermalink }}"> +```go-html-template {file="layouts/_partials/css.html" copy=true} +{{ with resources.Get "css/main.css" }} + {{ $opts := dict "minify" (not hugo.IsDevelopment) }} + {{ with . | css.TailwindCSS $opts }} + {{ if hugo.IsDevelopment }} + <link rel="stylesheet" href="{{ .RelPermalink }}"> + {{ else }} + {{ with . | fingerprint }} + <link rel="stylesheet" href="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous"> {{ end }} {{ end }} {{ end }} @@ -94,33 +94,16 @@ Create a partial template to process the CSS with the Tailwind CSS CLI: ### Step 5 -Call the partial template from your base template: +Call the partial template from your base template, deferring template execution until after all sites and output formats have been rendered: -```go-html-template {file="layouts/_default/baseof.html"} +```go-html-template {file="layouts/baseof.html" copy=true} <head> ... - {{ partialCached "css.html" . }} + {{ with (templates.Defer (dict "key" "global")) }} + {{ partial "css.html" . }} + {{ end }} ... -<head> -``` - -### Step 6 - -Optionally create a `tailwind.config.js` file in the root of your project as shown below. This is necessary if you use the [Tailwind CSS IntelliSense -extension] for Visual Studio Code. - -[Tailwind CSS IntelliSense -extension]: https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss - -```js {file="tailwind.config.js" copy=true} -/* -This file is present to satisfy a requirement of the Tailwind CSS IntelliSense -extension for Visual Studio Code. - -https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss - -The rest of this file is intentionally empty. -*/ +</head> ``` ## Options @@ -131,8 +114,9 @@ minify optimize : (`bool`) Whether to optimize the output without minifying. Default is `false`. -inlineImports -: (`bool`) Whether to enable inlining of `@import` statements. Inlining is performed recursively, but currently once only per file. It is not possible to import the same file in different scopes (root, media query, etc.). Note that this import routine does not care about the CSS specification, so you can have `@import` statements anywhere in the file. Default is `false`. +disableInlineImports +: {{< new-in 0.147.4 />}} +: (`bool`) Whether to disable inlining of `@import` statements. Inlining is performed recursively, but currently once only per file. It is not possible to import the same file in different scopes (root, media query, etc.). Note that this import routine does not care about the CSS specification, so you can have `@import` statements anywhere in the file. Default is `false`. skipInlineImportsNotFound : (`bool`) Whether to allow the build process to continue despite unresolved import statements, preserving the original import declarations. It is important to note that the inline importer does not process URL-based imports or those with media queries, and these will remain unaltered even when this option is disabled. Default is `false`. diff --git a/docs/content/en/functions/debug/Timer.md b/docs/content/en/functions/debug/Timer.md index c2cd59211..74395b130 100644 --- a/docs/content/en/functions/debug/Timer.md +++ b/docs/content/en/functions/debug/Timer.md @@ -18,7 +18,7 @@ The timer starts when you instantiate it, and stops when you call its `Stop` met ```go-html-template {{ $t := debug.Timer "TestSqrt" }} -{{ range seq 2000 }} +{{ range 2000 }} {{ $f := math.Sqrt . }} {{ end }} {{ $t.Stop }} diff --git a/docs/content/en/functions/diagrams/Goat.md b/docs/content/en/functions/diagrams/Goat.md index e2f55eee0..5f6fcf1da 100644 --- a/docs/content/en/functions/diagrams/Goat.md +++ b/docs/content/en/functions/diagrams/Goat.md @@ -66,7 +66,7 @@ To customize rendering, override Hugo's [embedded code block render hook] for Go By way of example, let's create a code block render hook to render GoAT diagrams as `figure` elements with an optional caption. -```go-html-template {file="layouts/_default/_markup/render-codeblock-goat.html"} +```go-html-template {file="layouts/_markup/render-codeblock-goat.html"} {{ $caption := or .Attributes.caption "" }} {{ $class := or .Attributes.class "diagram" }} {{ $id := or .Attributes.id (printf "diagram-%d" (add 1 .Ordinal)) }} diff --git a/docs/content/en/functions/global/page.md b/docs/content/en/functions/global/page.md index 0d4b8070f..40f6aba8f 100644 --- a/docs/content/en/functions/global/page.md +++ b/docs/content/en/functions/global/page.md @@ -30,7 +30,7 @@ When a `Page` object is not in context, you can use the global `page` function: ## Explanation -Hugo almost always passes a `Page` as the data context into the top-level template (e.g., `single.html`). The one exception is the multihost sitemap template. This means that you can access the current page with the `.` in the template. +Hugo almost always passes a `Page` as the data context into the top-level template (e.g., `baseof.html`). The one exception is the multihost sitemap template. This means that you can access the current page with the `.` in the template. But when you are deeply nested inside of a [content view](g), [partial](g), or [render hook](g), it is not always practical or possible to access the `Page` object. diff --git a/docs/content/en/functions/go-template/block.md b/docs/content/en/functions/go-template/block.md index bffab1f8c..383a3d72e 100644 --- a/docs/content/en/functions/go-template/block.md +++ b/docs/content/en/functions/go-template/block.md @@ -23,7 +23,7 @@ and then executing it in place: ``` The typical use is to define a set of root templates that are then customized by redefining the block templates within. -```go-html-template {file="layouts/_default/baseof.html"} +```go-html-template {file="layouts/baseof.html"} <body> <main> {{ block "main" . }} @@ -33,14 +33,14 @@ The typical use is to define a set of root templates that are then customized by </body> ``` -```go-html-template {file="layouts/_default/single.html"} +```go-html-template {file="layouts/page.html"} {{ define "main" }} <h1>{{ .Title }}</h1> {{ .Content }} {{ end }} ``` -```go-html-template {file="layouts/_default/list.html"} +```go-html-template {file="layouts/section.html"} {{ define "main" }} <h1>{{ .Title }}</h1> {{ .Content }} diff --git a/docs/content/en/functions/go-template/define.md b/docs/content/en/functions/go-template/define.md index 19762a3d6..40d495bd9 100644 --- a/docs/content/en/functions/go-template/define.md +++ b/docs/content/en/functions/go-template/define.md @@ -28,7 +28,7 @@ Use with the [`partial`] function: ```go-html-template {{ partial "inline/foo.html" (dict "answer" 42) }} -{{ define "partials/inline/foo.html" }} +{{ define "_partials/inline/foo.html" }} {{ printf "The answer is %v." .answer }} {{ end }} ``` @@ -43,8 +43,21 @@ Use with the [`template`] function: {{ end }} ``` +> [!warning] +> Only [template comments] are allowed outside of the `define` and `end` statements. Avoid placing any other text, including HTML comments, outside of these boundaries. Doing so will cause rendering issues, potentially resulting in a blank page. See the example below. + +```go-html-template {file="layouts/do-not-do-this.html"} +<div>This div element broke your template.</div> +{{ define "main" }} + <h2>{{ .Title }}</h2> + {{ .Content }} +{{ end }} +<!-- An HTML comment will break your template too. --> +``` + +{{% include "/_common/functions/go-template/text-template.md" %}} + [`block`]: /functions/go-template/block/ [`template`]: /functions/go-template/block/ [`partial`]: /functions/partials/include/ - -{{% include "/_common/functions/go-template/text-template.md" %}} +[template comments]: /templates/introduction/#comments diff --git a/docs/content/en/functions/go-template/range.md b/docs/content/en/functions/go-template/range.md index a06907c79..50f714140 100644 --- a/docs/content/en/functions/go-template/range.md +++ b/docs/content/en/functions/go-template/range.md @@ -11,7 +11,7 @@ params: aliases: [/functions/range] --- -{{% include "/_common/functions/truthy-falsy.md" %}} +The collection may be a slice, a map, or an integer. ```go-html-template {{ $s := slice "foo" "bar" "baz" }} @@ -40,19 +40,22 @@ Within a range block: At the top of a page template, the [context](g) (the dot) is a `Page` object. Within the `range` block, the context is bound to each successive element. -With this contrived example that uses the [`seq`] function to generate a slice of integers: +With this contrived example: ```go-html-template -{{ range seq 3 }} - {{ .Title }} +{{ $s := slice "foo" "bar" "baz" }} +{{ range $s }} + {{ .Title }} {{ end }} ``` Hugo will throw an error: - can't evaluate field Title in type int +```text +can't evaluate field Title in type int +``` -The error occurs because we are trying to use the `.Title` method on an integer instead of a `Page` object. Within the `range` block, if we want to render the page title, we need to get the context passed into the template. +The error occurs because we are trying to use the `.Title` method on a string instead of a `Page` object. Within the `range` block, if we want to render the page title, we need to get the context passed into the template. > [!note] > Use the `$` to get the context passed into the template. @@ -60,15 +63,18 @@ The error occurs because we are trying to use the `.Title` method on an integer This template will render the page title three times: ```go-html-template -{{ range seq 3 }} - {{ $.Title }} +{{ $s := slice "foo" "bar" "baz" }} +{{ range $s }} + {{ $.Title }} {{ end }} ``` > [!note] > Gaining a thorough understanding of context is critical for anyone writing template code. -## Array or slice of scalars +## Examples + +### Slice of scalars This template code: @@ -121,7 +127,7 @@ Is rendered to: <p>2: baz</p> ``` -## Array or slice of maps +### Slice of maps This template code: @@ -144,7 +150,7 @@ Is rendered to: <p>Joey is 24</p> ``` -## Array or slice of pages +### Slice of pages This template code: @@ -162,7 +168,7 @@ Is rendered to: <h2><a href="/articles/article-1/">Article 1</a></h2> ``` -## Maps +### Maps This template code: @@ -182,9 +188,32 @@ Is rendered to: Unlike ranging over an array or slice, Hugo sorts by key when ranging over a map. +### Integers + +{{< new-in 0.123.0 />}} + +Ranging over a positive integer `n` executes the block `n` times, with the context starting at zero and incrementing by one in each iteration. + +```go-html-template +{{ $s := slice }} +{{ range 1 }} + {{ $s = $s | append . }} +{{ end }} +{{ $s }} → [0] +``` + +```go-html-template +{{ $s := slice }} +{{ range 3 }} + {{ $s = $s | append . }} +{{ end }} +{{ $s }} → [0 1 2] +``` + +Ranging over a non-positive integer executes the block zero times. + {{% include "/_common/functions/go-template/text-template.md" %}} [`break`]: /functions/go-template/break/ [`continue`]: /functions/go-template/continue/ [`else`]: /functions/go-template/else/ -[`seq`]: /functions/collections/seq/ diff --git a/docs/content/en/functions/go-template/return.md b/docs/content/en/functions/go-template/return.md index eb6ba30cd..911c0925c 100644 --- a/docs/content/en/functions/go-template/return.md +++ b/docs/content/en/functions/go-template/return.md @@ -23,7 +23,7 @@ A `return` statement without a value returns an empty string of type `template.H By way of example, let's create a partial template that _renders_ HTML, describing whether the given number is odd or even: -```go-html-template {file="layouts/partials/odd-or-even.html"} +```go-html-template {file="layouts/_partials/odd-or-even.html"} {{ if math.ModBool . 2 }} <p>{{ . }} is even</p> {{ else }} @@ -39,7 +39,7 @@ When called, the partial renders HTML: Instead of rendering HTML, let's create a partial that _returns_ a boolean value, reporting whether the given number is even: -```go-html-template {file="layouts/partials/is-even.html"} +```go-html-template {file="layouts/_partials/is-even.html"} {{ return math.ModBool . 2 }} ``` @@ -60,8 +60,6 @@ Hugo renders: <p>42 is even</p> ``` -See additional examples in the [partial templates] section. - ## Usage > [!note] @@ -71,7 +69,7 @@ A partial that returns a value must contain only one `return` statement, placed For example: -```go-html-template {file="layouts/partials/is-even.html"} +```go-html-template {file="layouts/_partials/is-even.html"} {{ $result := false }} {{ if math.ModBool . 2 }} {{ $result = "even" }} @@ -84,7 +82,7 @@ For example: > [!note] > The construct below is incorrect; it contains more than one `return` statement. -```go-html-template {file="layouts/partials/do-not-do-this.html"} +```go-html-template {file="layouts/_partials/do-not-do-this.html"} {{ if math.ModBool . 2 }} {{ return "even" }} {{ else }} @@ -92,5 +90,4 @@ For example: {{ end }} ``` -[partial templates]: /templates/partial/#returning-a-value-from-a-partial [text/template package]: https://pkg.go.dev/text/template diff --git a/docs/content/en/functions/go-template/template.md b/docs/content/en/functions/go-template/template.md index 053cfcc22..903f1490a 100644 --- a/docs/content/en/functions/go-template/template.md +++ b/docs/content/en/functions/go-template/template.md @@ -10,27 +10,7 @@ params: signatures: ['template NAME [CONTEXT]'] --- -Use the `template` function to execute any of these [embedded templates](g): - -- [`disqus.html`] -- [`google_analytics.html`] -- [`opengraph.html`] -- [`pagination.html`] -- [`schema.html`] -- [`twitter_cards.html`] - - - -For example: - -```go-html-template -{{ range (.Paginate .Pages).Pages }} - <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2> -{{ end }} -{{ template "_internal/pagination.html" . }} -``` - -You can also use the `template` function to execute a defined template: +Use the `template` function to execute a defined template: ```go-html-template {{ template "foo" (dict "answer" 42) }} @@ -40,12 +20,12 @@ You can also use the `template` function to execute a defined template: {{ end }} ``` -The example above can be rewritten using an [inline partial] template: +The example above can be rewritten using an inline partial template: ```go-html-template {{ partial "inline/foo.html" (dict "answer" 42) }} -{{ define "partials/inline/foo.html" }} +{{ define "_partials/inline/foo.html" }} {{ printf "The answer is %v." .answer }} {{ end }} ``` @@ -58,13 +38,5 @@ The key distinctions between the preceding two examples are: {{% include "/_common/functions/go-template/text-template.md" %}} -[`disqus.html`]: /templates/embedded/#disqus -[`google_analytics.html`]: /templates/embedded/#google-analytics -[`opengraph.html`]: /templates/embedded/#open-graph -[`pagination.html`]: /templates/embedded/#pagination [`partialCached`]: /functions/partials/includecached/ -[`partial`]: /functions/partials/include/ [`return`]: /functions/go-template/return/ -[`schema.html`]: /templates/embedded/#schema -[`twitter_cards.html`]: /templates/embedded/#x-twitter-cards -[inline partial]: /templates/partial/#inline-partials diff --git a/docs/content/en/functions/hugo/Generator.md b/docs/content/en/functions/hugo/Generator.md index dc72a7af2..c044a210c 100644 --- a/docs/content/en/functions/hugo/Generator.md +++ b/docs/content/en/functions/hugo/Generator.md @@ -11,5 +11,5 @@ params: --- ```go-html-template -{{ hugo.Generator }} → <meta name="generator" content="Hugo 0.144.2"> +{{ hugo.Generator }} → <meta name="generator" content="Hugo 0.147.9"> ``` diff --git a/docs/content/en/functions/hugo/Version.md b/docs/content/en/functions/hugo/Version.md index 7925af981..a23bd75cd 100644 --- a/docs/content/en/functions/hugo/Version.md +++ b/docs/content/en/functions/hugo/Version.md @@ -11,5 +11,5 @@ params: --- ```go-html-template -{{ hugo.Version }} → 0.144.2 +{{ hugo.Version }} → 0.147.9 ``` diff --git a/docs/content/en/functions/images/QR.md b/docs/content/en/functions/images/QR.md index eee2dff14..bf13e16e9 100644 --- a/docs/content/en/functions/images/QR.md +++ b/docs/content/en/functions/images/QR.md @@ -68,7 +68,7 @@ Specify `level`, `scale`, and `targetDir` as needed to achieve the desired resul To include a QR code that points to the `Permalink` of the current page: -```go-html-template {file="layouts/_default/single.html"} +```go-html-template {file="layouts/page.html"} {{ with images.QR .Permalink }} <img src="{{ .RelPermalink }}" diff --git a/docs/content/en/functions/images/Text.md b/docs/content/en/functions/images/Text.md index 8f7e730ba..c6a0e5b6e 100644 --- a/docs/content/en/functions/images/Text.md +++ b/docs/content/en/functions/images/Text.md @@ -19,6 +19,7 @@ alignx : (`string`) The horizontal alignment of the text relative to the horizontal offset, one of `left`, `center`, or `right`. Default is `left`. aligny +: {{< new-in 0.147.0 />}} : (`string`) The vertical alignment of the text relative to the vertical offset, one of `top`, `center`, or `bottom`. Default is `top`. color @@ -74,6 +75,7 @@ Create the filter, centering the text horizontally and vertically: {{ with $r = resources.Get $imagePath }} {{ $opts := dict "alignx" "center" + "aligny" "center" "color" "#fbfaf5" "font" $font "linespacing" 8 diff --git a/docs/content/en/functions/js/Build.md b/docs/content/en/functions/js/Build.md index 1bec6b16f..d55220a52 100644 --- a/docs/content/en/functions/js/Build.md +++ b/docs/content/en/functions/js/Build.md @@ -20,18 +20,18 @@ The `js.Build` function uses the [evanw/esbuild] package to: ```go-html-template {{ with resources.Get "js/main.js" }} - {{ $opts := dict - "minify" hugo.IsProduction - "sourceMap" (cond hugo.IsProduction "" "external") + {{$opts := dict + "minify" (not hugo.IsDevelopment) + "sourceMap" (cond hugo.IsDevelopment "external" "") "targetPath" "js/main.js" }} {{ with . | js.Build $opts }} - {{ if hugo.IsProduction }} + {{ if hugo.IsDevelopment }} + <script src="{{ .RelPermalink }}"></script> + {{ else }} {{ with . | fingerprint }} <script src="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous"></script> {{ end }} - {{ else }} - <script src="{{ .RelPermalink }}"></script> {{ end }} {{ end }} {{ end }} diff --git a/docs/content/en/functions/lang/Merge.md b/docs/content/en/functions/lang/Merge.md index db40c2669..f2ce16011 100644 --- a/docs/content/en/functions/lang/Merge.md +++ b/docs/content/en/functions/lang/Merge.md @@ -24,6 +24,6 @@ A more practical example is to fill in the missing translations from the other l ```sh {{ $pages := .Site.RegularPages }} {{ range .Site.Home.Translations }} -{{ $pages = $pages | lang.Merge .Site.RegularPages }} + {{ $pages = $pages | lang.Merge .Site.RegularPages }} {{ end }} ``` diff --git a/docs/content/en/functions/math/Counter.md b/docs/content/en/functions/math/Counter.md index 16456cec6..eec4df8b3 100644 --- a/docs/content/en/functions/math/Counter.md +++ b/docs/content/en/functions/math/Counter.md @@ -12,14 +12,14 @@ params: The counter is global for both monolingual and multilingual sites, and its initial value for each build is 1. -```go-html-template -{{ warnf "single.html called %d times" math.Counter }} +```go-html-template {file="layouts/page.html"} +{{ warnf "page.html called %d times" math.Counter }} ``` -```sh -WARN single.html called 1 times -WARN single.html called 2 times -WARN single.html called 3 times +```text +WARN page.html called 1 times +WARN page.html called 2 times +WARN page.html called 3 times ``` Use this function to: diff --git a/docs/content/en/functions/math/MaxInt64.md b/docs/content/en/functions/math/MaxInt64.md new file mode 100644 index 000000000..ee4f68ffd --- /dev/null +++ b/docs/content/en/functions/math/MaxInt64.md @@ -0,0 +1,27 @@ +--- +title: math.MaxInt64 +description: Returns the maximum value for a signed 64-bit integer. +categories: [] +keywords: [] +params: + functions_and_methods: + aliases: [] + returnType: int64 + signatures: [math.MaxInt64] +--- + +{{< new-in 0.147.3 />}} + +```go-html-template +{{ math.MaxInt64 }} → 9223372036854775807 +``` + +This function is helpful for simulating a loop that continues indefinitely until a break condition is met. For example: + +```go-html-template +{{ range math.MaxInt64 }} + {{ if eq . 42 }} + {{ break }} + {{ end }} +{{ end }} +``` diff --git a/docs/content/en/functions/openapi3/Unmarshal.md b/docs/content/en/functions/openapi3/Unmarshal.md index d1f928aeb..ca2ee93e3 100644 --- a/docs/content/en/functions/openapi3/Unmarshal.md +++ b/docs/content/en/functions/openapi3/Unmarshal.md @@ -39,7 +39,7 @@ To inspect the data structure: To list the GET and POST operations for each of the API paths: ```go-html-template -{{ range $path, $details := $api.Paths }} +{{ range $path, $details := $api.Paths.Map }} <p>{{ $path }}</p> <dl> {{ with $details.Get }} @@ -54,6 +54,11 @@ To list the GET and POST operations for each of the API paths: {{ end }} ``` +> [!warning] +> The unmarshaled data structure is created with [`kin-openapi`](https://github.com/getkin/kin-openapi). Many fields are structs or pointers (not maps), and therefore require accessors or other methods for indexing and iteration. +> For example, prior to [`kin-openapi` v0.122.0](https://github.com/getkin/kin-openapi#v01220) / [Hugo v0.121.0](https://github.com/gohugoio/hugo/releases/tag/v0.121.0), `Paths` was a map (so `.Paths` was iterable) and it is now a pointer (and requires the `.Paths.Map` accessor, as in the example above). +> See the [`kin-openapi` godoc for OpenAPI 3](https://pkg.go.dev/github.com/getkin/kin-openapi/openapi3) for full type definitions. + Hugo renders this to: ```html diff --git a/docs/content/en/functions/partials/Include.md b/docs/content/en/functions/partials/Include.md index eb7eeafdc..0474bf77f 100644 --- a/docs/content/en/functions/partials/Include.md +++ b/docs/content/en/functions/partials/Include.md @@ -19,7 +19,7 @@ In this example we have three partial templates: ```text layouts/ -└── partials/ +└── _partials/ ├── average.html ├── breadcrumbs.html └── footer.html diff --git a/docs/content/en/functions/partials/IncludeCached.md b/docs/content/en/functions/partials/IncludeCached.md index 3905ee15e..9bf1d5384 100644 --- a/docs/content/en/functions/partials/IncludeCached.md +++ b/docs/content/en/functions/partials/IncludeCached.md @@ -16,7 +16,7 @@ Without a [`return`] statement, the `partialCached` function returns a string of The `partialCached` function can offer significant performance gains for complex templates that don't need to be re-rendered on every invocation. > [!note] -> Each Site (or language) has its own `partialCached` cache, so each site will execute a partial once. +> Each site (or language) has its own `partialCached` cache, so each site will execute a partial once. > > Hugo renders pages in parallel, and will render the partial more than once with concurrent calls to the `partialCached` function. After Hugo caches the rendered partial, new pages entering the build pipeline will use the cached result. @@ -28,7 +28,7 @@ Here is the simplest usage: Pass additional arguments to `partialCached` to create variants of the cached partial. For example, if you have a complex partial that should be identical when rendered for pages within the same section, use a variant based on section so that the partial is only rendered once per section: -```go-html-template {file="layouts/_default/baseof.html"} +```go-html-template {file="layouts/baseof.html"} {{ partialCached "footer.html" . .Section }} ``` diff --git a/docs/content/en/functions/resources/FromString.md b/docs/content/en/functions/resources/FromString.md index 4cd04f609..bd2d894b1 100644 --- a/docs/content/en/functions/resources/FromString.md +++ b/docs/content/en/functions/resources/FromString.md @@ -22,9 +22,9 @@ Let's say you need to publish a file named "site.json" in the root of your `publ ```json { - "build_date": "2025-01-16T19:14:41-08:00", - "hugo_version": "0.141.0", - "last_modified": "2025-01-16T19:14:46-08:00" + "build_date": "2025-05-03T19:14:41-08:00", + "hugo_version": "0.147.9", + "last_modified": "2025-05-03T19:14:46-08:00" } ``` diff --git a/docs/content/en/functions/templates/Current.md b/docs/content/en/functions/templates/Current.md index 805aeec05..d2c2c9609 100644 --- a/docs/content/en/functions/templates/Current.md +++ b/docs/content/en/functions/templates/Current.md @@ -47,7 +47,7 @@ debug = true To visually mark where a template begins and ends execution: -```go-html-template {file="layouts/_default/single.html"} +```go-html-template {file="layouts/page.html"} {{ define "main" }} {{ if site.Params.debug }} <div class="debug">[entering {{ templates.Current.Filename }}]</div> @@ -66,7 +66,7 @@ To visually mark where a template begins and ends execution: To display the chain of templates that led to the current one, create a partial template that iterates through its ancestors: -```go-html-template {file="layouts/partials/template-call-stack.html" copy=true} +```go-html-template {file="layouts/_partials/template-call-stack.html" copy=true} {{ with templates.Current }} <div class="debug"> {{ range .Ancestors }} @@ -81,7 +81,7 @@ To display the chain of templates that led to the current one, create a partial Then call the partial from any template: -```go-html-template {file="layouts/partials/footer/copyright.html" copy=true} +```go-html-template {file="layouts/_partials/footer/copyright.html" copy=true} {{ if site.Params.debug }} {{ partial "template-call-stack.html" . }} {{ end }} @@ -90,15 +90,15 @@ Then call the partial from any template: The rendered template stack would look something like this: ```text -/home/user/project/layouts/partials/footer/copyright.html -/home/user/project/themes/foo/layouts/partials/footer.html -/home/user/project/layouts/_default/single.html -/home/user/project/themes/foo/layouts/_default/baseof.html +/home/user/project/layouts/_partials/footer/copyright.html +/home/user/project/themes/foo/layouts/_partials/footer.html +/home/user/project/layouts/page.html +/home/user/project/themes/foo/layouts/baseof.html ``` To reverse the order of the entries, chain the `Reverse` method to the `Ancestors` method: -```go-html-template {file="layouts/partials/template-call-stack.html" copy=true} +```go-html-template {file="layouts/_partials/template-call-stack.html" copy=true} {{ with templates.Current }} <div class="debug"> {{ range .Ancestors.Reverse }} @@ -115,7 +115,7 @@ To reverse the order of the entries, chain the `Reverse` method to the `Ancestor To render links that, when clicked, will open the template in Microsoft Visual Studio Code, create a partial template with anchor elements that use the `vscode` URI scheme: -```go-html-template {file="layouts/partials/template-open-in-vs-code.html" copy=true} +```go-html-template {file="layouts/_partials/template-open-in-vs-code.html" copy=true} {{ with templates.Current.Parent }} <div class="debug"> <a href="vscode://file/{{ .Filename }}">{{ .Name }}</a> @@ -128,7 +128,7 @@ To render links that, when clicked, will open the template in Microsoft Visual S Then call the partial from any template: -```go-html-template {file="layouts/_default/single.html" copy=true} +```go-html-template {file="layouts/page.html" copy=true} {{ define "main" }} <h1>{{ .Title }}</h1> {{ .Content }} @@ -141,7 +141,7 @@ Then call the partial from any template: Use the same approach to render the entire call stack as links: -```go-html-template {file="layouts/partials/template-call-stack.html" copy=true} +```go-html-template {file="layouts/_partials/template-call-stack.html" copy=true} {{ with templates.Current }} <div class="debug"> {{ range .Ancestors }} diff --git a/docs/content/en/functions/templates/Defer.md b/docs/content/en/functions/templates/Defer.md index 6a9ca56ae..16c32724e 100644 --- a/docs/content/en/functions/templates/Defer.md +++ b/docs/content/en/functions/templates/Defer.md @@ -14,33 +14,34 @@ aliases: [/functions/templates.defer] {{< new-in 0.128.0 />}} > [!note] -> This feature is meant to be used in the main page layout files/templates, and has undefined behavior when used from shortcodes, partials or render hook templates. See [this issue](https://github.com/gohugoio/hugo/issues/13492#issuecomment-2734700391) for more info. +> This feature should only be used in the main page template, typically `layouts/baseof.html`. Using it in shortcodes, partials, or render hook templates may lead to unpredictable results. For further details, please refer to [this issue]. + +[this issue]: https://github.com/gohugoio/hugo/issues/13492#issuecomment-2734700391 In some rare use cases, you may need to defer the execution of a template until after all sites and output formats have been rendered. One such example could be [TailwindCSS](/functions/css/tailwindcss/) using the output of [hugo_stats.json](/configuration/build/) to determine which classes and other HTML identifiers are being used in the final output: -```go-html-template -{{ with (templates.Defer (dict "key" "global")) }} - {{ $t := debug.Timer "tailwindcss" }} - {{ with resources.Get "css/styles.css" }} - {{ $opts := dict - "inlineImports" true - "optimize" hugo.IsProduction - }} - {{ with . | css.TailwindCSS $opts }} - {{ if hugo.IsDevelopment }} - <link rel="stylesheet" href="{{ .RelPermalink }}" /> - {{ else }} - {{ with . | minify | fingerprint }} - <link - rel="stylesheet" - href="{{ .RelPermalink }}" - integrity="{{ .Data.Integrity }}" - crossorigin="anonymous" /> - {{ end }} +```go-html-template {file="layouts/baseof.html" copy=true} +<head> + ... + {{ with (templates.Defer (dict "key" "global")) }} + {{ partial "css.html" . }} + {{ end }} + ... +</head> +``` + +```go-html-template {file="layouts/_partials/css.html" copy=true} +{{ with resources.Get "css/main.css" }} + {{ $opts := dict "minify" (not hugo.IsDevelopment) }} + {{ with . | css.TailwindCSS $opts }} + {{ if hugo.IsDevelopment }} + <link rel="stylesheet" href="{{ .RelPermalink }}"> + {{ else }} + {{ with . | fingerprint }} + <link rel="stylesheet" href="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous"> {{ end }} {{ end }} {{ end }} - {{ $t.Stop }} {{ end }} ``` @@ -52,19 +53,23 @@ In some rare use cases, you may need to defer the execution of a template until For the above to work well when running the server (or `hugo -w`), you want to have a configuration similar to this: {{< code-toggle file=hugo >}} +[build] + [build.buildStats] + enable = true + [[build.cachebusters]] + source = 'assets/notwatching/hugo_stats\.json' + target = 'css' + [[build.cachebusters]] + source = '(postcss|tailwind)\.config\.js' + target = 'css' [module] -[[module.mounts]] -source = "hugo_stats.json" -target = "assets/notwatching/hugo_stats.json" -disableWatch = true -[build.buildStats] -enable = true -[[build.cachebusters]] -source = "assets/notwatching/hugo_stats\\.json" -target = "styles\\.css" -[[build.cachebusters]] -source = "(postcss|tailwind)\\.config\\.js" -target = "css" + [[module.mounts]] + source = 'assets' + target = 'assets' + [[module.mounts]] + disableWatch = true + source = 'hugo_stats.json' + target = 'assets/notwatching/hugo_stats.json' {{< /code-toggle >}} ## Options diff --git a/docs/content/en/functions/templates/Exists.md b/docs/content/en/functions/templates/Exists.md index 79fc561c8..a8d627ff7 100644 --- a/docs/content/en/functions/templates/Exists.md +++ b/docs/content/en/functions/templates/Exists.md @@ -17,7 +17,7 @@ Use the `templates.Exists` function with dynamic template paths: ```go-html-template {{ $partialPath := printf "headers/%s.html" .Type }} -{{ if templates.Exists ( printf "partials/%s" $partialPath ) }} +{{ if templates.Exists ( printf "_partials/%s" $partialPath ) }} {{ partial $partialPath . }} {{ else }} {{ partial "headers/default.html" . }} diff --git a/docs/content/en/functions/transform/ToMath.md b/docs/content/en/functions/transform/ToMath.md index a9f12c546..0beb8f56a 100644 --- a/docs/content/en/functions/transform/ToMath.md +++ b/docs/content/en/functions/transform/ToMath.md @@ -6,7 +6,7 @@ keywords: [] params: functions_and_methods: aliases: [] - returnType: types.Result[template.HTML] + returnType: template.HTML signatures: ['transform.ToMath INPUT [OPTIONS]'] aliases: [/functions/tomath] --- @@ -58,12 +58,25 @@ minRuleThickness : (`float`) The minimum thickness of the fraction lines in `em`. Default is `0.04`. output -: (`string`). Determines the markup language of the output, one of `html`, `mathml`, or `htmlAndMathml`. Default is `mathml`. +: (`string`) Determines the markup language of the output, one of `html`, `mathml`, or `htmlAndMathml`. Default is `mathml`. With `html` and `htmlAndMathml` you must include the KaTeX style sheet within the `head` element of your base template. ```html - <link href="https://cdn.jsdelivr.net/npm/katex@0.16.21/dist/katex.min.css" rel="stylesheet"> + <link href="https://cdn.jsdelivr.net/npm/katex@0.16.22/dist/katex.min.css" rel="stylesheet"> + +strict +: {{< new-in 0.147.6 />}} +: (`string`) Controls how KaTeX handles LaTeX features that offer convenience but aren't officially supported, one of `error`, `ignore`, or `warn`. Default is `error`. + + - `error`: Throws an error when convenient, unsupported LaTeX features are encountered. + - `ignore`: Allows convenient, unsupported LaTeX features without any feedback. + - `warn`: {{< new-in 0.147.7 />}} Emits a warning when convenient, unsupported LaTeX features are encountered. + +: The `newLineInDisplayMode` error code, which flags the use of `\\` +or `\newline` in display mode outside an array or tabular environment, is +intentionally designed not to throw an error, despite this behavior +being questionable. throwOnError : (`bool`) Whether to throw a `ParseError` when KaTeX encounters an unsupported command or invalid LaTeX. Default is `true`. @@ -96,13 +109,13 @@ inline = [['\(', '\)']] {{< /code-toggle >}} > [!note] -> The configuration above precludes the use of the `$...$` delimiter pair for inline equations. Although you can add this delimiter pair to the configuration, you will need to double-escape the `$` symbol when used outside of math contexts to avoid unintended formatting. +> The configuration above precludes the use of the `$...$` delimiter pair for inline equations. Although you can add this delimiter pair to the configuration, you must double-escape the `$` symbol when used outside of math contexts to avoid unintended formatting. ### Step 2 Create a [passthrough render hook] to capture and render the LaTeX markup. -```go-html-template {file="layouts/_default/_markup/render-passthrough.html" copy=true} +```go-html-template {file="layouts/_markup/render-passthrough.html" copy=true} {{- $opts := dict "output" "htmlAndMathml" "displayMode" (eq .Type "block") }} {{- with try (transform.ToMath .Inner $opts) }} {{- with .Err }} @@ -118,11 +131,11 @@ Create a [passthrough render hook] to capture and render the LaTeX markup. In your base template, conditionally include the KaTeX CSS within the head element. -```go-html-template {file="layouts/_default/baseof.html" copy=true} +```go-html-template {file="layouts/baseof.html" copy=true} <head> {{ $noop := .WordCount }} {{ if .Page.Store.Get "hasMath" }} - <link href="https://cdn.jsdelivr.net/npm/katex@0.16.21/dist/katex.min.css" rel="stylesheet"> + <link href="https://cdn.jsdelivr.net/npm/katex@0.16.22/dist/katex.min.css" rel="stylesheet"> {{ end }} </head> ``` diff --git a/docs/content/en/functions/transform/Unmarshal.md b/docs/content/en/functions/transform/Unmarshal.md index 93168294c..8b2173b9b 100644 --- a/docs/content/en/functions/transform/Unmarshal.md +++ b/docs/content/en/functions/transform/Unmarshal.md @@ -180,7 +180,7 @@ To render an HTML table from a CSV file: To extract a subset of the data, or to sort the data, unmarshal to a map instead of a slice: ```go-html-template -{{ $data := slice }} +{{ $data := dict }} {{ $file := "pets.csv" }} {{ with or (.Resources.Get $file) (resources.Get $file) }} {{ $opts := dict "targetType" "map" }} diff --git a/docs/content/en/functions/transform/XMLEscape.md b/docs/content/en/functions/transform/XMLEscape.md index 9e6c77927..372ad9b6a 100644 --- a/docs/content/en/functions/transform/XMLEscape.md +++ b/docs/content/en/functions/transform/XMLEscape.md @@ -31,7 +31,7 @@ For example: When using `transform.XMLEscape` in a template rendered by Go's [html/template] package, declare the string to be safe HTML to avoid double escaping. For example, in an RSS template: -```xml {file="layouts/_default/rss.xml"} +```xml {file="layouts/rss.xml"} <description>{{ .Summary | transform.XMLEscape | safeHTML }}</description> ``` diff --git a/docs/content/en/getting-started/external-learning-resources/index.md b/docs/content/en/getting-started/external-learning-resources/index.md index 7838b6810..f36544c02 100644 --- a/docs/content/en/getting-started/external-learning-resources/index.md +++ b/docs/content/en/getting-started/external-learning-resources/index.md @@ -62,7 +62,7 @@ This course covers the basics of using the Hugo static site generator. Work your 1. [Content Organization](https://www.giraffeacademy.com/static-site-generators/hugo/content-organization/) 1. [Front Matter](https://www.giraffeacademy.com/static-site-generators/hugo/front-matter/) 1. [Archetypes](https://www.giraffeacademy.com/static-site-generators/hugo/archetypes/) -1. [Shortcodes](https://www.giraffeacademy.com/static-site-generators/hugo/archetypes/) +1. [Shortcodes](https://www.giraffeacademy.com/static-site-generators/hugo/shortcodes/) 1. [Taxonomies](https://www.giraffeacademy.com/static-site-generators/hugo/taxonomies/) 1. [Template Basics](https://www.giraffeacademy.com/static-site-generators/hugo/introduction-to-templates/) 1. [List Page Templates](https://www.giraffeacademy.com/static-site-generators/hugo/list-page-templates/) diff --git a/docs/content/en/host-and-deploy/host-on-aws-amplify/index.md b/docs/content/en/host-and-deploy/host-on-aws-amplify/index.md index aadb89116..e2b35dbbe 100644 --- a/docs/content/en/host-and-deploy/host-on-aws-amplify/index.md +++ b/docs/content/en/host-and-deploy/host-on-aws-amplify/index.md @@ -44,9 +44,9 @@ version: 1 env: variables: # Application versions - DART_SASS_VERSION: 1.85.0 - GO_VERSION: 1.23.3 - HUGO_VERSION: 0.144.2 + DART_SASS_VERSION: 1.89.2 + GO_VERSION: 1.24.2 + HUGO_VERSION: 0.147.9 # Time zone TZ: America/Los_Angeles # Cache diff --git a/docs/content/en/host-and-deploy/host-on-codeberg-pages.md b/docs/content/en/host-and-deploy/host-on-codeberg-pages.md index cd137c420..2a881f718 100644 --- a/docs/content/en/host-and-deploy/host-on-codeberg-pages.md +++ b/docs/content/en/host-and-deploy/host-on-codeberg-pages.md @@ -51,9 +51,11 @@ git remote add origin https://codeberg.org/<YourUsername>/pages.git git push -u origin main ``` -## Automated deployment +## Automated deployment using Woodpecker CI -In order to automatically deploy your Hugo website, you need to have or [request] access to Codeberg's CI, as well as add a `.woodpecker.yaml` file in the root of your project. A template and additional instructions are available in the official [examples repository]. +There are two methods you can use to deploy your Hugo website to Codeberg automatically. These are: Woodpecker CI and Forgejo Actions. + +To use Codeberg's Woodpecker CI, you need to have or [request] access to it, as well as add a `.woodpecker.yaml` file in the root of your project. A template and additional instructions are available in the official [examples repository]. [request]: https://codeberg.org/Codeberg-e.V./requests/issues/new?template=ISSUE_TEMPLATE%2fWoodpecker-CI.yaml [examples repository]: https://codeberg.org/Codeberg-CI/examples/src/branch/main/Hugo/.woodpecker.yaml @@ -74,7 +76,178 @@ git remote add origin https://codeberg.org/<YourUsername>/<YourWebsite>.git git push -u origin main ``` -Your project will then be built and deployed by Codeberg's CI. +Your project will then be built and deployed by Codeberg's Woodpecker CI. + +## Automated deployment using Forgejo Actions + +The other way to deploy your website to Codeberg pages automatically is to make use of Forgejo Actions. Actions need a _runner_ to work, and Codeberg has [great documentation] on how to set one up yourself. However, Codeberg provides a [handful of humble runners] themselves (they say this feature is in "open alpha"), which actually seem powerful enough to build at least relatively simple websites. + +[great documentation]: https://docs.codeberg.org/ci/actions/ +[handful of humble runners]: https://codeberg.org/actions/meta + +To deploy your website this way, you don't need to request any access. All you need to do is enable actions in your repository settings (see the documentation link above) and add a workflow configuration file, for example, `hugo.yaml`, to the `.forgejo/workflows/` directory in your website's source repository. + +Two examples of such a file are provided below. + +The first file should work for automatically building your website from the source branch (`main` in this case) and committing the result to the target branch (`pages`). Without changes, this file should make your built website accessible under `https://<YourUsername>.codeberg.page/<YourWebsiteRepositoryName>/`: + +```yaml {file=".forgejo/workflows/hugo.yaml" copy=true} +name: Deploy Hugo site to Pages + +on: + # Runs on pushes targeting the default branch + push: + branches: + # If you want to build from a different branch, change it here. + - main + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +jobs: + build: + # You can find the list of available runners on https://codeberg.org/actions/meta, or run one yourself. + runs-on: codeberg-tiny-lazy + container: + # Specify "hugomods/hugo:exts" if you want to always use the latest version of Hugo for building. + image: "hugomods/hugo:exts-0.147.9" + steps: + - name: Clone the repository + uses: https://code.forgejo.org/actions/checkout@v4 + with: + submodules: recursive + fetch-depth: 0 + - name: Generate static files with Hugo + env: + # For maximum backward compatibility with Hugo modules + HUGO_ENVIRONMENT: production + HUGO_ENV: production + run: | + hugo \ + --gc \ + --minify + - name: Upload generated files + uses: https://code.forgejo.org/actions/upload-artifact@v3 + with: + name: Generated files + path: public/ + deploy: + needs: [ build ] + runs-on: codeberg-tiny-lazy + steps: + - name: Clone the repository + uses: https://code.forgejo.org/actions/checkout@v4 + with: + submodules: recursive + fetch-depth: 0 + - name: Checkout the target branch and clean it up + # If you want to commit to a branch other than "pages", change the two references below, as well as the reference in the last step. + run: | + git checkout pages || git switch --orphan pages && \ + rm -Rfv $(ls -A | egrep -v '^(\.git|LICENSE)$') + - name: Download generated files + uses: https://code.forgejo.org/actions/download-artifact@v3 + with: + name: Generated files + - name: Publish the website + run: | + git config user.email codeberg-ci && \ + git config user.name "Codeberg CI" && \ + git add . && \ + git commit --allow-empty --message "Codeberg build for ${GITHUB_SHA}" && \ + git push origin pages +``` + +The second file implements a more complex scenario: having your website sources in one repository and the resulting static website in another repository (in this case, `pages`). If you want Codeberg to make your website available at the root of your pages subdomain (`https://<YourUsername>.codeberg.page/`), you have to push that website to the default branch of your repository named `pages`. + +Since this action involves more than one repository, it will require a bit more preparation: +1. Create the target repository. Name it `pages`. +2. Generate a new SSH key. *Do not* use any of your own SSH keys for this, but generate one for this specific task only. On Linux, BSD, and, likely, other operating systems, you can open a terminal emulator and run the following command to generate the key: + ```shell + ssh-keygen -f pagesbuild -P "" + ``` + This will generate two files in your current directory: `pagesbuild` (private key) and `pagesbuild.pub` (public key). +3. Add the newly generated public key as a deploy key to your `pages` repository: navigate to its Settings, click on "Deploy keys" in the left menu, click the "Add deploy key" button, give it a name (e.g. "Actions deploy key"), paste the contents of the **public** key file (`pagesbuild.pub`) to the Content field, tick the "Enable write access" checkbox, then submit the form. +4. Navigate back to your source repository settings, expand the "Actions" menu and click on "Secrets". Then click "Add Secret", enter "DEPLOY_KEY" as the secret name and paste the contents of the newly generated **private** key file (`pagesbuild`) into the Value field. +5. Navigate to the "Variables" submenu of the "Actions" menu and add the following variables: + + | Name | Value | + |---------------------|----------------------------------------------------------------------------------| + | `TARGET_REPOSITORY` | `<YourUsername>/pages` | + | `TARGET_BRANCH` | `main` (enter the default branch name of the `pages` repo here) | + | `SSH_KNOWN_HOSTS` | (paste the output you get by running `ssh-keyscan codeberg.org` in the terminal) | + +Once you've done all of the above, commit the following file to your repository as `.forgejo/workflows/hugo.yaml`. As you can see, the `deploy` job of this workflow is slightly different from the file above: + +```yaml {file=".forgejo/workflows/hugo.yaml" copy=true} +name: Deploy Hugo site to Pages + +on: + # Runs on pushes targeting the default branch + push: + branches: + # If you want to build from a different branch, change it here. + - main + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +jobs: + build: + runs-on: codeberg-tiny-lazy + container: + # Specify "hugomods/hugo:exts" if you want to always use the latest version of Hugo for building. + image: "hugomods/hugo:exts-0.147.9" + steps: + - name: Clone the repository + uses: https://code.forgejo.org/actions/checkout@v4 + with: + submodules: recursive + fetch-depth: 0 + - name: Generate static files with Hugo + env: + # For maximum backward compatibility with Hugo modules + HUGO_ENVIRONMENT: production + HUGO_ENV: production + run: | + hugo \ + --gc \ + --minify \ + --source ${PWD} \ + --destination ${PWD}/public/ + - name: Upload generated files + uses: https://code.forgejo.org/actions/upload-artifact@v3 + with: + name: Generated files + path: public/ + deploy: + needs: [ build ] + runs-on: codeberg-tiny-lazy + steps: + - name: Clone the repository + uses: https://code.forgejo.org/actions/checkout@v4 + with: + repository: ${{ vars.TARGET_REPOSITORY }} + ref: ${{ vars.TARGET_BRANCH }} + submodules: recursive + fetch-depth: 0 + ssh-key: ${{ secrets.DEPLOY_KEY }} + ssh-known-hosts: ${{ vars.SSH_KNOWN_HOSTS }} + - name: Remove all files + run: | + rm -Rfv $(ls -A | egrep -v '^(\.git|LICENSE)$') + - name: Download generated files + uses: https://code.forgejo.org/actions/download-artifact@v3 + with: + name: Generated files + - name: Commit and push the website + run: | + git config user.email codeberg-ci && \ + git config user.name "Codeberg CI" && \ + git add -v . && \ + git commit -v --allow-empty --message "Codeberg build for ${GITHUB_SHA}" && \ + git push -v origin ${{ vars.TARGET_BRANCH }} +``` + +Once you commit one of the two files to your website source repository, you should see your first automated build firing up pretty soon. You can also trigger it manually by navigating to the **Actions** section of your repository web page, choosing **hugo.yaml** on the left and clicking on **Run workflow**. ## Other resources diff --git a/docs/content/en/host-and-deploy/host-on-github-pages/index.md b/docs/content/en/host-and-deploy/host-on-github-pages/index.md index 7c3201099..165c9934c 100644 --- a/docs/content/en/host-and-deploy/host-on-github-pages/index.md +++ b/docs/content/en/host-and-deploy/host-on-github-pages/index.md @@ -107,7 +107,8 @@ jobs: build: runs-on: ubuntu-latest env: - HUGO_VERSION: 0.145.0 + DART_SASS_VERSION: 1.89.2 + HUGO_VERSION: 0.147.9 HUGO_ENVIRONMENT: production TZ: America/Los_Angeles steps: @@ -116,7 +117,11 @@ jobs: wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb \ && sudo dpkg -i ${{ runner.temp }}/hugo.deb - name: Install Dart Sass - run: sudo snap install dart-sass + run: | + wget -O ${{ runner.temp }}/dart-sass.tar.gz https://github.com/sass/dart-sass/releases/download/${DART_SASS_VERSION}/dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz \ + && tar -xf ${{ runner.temp }}/dart-sass.tar.gz --directory ${{ runner.temp }} \ + && mv ${{ runner.temp }}/dart-sass/ /usr/local/bin \ + && echo "/usr/local/bin/dart-sass" >> $GITHUB_PATH - name: Checkout uses: actions/checkout@v4 with: diff --git a/docs/content/en/host-and-deploy/host-on-gitlab-pages.md b/docs/content/en/host-and-deploy/host-on-gitlab-pages.md index 4750b0ff3..cf4220888 100644 --- a/docs/content/en/host-and-deploy/host-on-gitlab-pages.md +++ b/docs/content/en/host-and-deploy/host-on-gitlab-pages.md @@ -23,17 +23,18 @@ Define your [CI/CD](g) jobs by creating a `.gitlab-ci.yml` file in the root of y ```yaml {file=".gitlab-ci.yml" copy=true} variables: - DART_SASS_VERSION: 1.87.0 + DART_SASS_VERSION: 1.89.2 GIT_DEPTH: 0 GIT_STRATEGY: clone GIT_SUBMODULE_STRATEGY: recursive - HUGO_VERSION: 0.146.7 + HUGO_VERSION: 0.147.9 NODE_VERSION: 22.x TZ: America/Los_Angeles image: name: golang:1.24.2-bookworm pages: + stage: deploy script: # Install brotli - apt-get update diff --git a/docs/content/en/host-and-deploy/host-on-netlify/index.md b/docs/content/en/host-and-deploy/host-on-netlify/index.md index 4c89a6c1e..61ac15da8 100644 --- a/docs/content/en/host-and-deploy/host-on-netlify/index.md +++ b/docs/content/en/host-and-deploy/host-on-netlify/index.md @@ -113,8 +113,8 @@ Create a new file named netlify.toml in the root of your project directory. In i ```toml {file="netlify.toml"} [build.environment] -GO_VERSION = "1.24" -HUGO_VERSION = "0.146.7" +GO_VERSION = "1.24.2" +HUGO_VERSION = "0.147.9" NODE_VERSION = "22" TZ = "America/Los_Angeles" @@ -127,9 +127,9 @@ If your site requires Dart Sass to transpile Sass to CSS, the configuration file ```toml {file="netlify.toml"} [build.environment] -DART_SASS_VERSION = "1.87.0" -GO_VERSION = "1.24" -HUGO_VERSION = "0.146.7" +DART_SASS_VERSION = "1.89.2" +GO_VERSION = "1.24.2" +HUGO_VERSION = "0.147.9" NODE_VERSION = "22" TZ = "America/Los_Angeles" diff --git a/docs/content/en/host-and-deploy/host-on-render.md b/docs/content/en/host-and-deploy/host-on-render.md index ac486fcbf..c4495c4b1 100644 --- a/docs/content/en/host-and-deploy/host-on-render.md +++ b/docs/content/en/host-and-deploy/host-on-render.md @@ -1,6 +1,6 @@ --- title: Host on Render -description: Host your on Render. +description: Host your site on Render. categories: [] keywords: [] aliases: [/hosting-and-deployment/hosting-on-render/] diff --git a/docs/content/en/methods/menu-entry/PageRef.md b/docs/content/en/methods/menu-entry/PageRef.md index 979879b03..5fc2dfcae 100644 --- a/docs/content/en/methods/menu-entry/PageRef.md +++ b/docs/content/en/methods/menu-entry/PageRef.md @@ -62,7 +62,7 @@ weight = 20 With this template code: -```go-html-template {file="layouts/partials/menu.html"} +```go-html-template {file="layouts/_partials/menu.html"} <ul> {{ range .Site.Menus.main }} <li><a href="{{ .URL }}">{{ .Name }}</a></li> @@ -83,7 +83,7 @@ In the above note that the `href` attribute of the second `anchor` element is bl With this template code: -```go-html-template {file="layouts/partials/menu.html"} +```go-html-template {file="layouts/_partials/menu.html"} <ul> {{ range .Site.Menus.main }} <li><a href="{{ or .URL .PageRef }}">{{ .Name }}</a></li> diff --git a/docs/content/en/methods/page/Data.md b/docs/content/en/methods/page/Data.md index ae0bdc57f..bb88dbde6 100644 --- a/docs/content/en/methods/page/Data.md +++ b/docs/content/en/methods/page/Data.md @@ -14,7 +14,7 @@ The `Data` method on a `Page` object returns a unique data object for each [page > [!note] > The `Data` method is only useful within [taxonomy](g) and [term](g) templates. > -> Themes that are not actively maintained may still use `.Data.Pages` in list templates. Although that syntax remains functional, use one of these methods instead: [`Pages`], [`RegularPages`], or [`RegularPagesRecursive`] +> Themes that are not actively maintained may still use `.Data.Pages` in their templates. Although that syntax remains functional, use one of these methods instead: [`Pages`], [`RegularPages`], or [`RegularPagesRecursive`] The examples that follow are based on this site configuration: diff --git a/docs/content/en/methods/page/Description.md b/docs/content/en/methods/page/Description.md index 5287aa699..7a609bb07 100644 --- a/docs/content/en/methods/page/Description.md +++ b/docs/content/en/methods/page/Description.md @@ -16,7 +16,7 @@ title = 'How to make spicy tuna hand rolls' description = 'Instructions for making spicy tuna hand rolls.' {{< /code-toggle >}} -```go-html-template {file="layouts/_default/baseof.html"} +```go-html-template {file="layouts/baseof.html"} <head> ... <meta name="description" content="{{ .Description }}"> diff --git a/docs/content/en/methods/page/Eq.md b/docs/content/en/methods/page/Eq.md index 4947a4bfa..0cfe1f1f7 100644 --- a/docs/content/en/methods/page/Eq.md +++ b/docs/content/en/methods/page/Eq.md @@ -9,9 +9,9 @@ params: signatures: [PAGE1.Eq PAGE2] --- -In this contrived example from a single template, we list all pages in the current section except for the current page. +In this contrived example we list all pages in the current section except for the current page. -```go-html-template +```go-html-template {file="layouts/page.html"} {{ $currentPage := . }} {{ range .CurrentSection.Pages }} {{ if not (.Eq $currentPage) }} diff --git a/docs/content/en/methods/page/Fragments.md b/docs/content/en/methods/page/Fragments.md index 2c0460def..1b30ac973 100644 --- a/docs/content/en/methods/page/Fragments.md +++ b/docs/content/en/methods/page/Fragments.md @@ -102,8 +102,8 @@ Hugo renders this to: > When using the `Fragments` methods within a shortcode, call the shortcode using [standard notation]. If you use [Markdown notation] the rendered shortcode is included in the creation of the fragments map, resulting in a circular loop. [`TableOfContents`]: /methods/page/tableofcontents/ -[ATX]: https://spec.commonmark.org/0.30/#atx-headings +[ATX]: https://spec.commonmark.org/current/#atx-headings [Markdown notation]: /content-management/shortcodes/#notation -[setext]: https://spec.commonmark.org/0.30/#setext-headings +[setext]: https://spec.commonmark.org/current/#setext-headings [standard notation]: /content-management/shortcodes/#notation [table of contents]: /methods/page/tableofcontents/ diff --git a/docs/content/en/methods/page/GetPage.md b/docs/content/en/methods/page/GetPage.md index 02f6888e0..7c1e45dd9 100644 --- a/docs/content/en/methods/page/GetPage.md +++ b/docs/content/en/methods/page/GetPage.md @@ -35,9 +35,9 @@ content/ └── _index.md ``` -The examples below depict the result of rendering works/paintings/the-mona-lisa.md: +The examples below depict the result of rendering `works/paintings/the-mona-lisa.md`: -```go-html-template {file="layouts/works/single.html"} +```go-html-template {file="layouts/works/page.html"} {{ with .GetPage "starry-night" }} {{ .Title }} → Starry Night {{ end }} diff --git a/docs/content/en/methods/page/GitInfo.md b/docs/content/en/methods/page/GitInfo.md index 5fde05b07..889682390 100644 --- a/docs/content/en/methods/page/GitInfo.md +++ b/docs/content/en/methods/page/GitInfo.md @@ -117,6 +117,22 @@ hugo --enableGitInfo {{ end }} ``` +###### Ancestor + +(`*source.GitInfo`) The file-filtered ancestor commit, if any. + +```go-html-template +{{ partial "inline/changelog.html" .GitInfo }} → 2023-10-09: Add tutorials + 2025-03-26: Edit GitInfo docs + +{{ define "_partials/inline/changelog.html" }} + {{ with . }} + {{ partial "inline/changelog.html" .Ancestor }} + {{ .CommitDate.Format "2006-01-02" }}: {{ .Subject }}<br> + {{ end }} +{{ end }} +``` + ## Last modified date By default, when `enableGitInfo` is `true`, the `Lastmod` method on a `Page` object returns the Git AuthorDate of the last commit that included the file. diff --git a/docs/content/en/methods/page/HasShortcode.md b/docs/content/en/methods/page/HasShortcode.md index 616b6de09..2e585da31 100644 --- a/docs/content/en/methods/page/HasShortcode.md +++ b/docs/content/en/methods/page/HasShortcode.md @@ -29,7 +29,7 @@ By example, let's use [Plotly] to render a chart: The shortcode is simple: -```go-html-template {file="layouts/shortcodes/plotly.html"} +```go-html-template {file="layouts/_shortcodes/plotly.html"} {{ $id := printf "plotly-%02d" .Ordinal }} <div id="{{ $id }}"></div> <script> @@ -39,7 +39,7 @@ The shortcode is simple: Now we can selectively load the required JavaScript on pages that call the "plotly" shortcode: -```go-html-template {file="layouts/_default/baseof.html"} +```go-html-template {file="layouts/baseof.html"} <head> ... {{ if .HasShortcode "plotly" }} diff --git a/docs/content/en/methods/page/Layout.md b/docs/content/en/methods/page/Layout.md index f9aa5b6ab..e038f3837 100644 --- a/docs/content/en/methods/page/Layout.md +++ b/docs/content/en/methods/page/Layout.md @@ -22,12 +22,13 @@ Hugo will render the page using contact.html. ```text layouts/ -└── _default/ - ├── baseof.html - ├── contact.html - ├── home.html - ├── list.html - └── single.html +├── baseof.html +├── contact.html +├── home.html +├── page.html +├── section.html +├── taxonomy.html +└── term.html ``` Although rarely used within a template, you can access the value with: diff --git a/docs/content/en/methods/page/Page.md b/docs/content/en/methods/page/Page.md index 7c7728b2f..01abb3103 100644 --- a/docs/content/en/methods/page/Page.md +++ b/docs/content/en/methods/page/Page.md @@ -11,19 +11,19 @@ params: This is a convenience method, useful within partial templates that are called from both [shortcodes](g) and page templates. -```go-html-template {file="layouts/shortcodes/foo.html"} +```go-html-template {file="layouts/_shortcodes/foo.html"} {{ partial "my-partial.html" . }} ``` When the shortcode calls the partial, it passes the current [context](g) (the dot). The context includes identifiers such as `Page`, `Params`, `Inner`, and `Name`. -```go-html-template {file="layouts/_default/single.html"} +```go-html-template {file="layouts/page.html"} {{ partial "my-partial.html" . }} ``` When the page template calls the partial, it also passes the current context (the dot). But in this case, the dot _is_ the `Page` object. -```go-html-template {file="layouts/partials/my-partial.html"} +```go-html-template {file="layouts/_partials/my-partial.html"} The page title is: {{ .Page.Title }} ``` diff --git a/docs/content/en/methods/page/Paginate.md b/docs/content/en/methods/page/Paginate.md index 0b699d6b2..7792980e6 100644 --- a/docs/content/en/methods/page/Paginate.md +++ b/docs/content/en/methods/page/Paginate.md @@ -20,13 +20,13 @@ By default, the number of elements on each pager is determined by your [site con You can invoke pagination on the [home template], [section templates], [taxonomy templates], and [term templates]. -```go-html-template {file="layouts/_default/list.html"} +```go-html-template {file="layouts/section.html"} {{ $pages := where .Site.RegularPages "Section" "articles" }} {{ $pages = $pages.ByTitle }} {{ range (.Paginate $pages 7).Pages }} <h2><a href="{{ .RelPermalink }}">{{ .Title }}</a></h2> {{ end }} -{{ template "_internal/pagination.html" . }} +{{ partial "pagination.html" . }} ``` In the example above, we: diff --git a/docs/content/en/methods/page/Paginator.md b/docs/content/en/methods/page/Paginator.md index bff7ea90c..1518ac95d 100644 --- a/docs/content/en/methods/page/Paginator.md +++ b/docs/content/en/methods/page/Paginator.md @@ -15,11 +15,11 @@ The number of elements on each pager is determined by your [site configuration]. You can invoke pagination on the [home template], [section templates], [taxonomy templates], and [term templates]. Each of these receives a collection of regular pages in [context](g). When you invoke the `Paginator` method, it paginates the page collection received in context. -```go-html-template {file="layouts/_default/list.html"} +```go-html-template {file="layouts/section.html"} {{ range .Paginator.Pages }} <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2> {{ end }} -{{ template "_internal/pagination.html" . }} +{{ partial "pagination.html" . }} ``` In the example above, the embedded pagination template creates navigation links between pagers. diff --git a/docs/content/en/methods/page/Render.md b/docs/content/en/methods/page/Render.md index 10f7f9ca5..4ee09fb6e 100644 --- a/docs/content/en/methods/page/Render.md +++ b/docs/content/en/methods/page/Render.md @@ -26,22 +26,21 @@ Although similar to the [`partial`] function, there are key differences. `Render` method|`partial` function| :--|:-- The `Page` object is automatically passed to the given template. You cannot pass additional context.| You must specify the context, allowing you to pass a combination of objects, slices, maps, and scalars. -The path to the template is determined by the [content type](g).|You must specify the path to the template, relative to the `layouts/partials` directory. +The path to the template is determined by the [content type](g).|You must specify the path to the template, relative to the `layouts/_partials` directory. Consider this layout structure: ```text layouts/ -├── _default/ -│ ├── baseof.html -│ ├── home.html -│ ├── li.html <-- used for other content types -│ ├── list.html -│ ├── single.html -│ └── summary.html -└── books/ - ├── li.html <-- used when content type is "books" - └── summary.html +├── books/ +│ └── li.html <-- used when content type is "books" +├── baseof.html +├── home.html +├── li.html <-- used for other content types +├── page.html +├── section.html +├── taxonomy.html +└── term.html ``` And this template: @@ -63,10 +62,10 @@ layouts/books/li.html For all other content types the `Render` methods calls: ```text -layouts/_default/li.html +layouts/li.html ``` See [content views] for more examples. -[content views]: /templates/content-view/ +[content views]: /templates/types/#content-view [`partial`]: /functions/partials/include/ diff --git a/docs/content/en/methods/page/RenderShortcodes.md b/docs/content/en/methods/page/RenderShortcodes.md index d124606f0..81a78b04b 100644 --- a/docs/content/en/methods/page/RenderShortcodes.md +++ b/docs/content/en/methods/page/RenderShortcodes.md @@ -9,13 +9,11 @@ params: signatures: [PAGE.RenderShortcodes] --- -{{< new-in 0.117.0 />}} - Use this method in shortcode templates to compose a page from multiple content files, while preserving a global context for footnotes and the table of contents. For example: -```go-html-template {file="layouts/shortcodes/include.html" copy=true} +```go-html-template {file="layouts/_shortcodes/include.html" copy=true} {{ with .Get 0 }} {{ with $.Page.GetPage . }} {{- .RenderShortcodes }} diff --git a/docs/content/en/methods/page/RenderString.md b/docs/content/en/methods/page/RenderString.md index c7774774c..5f97e3576 100644 --- a/docs/content/en/methods/page/RenderString.md +++ b/docs/content/en/methods/page/RenderString.md @@ -46,4 +46,4 @@ Render with [Pandoc]: ``` [markup identifier]: /content-management/formats/#classification -[pandoc]: https://www.pandoc.org/ +[pandoc]: https://pandoc.org/ diff --git a/docs/content/en/methods/page/Sitemap.md b/docs/content/en/methods/page/Sitemap.md index bb1360493..3a4f2ad62 100644 --- a/docs/content/en/methods/page/Sitemap.md +++ b/docs/content/en/methods/page/Sitemap.md @@ -58,7 +58,7 @@ changeFreq = 'hourly' And this simplistic sitemap template: -```xml {file="layouts/_default/sitemap.xml"} +```xml {file="layouts/sitemap.xml"} {{ printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>" | safeHTML }} <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml"> diff --git a/docs/content/en/methods/page/TableOfContents.md b/docs/content/en/methods/page/TableOfContents.md index 7ec9fe614..f44d660ae 100644 --- a/docs/content/en/methods/page/TableOfContents.md +++ b/docs/content/en/methods/page/TableOfContents.md @@ -12,8 +12,8 @@ aliases: [/content-management/toc/] The `TableOfContents` method on a `Page` object returns an ordered or unordered list of the Markdown [ATX] and [setext] headings within the page content. -[atx]: https://spec.commonmark.org/0.30/#atx-headings -[setext]: https://spec.commonmark.org/0.30/#setext-headings +[atx]: https://spec.commonmark.org/current/#atx-headings +[setext]: https://spec.commonmark.org/current/#setext-headings This template code: diff --git a/docs/content/en/methods/page/Title.md b/docs/content/en/methods/page/Title.md index dae4ba6dd..2201266a7 100644 --- a/docs/content/en/methods/page/Title.md +++ b/docs/content/en/methods/page/Title.md @@ -19,7 +19,16 @@ title = 'About us' {{ .Title }} → About us ``` -With section, taxonomy, and term pages not backed by a file, the `Title` method returns the section name, capitalized and pluralized. You can disable these transformations by setting [`capitalizeListTitles`] and [`pluralizeListTitles`] in your site configuration. For example: +When a page is not backed by a file, the value returned by the `Title` method depends on the page [kind](g). + +Page kind|Page title when the page is not backed by a file +:--|:-- +home|site title +section|section name (capitalized and pluralized) +taxonomy|taxonomy name (capitalized and pluralized) +term|term name (capitalized and pluralized) + +You can disable automatic capitalization and pluralization in your site configuration: {{< code-toggle file=hugo >}} capitalizeListTitles = false @@ -32,8 +41,6 @@ You can change the capitalization style in your site configuration to one of `ap titleCaseStyle = "firstupper" {{< /code-toggle >}} - See [details]. +See [details]. -[`capitalizeListTitles`]: /configuration/all/#capitalizelisttitles -[`pluralizeListTitles`]: /configuration/all/#pluralizelisttitles [details]: /configuration/all/#title-case-style diff --git a/docs/content/en/methods/pager/PageGroups.md b/docs/content/en/methods/pager/PageGroups.md index 46f6d81cb..df668ddd2 100644 --- a/docs/content/en/methods/pager/PageGroups.md +++ b/docs/content/en/methods/pager/PageGroups.md @@ -24,5 +24,5 @@ Use the `PageGroups` method with any of the [grouping methods]. {{ end }} {{ end }} -{{ template "_internal/pagination.html" . }} +{{ partial "pagination.html" . }} ``` diff --git a/docs/content/en/methods/pager/Pages.md b/docs/content/en/methods/pager/Pages.md index 6e5772a48..bb5ac927a 100644 --- a/docs/content/en/methods/pager/Pages.md +++ b/docs/content/en/methods/pager/Pages.md @@ -17,5 +17,5 @@ params: <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2> {{ end }} -{{ template "_internal/pagination.html" . }} +{{ partial "pagination.html" . }} ``` diff --git a/docs/content/en/methods/pages/Related.md b/docs/content/en/methods/pages/Related.md index 22eeb4dfa..6d3859560 100644 --- a/docs/content/en/methods/pages/Related.md +++ b/docs/content/en/methods/pages/Related.md @@ -15,7 +15,7 @@ Based on front matter, Hugo uses several factors to identify content related to The argument passed to the `Related` method may be a `Page` or an options map. For example, to pass the current page: -```go-html-template {file="layouts/_default/single.html"} +```go-html-template {file="layouts/page.html"} {{ with .Site.RegularPages.Related . | first 5 }} <p>Related pages:</p> <ul> @@ -28,7 +28,7 @@ The argument passed to the `Related` method may be a `Page` or an options map. F To pass an options map: -```go-html-template {file="layouts/_default/single.html"} +```go-html-template {file="layouts/page.html"} {{ $opts := dict "document" . "indices" (slice "tags" "keywords") diff --git a/docs/content/en/methods/resource/ResourceType.md b/docs/content/en/methods/resource/ResourceType.md index 0ea9c0cf9..70dc59108 100644 --- a/docs/content/en/methods/resource/ResourceType.md +++ b/docs/content/en/methods/resource/ResourceType.md @@ -36,7 +36,7 @@ content/ With the structure above, we can range through page resources of type `page` to build content: -```go-html-template {file="layouts/lessons/single.html"} +```go-html-template {file="layouts/lessons/page.html"} {{ range .Resources.ByType "page" }} {{ .Content }} {{ end }} diff --git a/docs/content/en/methods/shortcode/Get.md b/docs/content/en/methods/shortcode/Get.md index b9c01cfc4..aef9987f0 100644 --- a/docs/content/en/methods/shortcode/Get.md +++ b/docs/content/en/methods/shortcode/Get.md @@ -24,7 +24,7 @@ This shortcode call uses positional arguments: To retrieve arguments by position: -```go-html-template {file="layouts/shortcodes/myshortcode.html"} +```go-html-template {file="layouts/_shortcodes/myshortcode.html"} {{ printf "%s %s." (.Get 0) (.Get 1) }} → Hello world. ``` @@ -38,7 +38,7 @@ This shortcode call uses named arguments: To retrieve arguments by name: -```go-html-template {file="layouts/shortcodes/myshortcode.html"} +```go-html-template {file="layouts/_shortcodes/myshortcode.html"} {{ printf "%s %s." (.Get "greeting") (.Get "firstName") }} → Hello world. ``` diff --git a/docs/content/en/methods/shortcode/Inner.md b/docs/content/en/methods/shortcode/Inner.md index cdce4c1c3..bb5a16a01 100644 --- a/docs/content/en/methods/shortcode/Inner.md +++ b/docs/content/en/methods/shortcode/Inner.md @@ -19,7 +19,7 @@ We design the **best** widgets in the world. With this shortcode: -```go-html-template {file="layouts/shortcodes/card.html"} +```go-html-template {file="layouts/_shortcodes/card.html"} <div class="card"> {{ with .Get "title" }} <div class="card-title">{{ . }}</div> @@ -51,7 +51,7 @@ Is rendered to: Let's modify the example above to pass the value returned by `Inner` through the [`RenderString`] method on the `Page` object: -```go-html-template {file="layouts/shortcodes/card.html"} +```go-html-template {file="layouts/_shortcodes/card.html"} <div class="card"> {{ with .Get "title" }} <div class="card-title">{{ . }}</div> @@ -98,7 +98,7 @@ This configuration is not unsafe if _you_ control the content. Read more about H Second, because we are rendering the entire shortcode as Markdown, we must adhere to the rules governing [indentation] and inclusion of [raw HTML blocks] as provided in the [CommonMark] specification. -```go-html-template {file="layouts/shortcodes/card.html"} +```go-html-template {file="layouts/_shortcodes/card.html"} <div class="card"> {{ with .Get "title" }} <div class="card-title">{{ . }}</div> @@ -113,8 +113,8 @@ Second, because we are rendering the entire shortcode as Markdown, we must adher The difference between this and the previous example is subtle but required. Note the change in indentation, the addition of a blank line, and removal of the `RenderString` method. ```diff ---- layouts/shortcodes/a.html -+++ layouts/shortcodes/b.html +--- layouts/_shortcodes/a.html ++++ layouts/_shortcodes/b.html @@ -1,8 +1,9 @@ <div class="card"> {{ with .Get "title" }} @@ -137,7 +137,7 @@ The difference between this and the previous example is subtle but required. Not [`strings.TrimSpace`]: /functions/strings/trimspace/ [CommonMark]: https://spec.commonmark.org/current/ [details]: /methods/page/renderstring/ -[indentation]: https://spec.commonmark.org/0.30/#indented-code-blocks +[indentation]: https://spec.commonmark.org/current/#indented-code-blocks [Markdown notation]: /content-management/shortcodes/#notation -[raw HTML blocks]: https://spec.commonmark.org/0.31.2/#html-blocks +[raw HTML blocks]: https://spec.commonmark.org/current/#html-blocks [security model]: /about/security/ diff --git a/docs/content/en/methods/shortcode/InnerDeindent.md b/docs/content/en/methods/shortcode/InnerDeindent.md index 0b8c8e2d8..3d7536b6b 100644 --- a/docs/content/en/methods/shortcode/InnerDeindent.md +++ b/docs/content/en/methods/shortcode/InnerDeindent.md @@ -35,7 +35,7 @@ In the example above, notice that the content between the opening and closing sh With this shortcode, calling `Inner` instead of `InnerDeindent`: -```go-html-template {file="layouts/shortcodes/gallery.html"} +```go-html-template {file="layouts/_shortcodes/gallery.html"} <div class="gallery"> {{ .Inner | strings.TrimSpace | .Page.RenderString }} </div> @@ -66,7 +66,7 @@ Hugo renders the Markdown to: Although technically correct per the CommonMark specification, this is not what we want. If we remove the indentation using the `InnerDeindent` method: -```go-html-template {file="layouts/shortcodes/gallery.html"} +```go-html-template {file="layouts/_shortcodes/gallery.html"} <div class="gallery"> {{ .InnerDeindent | strings.TrimSpace | .Page.RenderString }} </div> @@ -94,5 +94,5 @@ Hugo renders the Markdown to: ``` [commonmark]: https://commonmark.org/ -[indentation]: https://spec.commonmark.org/0.30/#indented-code-blocks +[indentation]: https://spec.commonmark.org/current/#indented-code-blocks [`Inner`]: /methods/shortcode/inner/ diff --git a/docs/content/en/methods/shortcode/IsNamedParams.md b/docs/content/en/methods/shortcode/IsNamedParams.md index 1e0a7f00e..c95398313 100644 --- a/docs/content/en/methods/shortcode/IsNamedParams.md +++ b/docs/content/en/methods/shortcode/IsNamedParams.md @@ -13,7 +13,7 @@ To support both positional and named arguments when calling a shortcode, use the With this shortcode template: -```go-html-template {file="layouts/shortcodes/myshortcode.html"} +```go-html-template {file="layouts/_shortcodes/myshortcode.html"} {{ if .IsNamedParams }} {{ printf "%s %s." (.Get "greeting") (.Get "firstName") }} {{ else }} diff --git a/docs/content/en/methods/shortcode/Name.md b/docs/content/en/methods/shortcode/Name.md index b5f9b6c17..c42513cb2 100644 --- a/docs/content/en/methods/shortcode/Name.md +++ b/docs/content/en/methods/shortcode/Name.md @@ -11,7 +11,7 @@ params: The `Name` method is useful for error reporting. For example, if your shortcode requires a "greeting" argument: -```go-html-template {file="layouts/shortcodes/myshortcode.html"} +```go-html-template {file="layouts/_shortcodes/myshortcode.html"} {{ $greeting := "" }} {{ with .Get "greeting" }} {{ $greeting = . }} diff --git a/docs/content/en/methods/shortcode/Ordinal.md b/docs/content/en/methods/shortcode/Ordinal.md index def0c016f..4c32705c1 100644 --- a/docs/content/en/methods/shortcode/Ordinal.md +++ b/docs/content/en/methods/shortcode/Ordinal.md @@ -24,7 +24,7 @@ This method is useful for, among other things, assigning unique element IDs when This shortcode performs error checking, then renders an HTML `img` element with a unique `id` attribute: -```go-html-template {file="layouts/shortcodes/img.html"} +```go-html-template {file="layouts/_shortcodes/img.html"} {{ $src := "" }} {{ with .Get "src" }} {{ $src = . }} diff --git a/docs/content/en/methods/shortcode/Page.md b/docs/content/en/methods/shortcode/Page.md index 774caf9fc..0fa1c9cc9 100644 --- a/docs/content/en/methods/shortcode/Page.md +++ b/docs/content/en/methods/shortcode/Page.md @@ -26,7 +26,7 @@ Calling this shortcode: We can access the front matter values using the `Page` method: -```go-html-template {file="layouts/shortcodes/book-details.html"} +```go-html-template {file="layouts/_shortcodes/book-details.html"} <ul> <li>Title: {{ .Page.Title }}</li> <li>Author: {{ .Page.Params.author }}</li> diff --git a/docs/content/en/methods/shortcode/Params.md b/docs/content/en/methods/shortcode/Params.md index f001e737f..c8252f5b1 100644 --- a/docs/content/en/methods/shortcode/Params.md +++ b/docs/content/en/methods/shortcode/Params.md @@ -15,7 +15,7 @@ When you call a shortcode using positional arguments, the `Params` method return {{</* myshortcode "Hello" "world" */>}} ``` -```go-html-template {file="layouts/shortcodes/myshortcode.html"} +```go-html-template {file="layouts/_shortcodes/myshortcode.html"} {{ index .Params 0 }} → Hello {{ index .Params 1 }} → world ``` @@ -26,7 +26,7 @@ When you call a shortcode using named arguments, the `Params` method returns a m {{</* myshortcode greeting="Hello" name="world" */>}} ``` -```go-html-template {file="layouts/shortcodes/myshortcode.html"} +```go-html-template {file="layouts/_shortcodes/myshortcode.html"} {{ .Params.greeting }} → Hello {{ .Params.name }} → world ``` diff --git a/docs/content/en/methods/shortcode/Parent.md b/docs/content/en/methods/shortcode/Parent.md index 91c445d2a..4597d1034 100644 --- a/docs/content/en/methods/shortcode/Parent.md +++ b/docs/content/en/methods/shortcode/Parent.md @@ -19,13 +19,13 @@ Welcome. Today is {{</* now */>}}. {{</* /greeting */>}} ``` -```go-html-template {file="layouts/shortcodes/greeting.html"} +```go-html-template {file="layouts/_shortcodes/greeting.html"} <div class="greeting"> {{ .Inner | strings.TrimSpace | .Page.RenderString }} </div> ``` -```go-html-template {file="layouts/shortcodes/now.html"} +```go-html-template {file="layouts/_shortcodes/now.html"} {{- $dateFormat := "January 2, 2006 15:04:05" }} {{- with .Params }} diff --git a/docs/content/en/methods/shortcode/Position.md b/docs/content/en/methods/shortcode/Position.md index 24810e825..4052a735b 100644 --- a/docs/content/en/methods/shortcode/Position.md +++ b/docs/content/en/methods/shortcode/Position.md @@ -11,7 +11,7 @@ params: The `Position` method is useful for error reporting. For example, if your shortcode requires a "greeting" argument: -```go-html-template {file="layouts/shortcodes/myshortcode.html"} +```go-html-template {file="layouts/_shortcodes/myshortcode.html"} {{ $greeting := "" }} {{ with .Get "greeting" }} {{ $greeting = . }} diff --git a/docs/content/en/methods/site/Language.md b/docs/content/en/methods/site/Language.md index 31f15b8cb..73a64e4cc 100644 --- a/docs/content/en/methods/site/Language.md +++ b/docs/content/en/methods/site/Language.md @@ -72,7 +72,7 @@ Some of the methods above are commonly used in a base template as attributes for ```go-html-template <html lang="{{ .Site.Language.LanguageCode }}" - dir="{{ or .Site.Language.LanguageDirection `ltr` }} + dir="{{ or .Site.Language.LanguageDirection `ltr` }}" > ``` diff --git a/docs/content/en/methods/site/Taxonomies.md b/docs/content/en/methods/site/Taxonomies.md index 92dc41a9b..857bfd01d 100644 --- a/docs/content/en/methods/site/Taxonomies.md +++ b/docs/content/en/methods/site/Taxonomies.md @@ -140,7 +140,7 @@ The following example displays all terms in a site's tags taxonomy: ``` This example will list all taxonomies and their terms, as well as all the content assigned to each of the terms. -```go-html-template {file="layouts/partials/all-taxonomies.html"} +```go-html-template {file="layouts/_partials/all-taxonomies.html"} {{ with .Site.Taxonomies }} {{ $numberOfTerms := 0 }} {{ range $taxonomy, $terms := . }} diff --git a/docs/content/en/quick-reference/emojis.md b/docs/content/en/quick-reference/emojis.md index 15c2e60e6..75f269730 100644 --- a/docs/content/en/quick-reference/emojis.md +++ b/docs/content/en/quick-reference/emojis.md @@ -3,6 +3,8 @@ title: Emojis description: Include emoji shortcodes in your Markdown or templates. categories: [] keywords: [] +params: + searchable: false --- ## Attribution diff --git a/docs/content/en/quick-reference/glossary/_index.md b/docs/content/en/quick-reference/glossary/_index.md index 42894c4da..8940fd73b 100644 --- a/docs/content/en/quick-reference/glossary/_index.md +++ b/docs/content/en/quick-reference/glossary/_index.md @@ -13,6 +13,7 @@ cascade: layout: single params: hide_in_this_section: true + searchable: true aliases: [/getting-started/glossary/] --- diff --git a/docs/content/en/quick-reference/glossary/content-type.md b/docs/content/en/quick-reference/glossary/content-type.md index b7ebc5be4..ce2a59e17 100644 --- a/docs/content/en/quick-reference/glossary/content-type.md +++ b/docs/content/en/quick-reference/glossary/content-type.md @@ -1,6 +1,5 @@ --- title: content type -reference: /content-management/types --- -A _content type_ is a classification of content inferred from the top-level directory name or the `type` set in [front matter](g). Pages in the root of the `content` directory, including the home page, are of type "page". Accessed via `.Page.Type` in [_templates_](g). +A _content type_ is a classification of content inferred from the top-level directory name or the `type` set in [front matter](g). Pages in the root of the `content` directory, including the home page, are of type "page". The content type is a contributing factor in the template lookup order and determines which [archetype](/content-management/archetypes/) template to use when creating new content. diff --git a/docs/content/en/quick-reference/glossary/content-view.md b/docs/content/en/quick-reference/glossary/content-view.md index 009981cb5..443a07afd 100644 --- a/docs/content/en/quick-reference/glossary/content-view.md +++ b/docs/content/en/quick-reference/glossary/content-view.md @@ -1,6 +1,6 @@ --- title: content view -reference: /templates/content-view +reference: /templates/types/#content-view --- A _content view_ is a template called with the [`Render`](/methods/page/render/) method on a `Page` object. diff --git a/docs/content/en/quick-reference/glossary/list-template.md b/docs/content/en/quick-reference/glossary/list-template.md deleted file mode 100644 index 9a12a275f..000000000 --- a/docs/content/en/quick-reference/glossary/list-template.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: list template ---- - -A _list template_ is any [_template_](g) that renders a [_list page_](g). This includes home, [_section_](g), [_taxonomy_](g), and [_term_](g) templates. diff --git a/docs/content/en/render-hooks/blockquotes.md b/docs/content/en/render-hooks/blockquotes.md index 7ba282a0a..411c6c796 100755 --- a/docs/content/en/render-hooks/blockquotes.md +++ b/docs/content/en/render-hooks/blockquotes.md @@ -53,7 +53,7 @@ Type In its default configuration, Hugo renders Markdown blockquotes according to the [CommonMark specification]. To create a render hook that does the same thing: -```go-html-template {file="layouts/_default/_markup/render-blockquote.html" copy=true} +```go-html-template {file="layouts/_markup/render-blockquote.html" copy=true} <blockquote> {{ .Text }} </blockquote> @@ -61,7 +61,7 @@ In its default configuration, Hugo renders Markdown blockquotes according to the To render a blockquote as an HTML `figure` element with an optional citation and caption: -```go-html-template {file="layouts/_default/_markup/render-blockquote.html" copy=true} +```go-html-template {file="layouts/_markup/render-blockquote.html" copy=true} <figure> <blockquote {{ with .Attributes.cite }}cite="{{ . }}"{{ end }}> {{ .Text }} @@ -126,7 +126,7 @@ The extended syntax is compatible with [Obsidian]. This blockquote render hook renders a multilingual alert if an alert designator is present, otherwise it renders a blockquote according to the CommonMark specification. -```go-html-template {file="layouts/_default/_markup/render-blockquote.html" copy=true} +```go-html-template {file="layouts/_markup/render-blockquote.html" copy=true} {{ $emojis := dict "caution" ":exclamation:" "important" ":information_source:" @@ -168,10 +168,9 @@ Although you can use one template with conditional logic as shown above, you can ```text layouts/ -└── _default/ - └── _markup/ - ├── render-blockquote-alert.html - └── render-blockquote-regular.html + └── _markup/ + ├── render-blockquote-alert.html + └── render-blockquote-regular.html ``` {{% include "/_common/render-hooks/pageinner.md" %}} diff --git a/docs/content/en/render-hooks/code-blocks.md b/docs/content/en/render-hooks/code-blocks.md index d1a01e9b0..6e0ea011f 100755 --- a/docs/content/en/render-hooks/code-blocks.md +++ b/docs/content/en/render-hooks/code-blocks.md @@ -72,7 +72,7 @@ Type In its default configuration, Hugo renders fenced code blocks by passing the code sample through the Chroma syntax highlighter and wrapping the result. To create a render hook that does the same thing: -```go-html-template {file="layouts/_default/_markup/render-codeblock.html" copy=true} +```go-html-template {file="layouts/_markup/render-codeblock.html" copy=true} {{ $result := transform.HighlightCodeBlock . }} {{ $result.Wrapped }} ``` @@ -81,16 +81,15 @@ Although you can use one template with conditional logic to control the behavior ```text layouts/ -└── _default/ - └── _markup/ - ├── render-codeblock-mermaid.html - ├── render-codeblock-python.html - └── render-codeblock.html + └── _markup/ + ├── render-codeblock-mermaid.html + ├── render-codeblock-python.html + └── render-codeblock.html ``` For example, to create a code block render hook to render [Mermaid] diagrams: -```go-html-template {file="layouts/_default/_markup/render-codeblock-mermaid.html" copy=true} +```go-html-template {file="layouts/_markup/render-codeblock-mermaid.html" copy=true} <pre class="mermaid"> {{ .Inner | htmlEscape | safeHTML }} </pre> @@ -99,7 +98,7 @@ For example, to create a code block render hook to render [Mermaid] diagrams: Then include this snippet at the _bottom_ of your base template, before the closing `body` tag: -```go-html-template {file="layouts/_default/baseof.html" copy=true} +```go-html-template {file="layouts/baseof.html" copy=true} {{ if .Store.Get "hasMermaid" }} <script type="module"> import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.esm.min.mjs'; @@ -118,10 +117,10 @@ Hugo includes an [embedded code block render hook] to render [GoAT diagrams]. [`RenderShortcodes`]: /methods/page/rendershortcodes [Chroma]: https://github.com/alecthomas/chroma/ -[code fence]: https://spec.commonmark.org/0.31.2/#code-fence +[code fence]: https://spec.commonmark.org/current/#code-fence [diagrams]: /content-management/diagrams/#mermaid-diagrams [embedded code block render hook]: {{% eturl render-codeblock-goat %}} [GoAT diagrams]: /content-management/diagrams/#goat-diagrams-ascii [highlighting options]: /functions/transform/highlight/#options -[info string]: https://spec.commonmark.org/0.31.2/#info-string +[info string]: https://spec.commonmark.org/current/#info-string [Mermaid]: https://mermaid.js.org/ diff --git a/docs/content/en/render-hooks/headings.md b/docs/content/en/render-hooks/headings.md index 89868d478..5279dff78 100755 --- a/docs/content/en/render-hooks/headings.md +++ b/docs/content/en/render-hooks/headings.md @@ -46,7 +46,7 @@ In its default configuration, Hugo renders Markdown headings according to the [C [CommonMark specification]: https://spec.commonmark.org/current/ -```go-html-template {file="layouts/_default/_markup/render-heading.html" copy=true} +```go-html-template {file="layouts/_markup/render-heading.html" copy=true} <h{{ .Level }} id="{{ .Anchor }}" {{- with .Attributes.class }} class="{{ . }}" {{- end }}> {{- .Text -}} </h{{ .Level }}> @@ -54,7 +54,7 @@ In its default configuration, Hugo renders Markdown headings according to the [C To add an anchor link to the right of each heading: -```go-html-template {file="layouts/_default/_markup/render-heading.html" copy=true} +```go-html-template {file="layouts/_markup/render-heading.html" copy=true} <h{{ .Level }} id="{{ .Anchor }}" {{- with .Attributes.class }} class="{{ . }}" {{- end }}> {{ .Text }} <a href="#{{ .Anchor }}">#</a> diff --git a/docs/content/en/render-hooks/images.md b/docs/content/en/render-hooks/images.md index a4faac672..9f8ef1efb 100755 --- a/docs/content/en/render-hooks/images.md +++ b/docs/content/en/render-hooks/images.md @@ -64,7 +64,7 @@ Title In its default configuration, Hugo renders Markdown images according to the [CommonMark specification]. To create a render hook that does the same thing: -```go-html-template {file="layouts/_default/_markup/render-image.html" copy=true} +```go-html-template {file="layouts/_markup/render-image.html" copy=true} <img src="{{ .Destination | safeURL }}" {{- with .PlainText }} alt="{{ . }}"{{ end -}} {{- with .Title }} title="{{ . }}"{{ end -}} @@ -74,7 +74,7 @@ In its default configuration, Hugo renders Markdown images according to the [Com To render standalone images within `figure` elements: -```go-html-template {file="layouts/_default/_markup/render-image.html" copy=true} +```go-html-template {file="layouts/_markup/render-image.html" copy=true} {{- if .IsBlock -}} <figure> <img src="{{ .Destination | safeURL }}" diff --git a/docs/content/en/render-hooks/introduction.md b/docs/content/en/render-hooks/introduction.md index 045d25c3d..aafebf3e6 100755 --- a/docs/content/en/render-hooks/introduction.md +++ b/docs/content/en/render-hooks/introduction.md @@ -47,25 +47,23 @@ Each render hook is a template, with one template for each supported element typ ```text layouts/ -└── _default/ - └── _markup/ - ├── render-blockquote.html - ├── render-codeblock.html - ├── render-heading.html - ├── render-image.html - ├── render-link.html - ├── render-passthrough.html - └── render-table.html + └── _markup/ + ├── render-blockquote.html + ├── render-codeblock.html + ├── render-heading.html + ├── render-image.html + ├── render-link.html + ├── render-passthrough.html + └── render-table.html ``` The template lookup order allows you to create different render hooks for each page [type](g), [kind](g), language, and [output format](g). For example: ```text layouts/ -├── _default/ -│ └── _markup/ -│ ├── render-link.html -│ └── render-link.rss.xml +├── _markup/ +│ ├── render-link.html +│ └── render-link.rss.xml ├── books/ │ └── _markup/ │ ├── render-link.html diff --git a/docs/content/en/render-hooks/links.md b/docs/content/en/render-hooks/links.md index 23f725eb7..af0a8f0dd 100755 --- a/docs/content/en/render-hooks/links.md +++ b/docs/content/en/render-hooks/links.md @@ -48,7 +48,7 @@ Title In its default configuration, Hugo renders Markdown links according to the [CommonMark specification]. To create a render hook that does the same thing: -```go-html-template {file="layouts/_default/_markup/render-link.html" copy=true} +```go-html-template {file="layouts/_markup/render-link.html" copy=true} <a href="{{ .Destination | safeURL }}" {{- with .Title }} title="{{ . }}"{{ end -}} > @@ -59,7 +59,7 @@ In its default configuration, Hugo renders Markdown links according to the [Comm To include a `rel` attribute set to `external` for external links: -```go-html-template {file="layouts/_default/_markup/render-link.html" copy=true} +```go-html-template {file="layouts/_markup/render-link.html" copy=true} {{- $u := urls.Parse .Destination -}} <a href="{{ .Destination | safeURL }}" {{- with .Title }} title="{{ . }}"{{ end -}} diff --git a/docs/content/en/render-hooks/passthrough.md b/docs/content/en/render-hooks/passthrough.md index 356a030af..ea0df8824 100755 --- a/docs/content/en/render-hooks/passthrough.md +++ b/docs/content/en/render-hooks/passthrough.md @@ -86,7 +86,7 @@ Instead of client-side JavaScript rendering of mathematical markup using MathJax [`transform.ToMath`]: /functions/transform/tomath/ -```go-html-template {file="layouts/_default/_markup/render-passthrough.html" copy=true} +```go-html-template {file="layouts/_markup/render-passthrough.html" copy=true} {{- $opts := dict "output" "htmlAndMathml" "displayMode" (eq .Type "block") }} {{- with try (transform.ToMath .Inner $opts) }} {{- with .Err }} @@ -100,7 +100,7 @@ Instead of client-side JavaScript rendering of mathematical markup using MathJax Then, in your base template, conditionally include the KaTeX CSS within the head element: -```go-html-template {file="layouts/_default/baseof.html" copy=true} +```go-html-template {file="layouts/baseof.html" copy=true} <head> {{ $noop := .WordCount }} {{ if .Page.Store.Get "hasMath" }} @@ -115,10 +115,9 @@ Although you can use one template with conditional logic as shown above, you can ```text layouts/ -└── _default/ - └── _markup/ - ├── render-passthrough-block.html - └── render-passthrough-inline.html + └── _markup/ + ├── render-passthrough-block.html + └── render-passthrough-inline.html ``` {{% include "/_common/render-hooks/pageinner.md" %}} diff --git a/docs/content/en/render-hooks/tables.md b/docs/content/en/render-hooks/tables.md index c7671aff4..619090797 100755 --- a/docs/content/en/render-hooks/tables.md +++ b/docs/content/en/render-hooks/tables.md @@ -57,7 +57,7 @@ In its default configuration, Hugo renders Markdown tables according to the [Git [GitHub Flavored Markdown specification]: https://github.github.com/gfm/#tables-extension- -```go-html-template {file="layouts/_default/_markup/render-table.html" copy=true} +```go-html-template {file="layouts/_markup/render-table.html" copy=true} <table {{- range $k, $v := .Attributes }} {{- if $v }} diff --git a/docs/content/en/shortcodes/details.md b/docs/content/en/shortcodes/details.md index 94502ac1c..421fb4e66 100755 --- a/docs/content/en/shortcodes/details.md +++ b/docs/content/en/shortcodes/details.md @@ -9,7 +9,7 @@ keywords: [] {{< new-in 0.140.0 />}} > [!note] -> To override Hugo's embedded `details` shortcode, copy the [source code] to a file with the same name in the `layouts/shortcodes` directory. +> To override Hugo's embedded `details` shortcode, copy the [source code] to a file with the same name in the `layouts/_shortcodes` directory. ## Example diff --git a/docs/content/en/shortcodes/figure.md b/docs/content/en/shortcodes/figure.md index 74af52fe7..2234bb3c5 100755 --- a/docs/content/en/shortcodes/figure.md +++ b/docs/content/en/shortcodes/figure.md @@ -7,7 +7,7 @@ keywords: [] --- > [!note] -> To override Hugo's embedded `figure` shortcode, copy the [source code] to a file with the same name in the `layouts/shortcodes` directory. +> To override Hugo's embedded `figure` shortcode, copy the [source code] to a file with the same name in the `layouts/_shortcodes` directory. ## Example diff --git a/docs/content/en/shortcodes/gist.md b/docs/content/en/shortcodes/gist.md index fd2b468ab..03314da0f 100755 --- a/docs/content/en/shortcodes/gist.md +++ b/docs/content/en/shortcodes/gist.md @@ -10,7 +10,7 @@ expiryDate: 2027-02-01 # deprecated 2025-02-01 in v0.143.0 {{< deprecated-in 0.143.0 >}} The `gist` shortcode was deprecated in version 0.143.0 and will be removed in a future release. To continue embedding GitHub Gists in your content, you'll need to create a custom shortcode: -1. Create a new file: Create a file named `gist.html` within the `layouts/shortcodes` directory. +1. Create a new file: Create a file named `gist.html` within the `layouts/_shortcodes` directory. 1. Copy the source code: Paste the [original source code]({{% eturl gist %}}) of the gist shortcode into the newly created `gist.html` file. This will allow you to maintain the functionality of embedding GitHub Gists in your content after the deprecation of the original shortcode. diff --git a/docs/content/en/shortcodes/highlight.md b/docs/content/en/shortcodes/highlight.md index 371a3d46e..de90f64f3 100755 --- a/docs/content/en/shortcodes/highlight.md +++ b/docs/content/en/shortcodes/highlight.md @@ -7,7 +7,7 @@ keywords: [highlight] --- > [!note] -> To override Hugo's embedded `highlight` shortcode, copy the [source code] to a file with the same name in the `layouts/shortcodes` directory. +> To override Hugo's embedded `highlight` shortcode, copy the [source code] to a file with the same name in the `layouts/_shortcodes` directory. > [!note] > With the Markdown [content format], the `highlight` shortcode is rarely needed because, by default, Hugo automatically applies syntax highlighting to fenced code blocks. @@ -77,7 +77,7 @@ This is some {{< highlight go "hl_inline=true, noClasses=true" >}}fmt.Println("i Given the verbosity of the example above, if you need to frequently highlight inline code snippets, create your own shortcode using a shorter name with preset options. -```go-html-template {file="layouts/shortcodes/hl.html"} +```go-html-template {file="layouts/_shortcodes/hl.html"} {{ $code := .Inner | strings.TrimSpace }} {{ $lang := or (.Get 0) "go" }} {{ $opts := dict "hl_inline" true "noClasses" true }} diff --git a/docs/content/en/shortcodes/instagram.md b/docs/content/en/shortcodes/instagram.md index 3256790c6..4ee558c00 100755 --- a/docs/content/en/shortcodes/instagram.md +++ b/docs/content/en/shortcodes/instagram.md @@ -7,7 +7,7 @@ keywords: [] --- > [!note] -> To override Hugo's embedded `instagram` shortcode, copy the [source code] to a file with the same name in the `layouts/shortcodes` directory. +> To override Hugo's embedded `instagram` shortcode, copy the [source code] to a file with the same name in the `layouts/_shortcodes` directory. ## Example diff --git a/docs/content/en/shortcodes/param.md b/docs/content/en/shortcodes/param.md index 133b2322a..1a782056f 100755 --- a/docs/content/en/shortcodes/param.md +++ b/docs/content/en/shortcodes/param.md @@ -7,7 +7,7 @@ keywords: [] --- > [!note] -> To override Hugo's embedded `param` shortcode, copy the [source code] to a file with the same name in the `layouts/shortcodes` directory. +> To override Hugo's embedded `param` shortcode, copy the [source code] to a file with the same name in the `layouts/_shortcodes` directory. The `param` shortcode renders a parameter from front matter, falling back to a site parameter of the same name. The shortcode throws an error if the parameter does not exist. diff --git a/docs/content/en/shortcodes/qr.md b/docs/content/en/shortcodes/qr.md index 98d6cee4c..27d9ae02f 100755 --- a/docs/content/en/shortcodes/qr.md +++ b/docs/content/en/shortcodes/qr.md @@ -9,7 +9,7 @@ keywords: [] {{< new-in 0.141.0 />}} > [!note] -> To override Hugo's embedded `qr` shortcode, copy the [source code] to a file with the same name in the `layouts/shortcodes` directory. +> To override Hugo's embedded `qr` shortcode, copy the [source code] to a file with the same name in the `layouts/_shortcodes` directory. The `qr` shortcode encodes the given text into a [QR code] using the specified options and renders the resulting image. diff --git a/docs/content/en/shortcodes/ref.md b/docs/content/en/shortcodes/ref.md index a52c2bf6e..b38413c63 100755 --- a/docs/content/en/shortcodes/ref.md +++ b/docs/content/en/shortcodes/ref.md @@ -7,7 +7,7 @@ keywords: [] --- > [!note] -> To override Hugo's embedded `ref` shortcode, copy the [source code] to a file with the same name in the `layouts/shortcodes` directory. +> To override Hugo's embedded `ref` shortcode, copy the [source code] to a file with the same name in the `layouts/_shortcodes` directory. > [!note] > When working with Markdown, this shortcode is obsolete. Instead, use a [link render hook] that resolves the link destination using the `GetPage` method on the `Page` object. You can either create your own, or simply enable the [embedded link render hook]. The embedded link render hook is automatically enabled for multilingual single-host projects. diff --git a/docs/content/en/shortcodes/relref.md b/docs/content/en/shortcodes/relref.md index 219eae81a..d4f4c2425 100755 --- a/docs/content/en/shortcodes/relref.md +++ b/docs/content/en/shortcodes/relref.md @@ -7,7 +7,7 @@ keywords: [] --- > [!note] -> To override Hugo's embedded `relref` shortcode, copy the [source code] to a file with the same name in the `layouts/shortcodes` directory. +> To override Hugo's embedded `relref` shortcode, copy the [source code] to a file with the same name in the `layouts/_shortcodes` directory. > [!note] > When working with Markdown, this shortcode is obsolete. Instead, use a [link render hook] that resolves the link destination using the `GetPage` method on the `Page` object. You can either create your own, or simply enable the [embedded link render hook]. The embedded link render hook is automatically enabled for multilingual single-host projects. @@ -30,13 +30,13 @@ The `relref` shortcode typically provides the destination for a Markdown link. The following examples show the rendered output for a page on the English version of the site: ```md -[Link A]({{%/* ref "/books/book-1" */%}}) +[Link A]({{%/* relref "/books/book-1" */%}}) -[Link B]({{%/* ref path="/books/book-1" */%}}) +[Link B]({{%/* relref path="/books/book-1" */%}}) -[Link C]({{%/* ref path="/books/book-1" lang="de" */%}}) +[Link C]({{%/* relref path="/books/book-1" lang="de" */%}}) -[Link D]({{%/* ref path="/books/book-1" lang="de" outputFormat="json" */%}}) +[Link D]({{%/* relref path="/books/book-1" lang="de" outputFormat="json" */%}}) ``` Rendered: diff --git a/docs/content/en/shortcodes/vimeo.md b/docs/content/en/shortcodes/vimeo.md index 1164ce997..40daaeec2 100755 --- a/docs/content/en/shortcodes/vimeo.md +++ b/docs/content/en/shortcodes/vimeo.md @@ -7,7 +7,7 @@ keywords: [] --- > [!note] -> To override Hugo's embedded `vimeo` shortcode, copy the [source code] to a file with the same name in the `layouts/shortcodes` directory. +> To override Hugo's embedded `vimeo` shortcode, copy the [source code] to a file with the same name in the `layouts/_shortcodes` directory. ## Example @@ -30,7 +30,7 @@ Hugo renders this to: ## Arguments id -: (string) The video `id`. Optional if the `id` is provided as a positional argument as shown in the example above. +: (string) The video `id`. Optional if the `id` is the first and only positional argument. allowFullScreen : {{< new-in 0.146.0 />}} diff --git a/docs/content/en/shortcodes/x.md b/docs/content/en/shortcodes/x.md index f1eebdaf2..dbce7e613 100755 --- a/docs/content/en/shortcodes/x.md +++ b/docs/content/en/shortcodes/x.md @@ -9,7 +9,7 @@ keywords: [] {{< new-in 0.141.0 />}} > [!note] -> To override Hugo's embedded `x` shortcode, copy the [source code] to a file with the same name in the `layouts/shortcodes` directory. +> To override Hugo's embedded `x` shortcode, copy the [source code] to a file with the same name in the `layouts/_shortcodes` directory. ## Example diff --git a/docs/content/en/shortcodes/youtube.md b/docs/content/en/shortcodes/youtube.md index ed3cf0632..d9f5fb739 100755 --- a/docs/content/en/shortcodes/youtube.md +++ b/docs/content/en/shortcodes/youtube.md @@ -7,7 +7,7 @@ keywords: [] --- > [!note] -> To override Hugo's embedded `youtube` shortcode, copy the [source code] to a file with the same name in the `layouts/shortcodes` directory. +> To override Hugo's embedded `youtube` shortcode, copy the [source code] to a file with the same name in the `layouts/_shortcodes` directory. ## Example @@ -30,7 +30,7 @@ Hugo renders this to: ## Arguments id -: (`string`) The video `id`. Optional if the `id` is provided as a positional argument as shown in the example above. +: (`string`) The video `id`. Optional if the `id` is the first and only positional argument. allowFullScreen : {{< new-in 0.125.0 />}} diff --git a/docs/content/en/templates/base.md b/docs/content/en/templates/base.md deleted file mode 100644 index bb6a25b1e..000000000 --- a/docs/content/en/templates/base.md +++ /dev/null @@ -1,90 +0,0 @@ ---- -title: Base templates -description: The base and block construct allows you to define the outer shell of your master templates (i.e., the chrome of the page). -categories: [] -keywords: [] -weight: 40 -aliases: [/templates/blocks/,/templates/base-templates-and-blocks/] ---- - -The `block` keyword allows you to define the outer shell of your pages' one or more master template(s) and then fill in or override portions as necessary. - -{{< youtube QVOMCYitLEc >}} - -## Base template lookup order - -The base template lookup order closely follows that of the template it applies to (e.g. `_default/list.html`). - -See [Template Lookup Order](/templates/lookup-order/) for details and examples. - -## Define the base template - -The following defines a simple base template at `_default/baseof.html`. As a default template, it is the shell from which all your pages will be rendered unless you specify another `*baseof.html` closer to the beginning of the lookup order. - -```go-html-template {file="layouts/_default/baseof.html"} -<!DOCTYPE html> -<html> - <head> - <meta charset="utf-8"> - <title>{{ block "title" . }} - <!-- Blocks may include default content. --> - {{ .Site.Title }} - {{ end }}</title> - </head> - <body> - <!-- Code that all your templates share, like a header --> - {{ block "main" . }} - <!-- The part of the page that begins to differ between templates --> - {{ end }} - {{ block "footer" . }} - <!-- More shared code, perhaps a footer but that can be overridden if need be in --> - {{ end }} - </body> -</html> -``` - -## Override the base template - -The default list template will inherit all of the code defined above and can then implement its own `"main"` block from: - -```go-html-template {file="layouts/_default/list.html"} -{{ define "main" }} - <h1>Posts</h1> - {{ range .Pages }} - <article> - <h2>{{ .Title }}</h2> - {{ .Content }} - </article> - {{ end }} -{{ end }} -``` - -This replaces the contents of our (basically empty) `main` block with something useful for the list template. In this case, we didn't define a `title` block, so the contents from our base template remain unchanged in lists. - -> [!warning] -> Only [template comments] are allowed outside a block's `define` and `end` statements. Avoid placing any other text, including HTML comments, outside these boundaries. Doing so will cause rendering issues, potentially resulting in a blank page. See the example below. - -```go-html-template {file="layouts/_default/do-not-do-this.html"} -<div>This div element broke your template.</div> -{{ define "main" }} - <h2>{{ .Title }}</h2> - {{ .Content }} -{{ end }} -<!-- An HTML comment will break your template too. --> -``` - -The following shows how you can override both the `main` and `title` block areas from the base template with code unique to your default [single template]: - -```go-html-template {file="layouts/_default/single.html"} -{{ define "title" }} - <!-- This will override the default value set in baseof.html; i.e., "{{ .Site.Title }}" in the original example--> - {{ .Title }} – {{ .Site.Title }} -{{ end }} -{{ define "main" }} - <h1>{{ .Title }}</h1> - {{ .Content }} -{{ end }} -``` - -[single template]: /templates/types/#single -[template comments]: /templates/introduction/#comments diff --git a/docs/content/en/templates/content-view.md b/docs/content/en/templates/content-view.md deleted file mode 100644 index f001e400e..000000000 --- a/docs/content/en/templates/content-view.md +++ /dev/null @@ -1,90 +0,0 @@ ---- -title: Content view templates -description: Hugo can render alternative views of your content, useful in list and summary views. -categories: [] -keywords: [] -weight: 110 -aliases: [/templates/views/] ---- - -The following are common use cases for content views: - -- You want content of every type to be shown on the home page but only with limited [summary views][summaries]. -- You only want a bulleted list of your content in a [taxonomy template]. Views make this very straightforward by delegating the rendering of each different type of content to the content itself. - -## Create a content view - -To create a new view, create a template in each of your different content type directories with the view name. The following example contains an "li" view and a "summary" view for the `posts` and `project` content types. As you can see, these sit next to the [single template], `single.html`. You can even provide a specific view for a given type and continue to use the `_default/single.html` for the primary view. - -```txt -layouts/ -├── posts/ -│ ├── li.html -│ ├── single.html -│ └── summary.html -├── project/ -│ ├── li.html -│ └── single.html -└── summary.html -``` - -## Which template will be rendered? - -The following is the lookup order for content views ordered by specificity. - -1. `/layouts/<TYPE>/<VIEW>.html` -1. `/layouts/<SECTION>/<VIEW>.html` -1. `/layouts/_default/<VIEW>.html` -1. `/themes/<THEME>/layouts/<TYPE>/<VIEW>.html` -1. `/themes/<THEME>/layouts/<SECTION>/<VIEW>.html` -1. `/themes/<THEME>/layouts/_default/<VIEW>.html` - -## Example: content view inside a list - -### list.html - -In this example, `.Render` is passed into the template to call the [render function][render]. `.Render` is a special function that instructs content to render itself with the view template provided as the first argument. In this case, the template is going to render the `summary.html` view that follows: - -```go-html-template {file="layouts/_default/list.html"} -<main id="main"> - <div> - <h1 id="title">{{ .Title }}</h1> - {{ range .Pages }} - {{ .Render "summary" }} - {{ end }} - </div> -</main> -``` - -### summary.html - -Hugo passes the `Page` object to the following `summary.html` view template. - -```go-html-template {file="layouts/_default/summary.html"} -<article class="post"> - <header> - <h2><a href="{{ .RelPermalink }}">{{ .Title }}</a></h2> - <div class="post-meta">{{ .Date.Format "Mon, Jan 2, 2006" }} - {{ .FuzzyWordCount }} Words </div> - </header> - {{ .Summary }} - <footer> - <a href='{{ .RelPermalink }}'>Read more »</a> - </footer> -</article> -``` - -### li.html - -Continuing on the previous example, we can change our render function to use a smaller `li.html` view by changing the argument in the call to the `.Render` function (i.e., `{{ .Render "li" }}`). - -```go-html-template {file="layouts/_default/li.html"} -<li> - <a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a> - <div class="meta">{{ .Date.Format "Mon, Jan 2, 2006" }}</div> -</li> -``` - -[render]: /methods/page/render/ -[single template]: /templates/types/#single -[summaries]: /content-management/summaries/ -[taxonomy template]: /templates/types/#taxonomy diff --git a/docs/content/en/templates/embedded.md b/docs/content/en/templates/embedded.md index ecfd90514..af9a08f26 100644 --- a/docs/content/en/templates/embedded.md +++ b/docs/content/en/templates/embedded.md @@ -7,10 +7,12 @@ weight: 170 aliases: [/templates/internal] --- +{{< newtemplatesystem >}} + ## Disqus > [!note] -> To override Hugo's embedded Disqus template, copy the [source code]({{% eturl disqus %}}) to a file with the same name in the `layouts/partials` directory, then call it from your templates using the [`partial`] function: +> To override Hugo's embedded Disqus template, copy the [source code]({{% eturl disqus %}}) to a file with the same name in the `layouts/_partials` directory, then call it from your templates using the [`partial`] function: > > `{{ partial "disqus.html" . }}` @@ -19,7 +21,7 @@ Hugo includes an embedded template for [Disqus], a popular commenting system for To include the embedded template: ```go-html-template -{{ template "_internal/disqus.html" . }} +{{ partial "disqus.html" . }} ``` ### Configuration {#configuration-disqus} @@ -55,7 +57,7 @@ disable ## Google Analytics > [!note] -> To override Hugo's embedded Google Analytics template, copy the [source code]({{% eturl google_analytics %}}) to a file with the same name in the `layouts/partials` directory, then call it from your templates using the [`partial`] function: +> To override Hugo's embedded Google Analytics template, copy the [source code]({{% eturl google_analytics %}}) to a file with the same name in the `layouts/_partials` directory, then call it from your templates using the [`partial`] function: > > `{{ partial "google_analytics.html" . }}` @@ -64,7 +66,7 @@ Hugo includes an embedded template supporting [Google Analytics 4]. To include the embedded template: ```go-html-template -{{ template "_internal/google_analytics.html" . }} +{{ partial "google_analytics.html" . }} ``` ### Configuration {#configuration-google-analytics} @@ -93,7 +95,7 @@ respectDoNotTrack ## Open Graph > [!note] -> To override Hugo's embedded Open Graph template, copy the [source code]({{% eturl opengraph %}}) to a file with the same name in the `layouts/partials` directory, then call it from your templates using the [`partial`] function: +> To override Hugo's embedded Open Graph template, copy the [source code]({{% eturl opengraph %}}) to a file with the same name in the `layouts/_partials` directory, then call it from your templates using the [`partial`] function: > > `{{ partial "opengraph.html" . }}` @@ -103,7 +105,7 @@ This format is used for Facebook and some other sites. To include the embedded template: ```go-html-template -{{ template "_internal/opengraph.html" . }} +{{ partial "opengraph.html" . }} ``` ### Configuration {#configuration-open-graph} @@ -147,12 +149,12 @@ If using YouTube this will produce a og:video tag like `<meta property="og:video ## Pagination -See [details](/templates/pagination/). +See [details](/templates/pagination/). ## Schema > [!note] -> To override Hugo's embedded Schema template, copy the [source code]({{% eturl schema %}}) to a file with the same name in the `layouts/partials` directory, then call it from your templates using the [`partial`] function: +> To override Hugo's embedded Schema template, copy the [source code]({{% eturl schema %}}) to a file with the same name in the `layouts/_partials` directory, then call it from your templates using the [`partial`] function: > > `{{ partial "schema.html" . }}` @@ -161,13 +163,13 @@ Hugo includes an embedded template to render [microdata] `meta` elements within To include the embedded template: ```go-html-template -{{ template "_internal/schema.html" . }} +{{ partial "schema.html" . }} ``` ## X (Twitter) Cards > [!note] -> To override Hugo's embedded Twitter Cards template, copy the [source code]({{% eturl twitter_cards %}}) to a file with the same name in the `layouts/partials` directory, then call it from your templates using the [`partial`] function: +> To override Hugo's embedded Twitter Cards template, copy the [source code]({{% eturl twitter_cards %}}) to a file with the same name in the `layouts/_partials` directory, then call it from your templates using the [`partial`] function: > > `{{ partial "twitter_cards.html" . }}` @@ -177,7 +179,7 @@ metadata used to attach rich media to Tweets linking to your site. To include the embedded template: ```go-html-template -{{ template "_internal/twitter_cards.html" . }} +{{ partial "twitter_cards.html" . }} ``` ### Configuration {#configuration-x-cards} diff --git a/docs/content/en/templates/home.md b/docs/content/en/templates/home.md deleted file mode 100644 index 937a4a5a8..000000000 --- a/docs/content/en/templates/home.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -title: Home page templates -description: The home page of a website is often formatted differently than the other pages. For this reason, Hugo makes it easy for you to define your new site's home page as a unique template. -categories: [] -keywords: [] -weight: 50 -aliases: [/layout/homepage/,/templates/homepage-template/,/templates/homepage/] ---- - -## Introduction - -A home page template is used to render your site's home page, and is the only template required for a single-page website. For example, the home page template below inherits the site's shell from the base template and renders the home page content, such as a list of other pages. - -```go-html-template {file="layouts/_default/home.html"} -{{ define "main" }} - {{ .Content }} - {{ range site.RegularPages }} - <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2> - {{ end }} -{{ end }} -``` - -{{% include "/_common/filter-sort-group.md" %}} - -## Lookup order - -Hugo's [template lookup order] determines the template path, allowing you to create unique templates for any page. - -> [!note] -> You must have thorough understanding of the template lookup order when creating templates. Template selection is based on template type, page kind, content type, section, language, and output format. - -## Content and front matter - -The home page template uses content and front matter from an `_index.md` file located in the root of your content directory. - -{{< code-toggle file=content/_index.md fm=true >}} ---- -title: The Home Page -date: 2025-01-30T03:36:57-08:00 -draft: false -params: - subtitle: The Subtitle ---- -{{< /code-toggle >}} - -The home page template below inherits the site's shell from the base template, renders the subtitle and content as defined in the `_index.md` file, then renders of list of the site's [regular pages](g). - -```go-html-template {file="layouts/_default/home.html"} -{{ define "main" }} - <h3>{{ .Params.Subtitle }}</h3> - {{ .Content }} - {{ range site.RegularPages }} - <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2> - {{ end }} -{{ end }} -``` - -[template lookup order]: /templates/lookup-order/#home-templates diff --git a/docs/content/en/templates/introduction.md b/docs/content/en/templates/introduction.md index 8898ee456..7ee4f6cdf 100644 --- a/docs/content/en/templates/introduction.md +++ b/docs/content/en/templates/introduction.md @@ -7,6 +7,9 @@ keywords: [] weight: 10 --- +{{< newtemplatesystem >}} + + {{% glossary-term template %}} Templates use [variables], [functions], and [methods] to transform your content, resources, and data into a published page. @@ -38,7 +41,7 @@ For example, a template for a single page receives a `Page` object, and the `Pag Within a template, the dot (`.`) represents the current context. -```go-html-template {file="layouts/_default/single.html"} +```go-html-template {file="layouts/page.html"} <h2>{{ .Title }}</h2> ``` @@ -46,7 +49,7 @@ In the example above the dot represents the `Page` object, and we call its [`Tit The current context may change within a template. For example, at the top of a template the context might be a `Page` object, but we rebind the context to another value or object within [`range`] or [`with`] blocks. -```go-html-template {file="layouts/_default/single.html"} +```go-html-template {file="layouts/page.html"} <h2>{{ .Title }}</h2> {{ range slice "foo" "bar" }} @@ -71,7 +74,7 @@ In the example above, the context changes as we `range` through the [slice](g) o Within a `range` or `with` block you can access the context passed into the template by prepending a dollar sign (`$`) to the dot: -```go-html-template {file="layouts/_default/single.html"} +```go-html-template {file="layouts/page.html"} {{ with "foo" }} <p>{{ $.Title }} - {{ . }}</p> {{ end }} @@ -92,7 +95,7 @@ In the examples above the paired opening and closing braces represent the beginn A template action may contain literal values ([boolean](g), [string](g), [integer](g), and [float](g)), variables, functions, and methods. -```go-html-template {file="layouts/_default/single.html"} +```go-html-template {file="layouts/page.html"} {{ $convertToLower := true }} {{ if $convertToLower }} <h2>{{ strings.ToLower .Title }}</h2> @@ -119,7 +122,7 @@ Hugo renders the above to: Notice the blank lines and indentation in the previous example? Although irrelevant in production when you typically minify the output, you can remove the adjacent whitespace by using template action delimiters with hyphens: -```go-html-template {file="layouts/_default/single.html"} +```go-html-template {file="layouts/page.html"} {{- $convertToLower := true -}} {{- if $convertToLower -}} <h2>{{ strings.ToLower .Title }}</h2> @@ -266,21 +269,21 @@ Object|Method|Description Chain the method to its object with a dot (`.`) as shown below, remembering that the leading dot represents the [current context]. -```go-html-template {file="layouts/_default/single.html"} +```go-html-template {file="layouts/page.html"} {{ .Site.Title }} → My Site Title {{ .Page.Title }} → My Page Title ``` The context passed into most templates is a `Page` object, so this is equivalent to the previous example: -```go-html-template {file="layouts/_default/single.html"} +```go-html-template {file="layouts/page.html"} {{ .Site.Title }} → My Site Title {{ .Title }} → My Page Title ``` Some methods take an argument. Separate the argument from the method with a space. For example: -```go-html-template {file="layouts/_default/single.html"} +```go-html-template {file="layouts/page.html"} {{ $page := .Page.GetPage "/books/les-miserables" }} {{ $page.Title }} → Les Misérables ``` @@ -326,11 +329,11 @@ To render an HTML comment, pass a string through the [`safeHTML`] template funct Use the [`template`] function to include one or more of Hugo's [embedded templates]: ```go-html-template -{{ template "_internal/google_analytics.html" . }} -{{ template "_internal/opengraph" . }} -{{ template "_internal/pagination.html" . }} -{{ template "_internal/schema.html" . }} -{{ template "_internal/twitter_cards.html" . }} +{{ partial "google_analytics.html" . }} +{{ partial "opengraph" . }} +{{ partial "pagination.html" . }} +{{ partial "schema.html" . }} +{{ partial "twitter_cards.html" . }} ``` Use the [`partial`] or [`partialCached`] function to include one or more [partial templates]: @@ -340,7 +343,7 @@ Use the [`partial`] or [`partialCached`] function to include one or more [partia {{ partialCached "css.html" . }} ``` -Create your partial templates in the layouts/partials directory. +Create your partial templates in the layouts/_partials directory. > [!note] > In the examples above, note that we are passing the current context (the dot) to each of the templates. @@ -400,14 +403,14 @@ See documentation for [`range`], [`else`], and [`end`]. {{ end }} ``` -Use the [`seq`] function to loop a specified number of times: +To loop a specified number of times: ```go-html-template -{{ $total := 0 }} -{{ range seq 4 }} - {{ $total = add $total . }} +{{ $s := slice }} +{{ range 3 }} + {{ $s = $s | append . }} {{ end }} -{{ $total }} → 10 +{{ $s }} → [0 1 2] ``` ### Rebind context @@ -513,7 +516,6 @@ In the template example above, each of the keys is a valid identifier. For examp [`range`]: /functions/go-template/range/ [`range`]: /functions/go-template/range/ [`safeHTML`]: /functions/safe/html -[`seq`]: /functions/collections/seq [`Site`]: /methods/site/ [`template`]: /functions/go-template/template/ [`Title`]: /methods/page/title @@ -529,7 +531,7 @@ In the template example above, each of the keys is a valid identifier. For examp [html/template]: https://pkg.go.dev/html/template [methods]: /methods/ [methods]: /methods/ -[partial templates]: /templates/partial +[partial templates]: /templates/types/#partial [templates]: /templates/ [text/template]: https://pkg.go.dev/text/template [variables]: #variables diff --git a/docs/content/en/templates/lookup-order.md b/docs/content/en/templates/lookup-order.md index 518900797..05108fc92 100644 --- a/docs/content/en/templates/lookup-order.md +++ b/docs/content/en/templates/lookup-order.md @@ -7,6 +7,8 @@ keywords: [] weight: 20 --- +{{< newtemplatesystem >}} + ## Lookup rules Hugo takes the parameters listed below into consideration when choosing a template for a given page. The templates are ordered by specificity. This should feel natural, but look at the table below for concrete examples of the different parameter variations. @@ -91,60 +93,3 @@ layouts/ └── contact.html <-- renders contact.md └── single.html <-- renders about.md ``` - -## Home templates - -These template paths are sorted by specificity in descending order. The least specific path is at the bottom of each list. - -{{< datatable-filtered "output" "layouts" "Kind == home" "Example" "OutputFormat" "Suffix" "Template Lookup Order" >}} - -## Single templates - -These template paths are sorted by specificity in descending order. The least specific path is at the bottom of each list. - -{{< datatable-filtered "output" "layouts" "Kind == page" "Example" "OutputFormat" "Suffix" "Template Lookup Order" >}} - -## Section templates - -These template paths are sorted by specificity in descending order. The least specific path is at the bottom of each list. - -{{< datatable-filtered "output" "layouts" "Kind == section" "Example" "OutputFormat" "Suffix" "Template Lookup Order" >}} - -## Taxonomy templates - -These template paths are sorted by specificity in descending order. The least specific path is at the bottom of each list. - -The examples below assume the following site configuration: - -{{< code-toggle file=hugo >}} -[taxonomies] -category = 'categories' -{{< /code-toggle >}} - -{{< datatable-filtered "output" "layouts" "Kind == taxonomy" "Example" "OutputFormat" "Suffix" "Template Lookup Order" >}} - -## Term templates - -These template paths are sorted by specificity in descending order. The least specific path is at the bottom of each list. - -The examples below assume the following site configuration: - -{{< code-toggle file=hugo >}} -[taxonomies] -category = 'categories' -{{< /code-toggle >}} - -{{< datatable-filtered "output" "layouts" "Kind == term" "Example" "OutputFormat" "Suffix" "Template Lookup Order" >}} - -## RSS templates - -These template paths are sorted by specificity in descending order. The least specific path is at the bottom of each list. - -The examples below assume the following site configuration: - -{{< code-toggle file=hugo >}} -[taxonomies] -category = 'categories' -{{< /code-toggle >}} - -{{< datatable-filtered "output" "layouts" "OutputFormat == rss" "Example" "OutputFormat" "Suffix" "Template Lookup Order" >}} diff --git a/docs/content/en/templates/menu.md b/docs/content/en/templates/menu.md index 4ff423255..e1eaa07b9 100644 --- a/docs/content/en/templates/menu.md +++ b/docs/content/en/templates/menu.md @@ -23,7 +23,7 @@ The example below handles every combination. This partial template recursively "walks" a menu structure, rendering a localized, accessible nested list. -```go-html-template {file="layouts/partials/menu.html" copy=true} +```go-html-template {file="layouts/_partials/menu.html" copy=true} {{- $page := .page }} {{- $menuID := .menuID }} @@ -35,7 +35,7 @@ This partial template recursively "walks" a menu structure, rendering a localize </nav> {{- end }} -{{- define "partials/inline/menu/walk.html" }} +{{- define "_partials/inline/menu/walk.html" }} {{- $page := .page }} {{- range .menuEntries }} {{- $attrs := dict "href" .URL }} @@ -70,7 +70,7 @@ This partial template recursively "walks" a menu structure, rendering a localize Call the partial above, passing a menu ID and the current page in context. -```go-html-template {file="layouts/_default/single.html"} +```go-html-template {file="layouts/page.html"} {{ partial "menu.html" (dict "menuID" "main" "page" .) }} {{ partial "menu.html" (dict "menuID" "footer" "page" .) }} ``` @@ -81,7 +81,7 @@ Regardless of how you [define menu entries], an entry associated with a page has This simplistic example renders a page parameter named `version` next to each entry's `name`. Code defensively using `with` or `if` to handle entries where (a) the entry points to an external resource, or (b) the `version` parameter is not defined. -```go-html-template {file="layouts/_default/single.html"} +```go-html-template {file="layouts/page.html"} {{- range site.Menus.main }} <a href="{{ .URL }}"> {{ .Name }} @@ -103,7 +103,7 @@ When you define menu entries [in site configuration] or [in front matter], you c This simplistic example renders a `class` attribute for each anchor element. Code defensively using `with` or `if` to handle entries where `params.class` is not defined. -```go-html-template {file="layouts/partials/menu.html"} +```go-html-template {file="layouts/_partials/menu.html"} {{- range site.Menus.main }} <a {{ with .Params.class -}} class="{{ . }}" {{ end -}} href="{{ .URL }}"> {{ .Name }} diff --git a/docs/content/en/templates/new-templatesystem-overview.md b/docs/content/en/templates/new-templatesystem-overview.md new file mode 100644 index 000000000..93be94bcc --- /dev/null +++ b/docs/content/en/templates/new-templatesystem-overview.md @@ -0,0 +1,99 @@ + +--- +title: New template system in Hugo v0.146.0 +linktitle: New template system +description: Overview of the new template system in Hugo v0.146.0. +categories: [] +keywords: [] +weight: 1 +--- + +In [Hugo v0.146.0], we performed a full re-implementation of how Go templates are handled in Hugo. This includes structural changes to the `layouts` folder and a new, more powerful template lookup system. + +We have aimed to maintain as much backward compatibility as possible by mapping "old to new," but some reported breakages have occurred. We're working on a full overhaul of the documentation on this topic – until then, this is a one-pager with the most important changes. + +## Changes to the `layouts` folder + +| Description | Action required | +| ------------- | ------------- | +| The `_default` folder is removed. | Move all files in `layouts/_default` up to the `layouts/` root.| +| The `layouts/partials` folder is renamed to `layouts/_partials`. | Rename the folder. | +| The `layouts/shortcodes` folder is renamed to `layouts/_shortcodes`. | Rename the folder. | +| Any folder in `layouts` that does not start with `_` represents the root of a [Page path]. In [Hugo v0.146.0], this can be nested as deeply as needed, and `_shortcodes` and `_markup` folders can be placed at any level in the tree.| No action required.| +| The above also means that there's no top-level `layouts/taxonomy` or `layouts/section` folders anymore, unless it represents a [Page path].|Move them up to `layouts/` with one of the [Page kinds] `section`, `taxonomy` or `term` as the base name, or place the layouts into the taxonomy [Page path]. | +|A template named `taxonomy.html` used to be a candidate for both Page kind `term` and `taxonomy`, now it's only considered for `taxonomy`.|Create both `taxonomy.html` and `term.html` or create a more general layout, e.g. `list.html`.| +| For base templates (e.g., `baseof.html`), in previous Hugo versions, you could prepend one identifier (layout, type, or kind) with a hyphen in front of the baseof keyword.|Move that identifier after the first "dot," e.g., rename`list-baseof.html` to `baseof.list.html`.| +| We have added a new `all` "catch-all" layout. This means that if you have, e.g., `layouts/all.html` and that is the only template, that layout will be used for all HTML page rendering.|| +| We have removed the concept of `_internal` Hugo templates.[^internal]|Replace constructs similar to `{{ template "_internal/opengraph.html" . }}` with `{{ partial "opengraph.html" . }}`.| +| The identifiers that can be used in a template filename are one of the [Page kinds] (`home`, `page`, `section`, `taxonomy`, or `term`), one of the standard layouts (`list`, `single`, or `all`), a custom layout (as defined in the `layout` front matter field), a language (e.g., `en`), an output format (e.g., `html`, `rss`), and a suffix representing the media type. E.g., `all.en.html` and `home.rss.xml`.|| +| The above means that there's no such thing as an `index.html` template for the home page anymore. | Rename `index.html` to `home.html`.| + +Also, see the [Example folder structure] below for a more concrete example of the new layout system. + +## Changes to template lookup order + +We have consolidated the template lookup so it works the same across all shortcodes, render hooks, partials, and page templates. The previous setup was very hard to understand and had a massive number of variants. The new setup aims to feel natural with few surprises. + +The identifiers used in the template weighting, in order of importance, are: + +| Identifier | Description | +| ---------- | ----------- | +| Layout custom | The custom `layout` set in front matter. | +| [Page kinds] | One of `home`, `section`, `taxonomy`, `term`, `page`. | +| Layouts standard 1 | `list` or `single`. | +| Output format | The output format (e.g., `html`, `rss`). | +| Layouts standard 2 | `all`. | +| Language | The language (e.g., `en`). | +| Media type | The media type (e.g., `text/html`). | +| [Page path] | The page path (e.g., `/blog/mypost`). | +| Type | `type` set in front matter.[^type]| + +For templates placed in a `layouts` folder partly or completely matching a [Page path], a closer match upwards will be considered _better_. In the [Example folder structure] below, this means that: + +* `layouts/docs/api/_markup/render-link.html` will be used to render links from the Page path `/docs/api` and below. +* `layouts/docs/baseof.html` will be used as the base template for the Page path `/docs` and below. +* `layouts/tags/term.html` will be used for all `term` rendering in the `tags` taxonomy, except for the `blue` term, which will use `layouts/tags/blue/list.html`. + +## Example folder structure + +```text +layouts +├── baseof.html +├── baseof.term.html +├── home.html +├── page.html +├── section.html +├── taxonomy.html +├── term.html +├── term.mylayout.en.rss.xml +├── _markup +│ ├── render-codeblock-go.term.mylayout.no.rss.xml +│ └── render-link.html +├── _partials +│ └── mypartial.html +├── _shortcodes +│ ├── myshortcode.html +│ └── myshortcode.section.mylayout.en.rss.xml +├── docs +│ ├── baseof.html +│ ├── _shortcodes +│ │ └── myshortcode.html +│ └── api +│ ├── mylayout.html +│ ├── page.html +│ └── _markup +│ └── render-link.html +└── tags + ├── taxonomy.html + ├── term.html + └── blue + └── list.html +``` + +[Hugo v0.146.0]: https://github.com/gohugoio/hugo/releases/tag/v0.146.0 +[Page path]: https://gohugo.io/methods/page/path/ +[Page kinds]: https://gohugo.io/methods/page/kind/ +[Example folder structure]: #example-folder-structure + +[^type]: The `type` set in front matter will effectively replace the `section` folder in [Page path] when doing lookups. +[^internal]: The old way of doing it made it very hard/impossible to, e.g., override `_internal/disqus.html` in a theme. Now you can just create a partial with the same name. diff --git a/docs/content/en/templates/pagination.md b/docs/content/en/templates/pagination.md index 018ec9271..76b9d1fdc 100644 --- a/docs/content/en/templates/pagination.md +++ b/docs/content/en/templates/pagination.md @@ -63,7 +63,7 @@ To paginate a list page using the `Paginate` method: <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2> {{ end }} -{{ template "_internal/pagination.html" . }} +{{ partial "pagination.html" . }} ``` In the example above, we: @@ -81,7 +81,7 @@ To paginate a list page using the `Paginator` method: <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2> {{ end }} -{{ template "_internal/pagination.html" . }} +{{ partial "pagination.html" . }} ``` In the example above, we: @@ -114,7 +114,7 @@ Use pagination with any of the [grouping methods]. For example: {{ end }} {{ end }} -{{ template "_internal/pagination.html" . }} +{{ partial "pagination.html" . }} ``` ## Navigation @@ -122,23 +122,23 @@ Use pagination with any of the [grouping methods]. For example: As shown in the examples above, the easiest way to add navigation between pagers is with Hugo's embedded pagination template: ```go-html-template -{{ template "_internal/pagination.html" . }} +{{ partial "pagination.html" . }} ``` The embedded pagination template has two formats: `default` and `terse`. The above is equivalent to: ```go-html-template -{{ template "_internal/pagination.html" (dict "page" . "format" "default") }} +{{ partial "pagination.html" (dict "page" . "format" "default") }} ``` The `terse` format has fewer controls and page slots, consuming less space when styled as a horizontal list. To use the `terse` format: ```go-html-template -{{ template "_internal/pagination.html" (dict "page" . "format" "terse") }} +{{ partial "pagination.html" (dict "page" . "format" "terse") }} ``` > [!note] -> To override Hugo's embedded pagination template, copy the [source code] to a file with the same name in the `layouts/partials` directory, then call it from your templates using the [`partial`] function: +> To override Hugo's embedded pagination template, copy the [source code] to a file with the same name in the `layouts/_partials` directory, then call it from your templates using the [`partial`] function: > > `{{ partial "pagination.html" . }}` @@ -179,7 +179,7 @@ And this section template: <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2> {{ end }} -{{ template "_internal/pagination.html" . }} +{{ partial "pagination.html" . }} ``` The published site has this structure: diff --git a/docs/content/en/templates/partial.md b/docs/content/en/templates/partial.md deleted file mode 100644 index 7ff2d9594..000000000 --- a/docs/content/en/templates/partial.md +++ /dev/null @@ -1,158 +0,0 @@ ---- -title: Partial templates -description: Partials are smaller, context-aware components in your list and page templates that can be used economically to keep your templating DRY. -categories: [] -keywords: [] -weight: 100 -aliases: [/templates/partials/,/layout/chrome/] ---- - -{{< youtube pjS4pOLyB7c >}} - -## Use partials in your templates - -All partials for your Hugo project are located in a single `layouts/partials` directory. For better organization, you can create multiple subdirectories within `partials` as well: - -```txt -layouts/ -└── partials/ - ├── footer/ - │ ├── scripts.html - │ └── site-footer.html - ├── head/ - │ ├── favicons.html - │ ├── metadata.html - │ └── prerender.html - └── header/ - ├── site-header.html - └── site-nav.html -``` - -All partials are called within your templates using the following pattern: - -```go-html-template -{{ partial "<PATH>/<PARTIAL>.html" . }} -``` - -> [!note] -> One of the most common mistakes with new Hugo users is failing to pass a context to the partial call. In the pattern above, note how "the dot" (`.`) is required as the second argument to give the partial context. You can read more about "the dot" in the [Hugo templating introduction](/templates/introduction/#context). - -> [!note] -> Do not include the word "baseof" when naming partial templates. The word "baseof" is reserved for base templates. - -As shown in the above example directory structure, you can nest your directories within `partials` for better source organization. You only need to call the nested partial's path relative to the `partials` directory: - -```go-html-template -{{ partial "header/site-header.html" . }} -{{ partial "footer/scripts.html" . }} -``` - -### Variable scoping - -The second argument in a partial call is the variable being passed down. The above examples are passing the dot (`.`), which tells the template receiving the partial to apply the current [context][context]. - -This means the partial will *only* be able to access those variables. The partial is isolated and cannot access the outer scope. From within the partial, `$.Var` is equivalent to `.Var`. - -## Returning a value from a partial - -In addition to outputting markup, partials can be used to return a value of any type. In order to return a value, a partial must include a lone `return` statement *at the end of the partial*. - -### Example GetFeatured - -```go-html-template -{{/* layouts/partials/GetFeatured.html */}} -{{ return first . (where site.RegularPages "Params.featured" true) }} -``` - -```go-html-template -{{/* layouts/index.html */}} -{{ range partial "GetFeatured.html" 5 }} - [...] -{{ end }} -``` - -### Example GetImage - -```go-html-template -{{/* layouts/partials/GetImage.html */}} -{{ $image := false }} -{{ with .Params.gallery }} - {{ $image = index . 0 }} -{{ end }} -{{ with .Params.image }} - {{ $image = . }} -{{ end }} -{{ return $image }} -``` - -```go-html-template -{{/* layouts/_default/single.html */}} -{{ with partial "GetImage.html" . }} - [...] -{{ end }} -``` - -> [!note] -> Only one `return` statement is allowed per partial file. - -## Inline partials - -You can also define partials inline in the template. But remember that template namespace is global, so you need to make sure that the names are unique to avoid conflicts. - -```go-html-template -Value: {{ partial "my-inline-partial.html" . }} - -{{ define "partials/my-inline-partial.html" }} -{{ $value := 32 }} -{{ return $value }} -{{ end }} -``` - -## Cached partials - -The `partialCached` template function provides significant performance gains for complex templates that don't need to be re-rendered on every invocation. See [details][partialcached]. - -## Examples - -### `header.html` - -The following `header.html` partial template is used for [spf13.com](https://spf13.com/): - -```go-html-template {file="layouts/partials/header.html"} -<!DOCTYPE html> -<html class="no-js" lang="en-US" prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#"> -<head> - <meta charset="utf-8"> - - {{ partial "meta.html" . }} - - <base href="{{ .Site.BaseURL }}"> - <title> {{ .Title }} : spf13.com </title> - <link rel="canonical" href="{{ .Permalink }}"> - {{ if .RSSLink }}<link href="{{ .RSSLink }}" rel="alternate" type="application/rss+xml" title="{{ .Title }}" />{{ end }} - - {{ partial "head_includes.html" . }} -</head> -``` - -> [!note] -> The `header.html` example partial was built before the introduction of block templates to Hugo. Read more on [base templates and blocks](/templates/base/) for defining the outer chrome or shell of your master templates (i.e., your site's head, header, and footer). You can even combine blocks and partials for added flexibility. - -### `footer.html` - -The following `footer.html` partial template is used for [spf13.com](https://spf13.com/): - -```go-html-template {file="layouts/partials/footer.html"} -<footer> - <div> - <p> - © 2013-14 Steve Francia. - <a href="https://creativecommons.org/licenses/by/3.0/" title="Creative Commons Attribution">Some rights reserved</a>; - please attribute properly and link back. - </p> - </div> -</footer> -``` - -[context]: /templates/introduction/ -[partialcached]: /functions/partials/includecached/ diff --git a/docs/content/en/templates/rss.md b/docs/content/en/templates/rss.md index f387a71e3..6e92d4ba4 100644 --- a/docs/content/en/templates/rss.md +++ b/docs/content/en/templates/rss.md @@ -60,20 +60,16 @@ Hugo will render this to: ## Custom templates -Override Hugo's [embedded RSS template] by creating one or more of your own, following the naming conventions as shown in the [template lookup order]. - -For example, to use different templates for home, section, taxonomy, and term pages: +Override Hugo's [embedded RSS template] by creating one or more of your own. For example, to use different templates for home, section, taxonomy, and term pages: ```text layouts/ -└── _default/ - ├── home.rss.xml - ├── section.rss.xml - ├── taxonomy.rss.xml - └── term.rss.xml + ├── home.rss.xml + ├── section.rss.xml + ├── taxonomy.rss.xml + └── term.rss.xml ``` RSS templates receive the `.Page` and `.Site` objects in context. [embedded RSS template]: {{% eturl rss %}} -[template lookup order]: /templates/lookup-order/#rss-templates diff --git a/docs/content/en/templates/section.md b/docs/content/en/templates/section.md deleted file mode 100644 index 8bc0f9dab..000000000 --- a/docs/content/en/templates/section.md +++ /dev/null @@ -1,81 +0,0 @@ ---- -title: Section templates -description: Create a section template to list its members. -categories: [] -keywords: [] -weight: 70 -aliases: [/templates/sections/,/templates/section-templates/] ---- - -## Add content and front matter to section templates - -To effectively leverage section templates, you should first understand Hugo's [content organization](/content-management/organization/) and, specifically, the purpose of `_index.md` for adding content and front matter to section and other list pages. - -## Section template lookup order - -See [Template Lookup](/templates/lookup-order/). - -## Example: creating a default section template - -```go-html-template {file="layouts/_default/section.html"} -{{ define "main" }} - <main> - {{ .Content }} - - {{ $pages := where site.RegularPages "Type" "posts" }} - {{ $paginator := .Paginate $pages }} - - {{ range $paginator.Pages }} - <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2> - {{ end }} - - {{ template "_internal/pagination.html" . }} - </main> -{{ end }} -``` - -### Example: using `.Site.GetPage` - -The `.Site.GetPage` example that follows assumes the following project directory structure: - -```txt -. -└── content - ├── blog - │ ├── _index.md <-- title: My Hugo Blog - │ ├── post-1.md - │ ├── post-2.md - │ └── post-3.md - └── events - ├── event-1.md - └── event-2.md -``` - -`.Site.GetPage` will return `nil` if no `_index.md` page is found. Therefore, if `content/blog/_index.md` does not exist, the template will output the section name: - -```go-html-template -<h1>{{ with .Site.GetPage "/blog" }}{{ .Title }}{{ end }}</h1> -``` - -Since `blog` has a section index page with front matter at `content/blog/_index.md`, the above code will return the following result: - -```html -<h1>My Hugo Blog</h1> -``` - -If we try the same code with the `events` section, however, Hugo will default to the section title because there is no `content/events/_index.md` from which to pull content and front matter: - -```go-html-template -<h1>{{ with .Site.GetPage "/events" }}{{ .Title }}{{ end }}</h1> -``` - -Which then returns the following: - -```html -<h1>Events</h1> -``` - -[contentorg]: /content-management/organization/ -[lookup]: /templates/lookup-order/ -[`where`]: /functions/collections/where/ -[sections]: /content-management/sections/ diff --git a/docs/content/en/templates/shortcode.md b/docs/content/en/templates/shortcode.md index 3ed573651..5e6ad3429 100644 --- a/docs/content/en/templates/shortcode.md +++ b/docs/content/en/templates/shortcode.md @@ -7,6 +7,9 @@ weight: 120 aliases: [/templates/shortcode-templates/] --- +{{< newtemplatesystem >}} + + > [!note] > Before creating custom shortcodes, please review the [shortcodes] page in the [content management] section. Understanding the usage details will help you design and create better templates. @@ -24,11 +27,11 @@ Hugo provides [embedded shortcodes] for many common tasks, but you'll likely nee ## Directory structure -Create shortcode templates within the `layouts/shortcodes` directory, either at its root or organized into subdirectories. +Create shortcode templates within the `layouts/_shortcodes` directory, either at its root or organized into subdirectories. ```text layouts/ -└── shortcodes/ +└── _shortcodes/ ├── diagrams/ │ ├── kroki.html │ └── plotly.html @@ -42,7 +45,7 @@ layouts/ └── row.html ``` -When calling a shortcode in a subdirectory, specify its path relative to the `shortcode` directory, excluding the file extension. +When calling a shortcode in a subdirectory, specify its path relative to the `_shortcode` directory, excluding the file extension. ```text {{</* media/audio path=/audio/podcast/episode-42.mp3 */>}} @@ -54,17 +57,17 @@ Hugo selects shortcode templates based on the shortcode name, the current output Shortcode name|Output format|Language|Template path :--|:--|:--|:-- -foo|html|en|`layouts/shortcodes/foo.en.html` -foo|html|en|`layouts/shortcodes/foo.html.html` -foo|html|en|`layouts/shortcodes/foo.html` -foo|html|en|`layouts/shortcodes/foo.html.en.html` +foo|html|en|`layouts/_shortcodes/foo.en.html` +foo|html|en|`layouts/_shortcodes/foo.html.html` +foo|html|en|`layouts/_shortcodes/foo.html` +foo|html|en|`layouts/_shortcodes/foo.html.en.html` Shortcode name|Output format|Language|Template path :--|:--|:--|:-- -foo|json|en|`layouts/shortcodes/foo.en.json` -foo|json|en|`layouts/shortcodes/foo.json` -foo|json|en|`layouts/shortcodes/foo.json.json` -foo|json|en|`layouts/shortcodes/foo.json.en.json` +foo|json|en|`layouts/_shortcodes/foo.en.json` +foo|json|en|`layouts/_shortcodes/foo.json` +foo|json|en|`layouts/_shortcodes/foo.json.json` +foo|json|en|`layouts/_shortcodes/foo.json.en.json` ## Methods @@ -80,7 +83,7 @@ These examples range in complexity from simple to moderately advanced, with some Create a shortcode to insert the current year: -```go-html-template {file="layouts/shortcodes/year.html"} +```go-html-template {file="layouts/_shortcodes/year.html"} {{- now.Format "2006" -}} ``` @@ -106,7 +109,7 @@ content/ Create a shortcode to capture an image as a page resource, resize it to the given width, convert it to the WebP format, and add an `alt` attribute: -```go-html-template {file="layouts/shortcodes/image.html"} +```go-html-template {file="layouts/_shortcodes/image.html"} {{- with .Page.Resources.Get (.Get "path") }} {{- with .Process (printf "resize %dx wepb" ($.Get "width")) -}} <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="{{ $.Get "alt" }}"> @@ -135,7 +138,7 @@ The example above uses: The previous example, while functional, silently fails if the image is missing, and does not gracefully exit if a required argument is missing. We'll add error handling to address these issues: -```go-html-template {file="layouts/shortcodes/image.html"} +```go-html-template {file="layouts/_shortcodes/image.html"} {{- with .Get "path" }} {{- with $r := $.Page.Resources.Get ($.Get "path") }} {{- with $.Get "width" }} @@ -178,7 +181,7 @@ Here's how to call it with positional arguments: Using the `Get` method with zero-indexed keys, we'll initialize variables with descriptive names in our template: -```go-html-template {file="layouts/shortcodes/image.html"} +```go-html-template {file="layouts/_shortcodes/image.html"} {{ $path := .Get 0 }} {{ $width := .Get 1 }} {{ $alt := .Get 2 }} @@ -191,7 +194,7 @@ Using the `Get` method with zero-indexed keys, we'll initialize variables with d You can create a shortcode that will accept both named and positional arguments, but not at the same time. Use the [`IsNamedParams`] method to determine whether the shortcode call used named or positional arguments: -```go-html-template {file="layouts/shortcodes/image.html"} +```go-html-template {file="layouts/_shortcodes/image.html"} {{ $path := cond (.IsNamedParams) (.Get "path") (.Get 0) }} {{ $width := cond (.IsNamedParams) (.Get "width") (.Get 1) }} {{ $alt := cond (.IsNamedParams) (.Get "alt") (.Get 2) }} @@ -209,7 +212,7 @@ When using named arguments, the `Params` method returns a map: {{</* image path=a.jpg width=300 alt="A white kitten" */>}} ``` -```go-html-template {file="layouts/shortcodes/image.html"} +```go-html-template {file="layouts/_shortcodes/image.html"} {{ .Params.path }} → a.jpg {{ .Params.width }} → 300 {{ .Params.alt }} → A white kitten @@ -221,7 +224,7 @@ When using named arguments, the `Params` method returns a map: {{</* image a.jpg 300 "A white kitten" */>}} ``` -```go-html-template {file="layouts/shortcodes/image.html"} +```go-html-template {file="layouts/_shortcodes/image.html"} {{ index .Params 0 }} → a.jpg {{ index .Params 1 }} → 300 {{ index .Params 1 }} → A white kitten @@ -239,7 +242,7 @@ This is a **bold** word, and this is an _emphasized_ word. {{</* /contrived */>}} ``` -```go-html-template {file="layouts/shortcodes/contrived.html"} +```go-html-template {file="layouts/_shortcodes/contrived.html"} <div class="contrived"> <h2>{{ .Get "title" }}</h2> {{ .Inner | .Page.RenderString }} @@ -254,7 +257,7 @@ The [`Parent`] method provides access to the parent shortcode context when the The following example is contrived but demonstrates the concept. Assume you have a `gallery` shortcode that expects one named `class` argument: -```go-html-template {file="layouts/shortcodes/gallery.html"} +```go-html-template {file="layouts/_shortcodes/gallery.html"} <div class="{{ .Get "class" }}"> {{ .Inner }} </div> @@ -262,7 +265,7 @@ The following example is contrived but demonstrates the concept. Assume you have You also have an `img` shortcode with a single named `src` argument that you want to call inside of `gallery` and other shortcodes, so that the parent defines the context of each `img`: -```go-html-template {file="layouts/shortcodes/img.html"} +```go-html-template {file="layouts/_shortcodes/img.html"} {{ $src := .Get "src" }} {{ with .Parent }} <img src="{{ $src }}" class="{{ .Get "class" }}-image"> @@ -305,7 +308,7 @@ The [`HasShortcode`] method allows you to check if a specific shortcode has been You can use the `HasShortcode` method in your base template to conditionally load CSS if the audio shortcode was used on the page: -```go-html-template {file="layouts/_default/baseof.html"} +```go-html-template {file="layouts/baseof.html"} <head> ... {{ if .HasShortcode "audio" }} diff --git a/docs/content/en/templates/single.md b/docs/content/en/templates/single.md deleted file mode 100644 index 6f244ef10..000000000 --- a/docs/content/en/templates/single.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -title: Single templates -description: Create a single template to render a single page. -categories: [] -keywords: [] -weight: 60 -aliases: [/layout/content/,/templates/single-page-templates/] ---- - -The single template below inherits the site's shell from the [base template]. - -[base template]: /templates/types/ - -```go-html-template {file="layouts/_default/single.html"} -{{ define "main" }} - <h1>{{ .Title }}</h1> - {{ .Content }} -{{ end }} -``` - -Review the [template lookup order] to select a template path that provides the desired level of specificity. - -[template lookup order]: /templates/lookup-order/#single-templates - -The single template below inherits the site's shell from the base template, and renders the page title, creation date, content, and a list of associated terms in the "tags" taxonomy. - -```go-html-template {file="layouts/_default/single.html"} -{{ define "main" }} - <section> - <h1>{{ .Title }}</h1> - {{ with .Date }} - {{ $dateMachine := . | time.Format "2006-01-02T15:04:05-07:00" }} - {{ $dateHuman := . | time.Format ":date_long" }} - <time datetime="{{ $dateMachine }}">{{ $dateHuman }}</time> - {{ end }} - <article> - {{ .Content }} - </article> - <aside> - {{ with .GetTerms "tags" }} - <div>{{ (index . 0).Parent.LinkTitle }}</div> - <ul> - {{ range . }} - <li><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></li> - {{ end }} - </ul> - {{ end }} - </aside> - </section> -{{ end }} -``` diff --git a/docs/content/en/templates/sitemap.md b/docs/content/en/templates/sitemap.md index bf0850eef..2691ae471 100644 --- a/docs/content/en/templates/sitemap.md +++ b/docs/content/en/templates/sitemap.md @@ -39,14 +39,14 @@ title = 'News' To override the built-in sitemap.xml template, create a new file in either of these locations: - `layouts/sitemap.xml` -- `layouts/_default/sitemap.xml` +- `layouts/sitemap.xml` When ranging through the page collection, access the _change frequency_ and _priority_ with `.Sitemap.ChangeFreq` and `.Sitemap.Priority` respectively. To override the built-in sitemapindex.xml template, create a new file in either of these locations: - `layouts/sitemapindex.xml` -- `layouts/_default/sitemapindex.xml` +- `layouts/sitemapindex.xml` ## Disable sitemap generation diff --git a/docs/content/en/templates/taxonomy.md b/docs/content/en/templates/taxonomy.md deleted file mode 100644 index 96c93ec95..000000000 --- a/docs/content/en/templates/taxonomy.md +++ /dev/null @@ -1,164 +0,0 @@ ---- -title: Taxonomy templates -description: Create a taxonomy template to render a list of terms. -categories: [] -keywords: [] -weight: 80 -aliases: [/taxonomies/displaying/,/templates/terms/,/indexes/displaying/,/taxonomies/templates/,/indexes/ordering/, /templates/taxonomies/, /templates/taxonomy-templates/] ---- - -The [taxonomy](g) template below inherits the site's shell from the [base template], and renders a list of [terms](g) in the current taxonomy. - -[base template]: /templates/types/ - -```go-html-template {file="layouts/_default/taxonomy.html"} -{{ define "main" }} - <h1>{{ .Title }}</h1> - {{ .Content }} - {{ range .Pages }} - <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2> - {{ end }} -{{ end }} -``` - -Review the [template lookup order] to select a template path that provides the desired level of specificity. - -[template lookup order]: /templates/lookup-order/#taxonomy-templates - -In the example above, the taxonomy and term will be capitalized if their respective pages are not backed by files. You can disable this in your site configuration: - -{{< code-toggle file=hugo >}} -capitalizeListTitles = false -{{< /code-toggle >}} - -## Data object - -Use these methods on the `Data` object within a taxonomy template. - -Singular -: (`string`) Returns the singular name of the taxonomy. - -```go-html-template -{{ .Data.Singular }} → tag -``` - -Plural -: (`string`) Returns the plural name of the taxonomy. - -```go-html-template -{{ .Data.Plural }} → tags -``` - -Terms -: (`page.Taxonomy`) Returns the `Taxonomy` object, consisting of a map of terms and the [weighted pages](g) associated with each term. - -```go-html-template -{{ $taxonomyObject := .Data.Terms }} -``` - -Once we have the `Taxonomy` object, we can call any of its [methods], allowing us to sort alphabetically or by term count. - -[methods]: /methods/taxonomy/ - -## Sort alphabetically - -The taxonomy template below inherits the site's shell from the base template, and renders a list of terms in the current taxonomy. Hugo sorts the list alphabetically by term, and displays the number of pages associated with each term. - -```go-html-template {file="layouts/_default/taxonomy.html"} -{{ define "main" }} - <h1>{{ .Title }}</h1> - {{ .Content }} - {{ range .Data.Terms.Alphabetical }} - <h2><a href="{{ .Page.RelPermalink }}">{{ .Page.LinkTitle }}</a> ({{ .Count }})</h2> - {{ end }} -{{ end }} -``` - -## Sort by term count - -The taxonomy template below inherits the site's shell from the base template, and renders a list of terms in the current taxonomy. Hugo sorts the list by the number of pages associated with each term, and displays the number of pages associated with each term. - -```go-html-template {file="layouts/_default/taxonomy.html"} -{{ define "main" }} - <h1>{{ .Title }}</h1> - {{ .Content }} - {{ range .Data.Terms.ByCount }} - <h2><a href="{{ .Page.RelPermalink }}">{{ .Page.LinkTitle }}</a> ({{ .Count }})</h2> - {{ end }} -{{ end }} -``` - -## Include content links - -The [`Alphabetical`] and [`ByCount`] methods used in the previous examples return an [ordered taxonomy](g), so we can also list the content to which each term is assigned. - -[`Alphabetical`]: /methods/taxonomy/alphabetical/ -[`ByCount`]: /methods/taxonomy/bycount/ - -The taxonomy template below inherits the site's shell from the base template, and renders a list of terms in the current taxonomy. Hugo sorts the list by the number of pages associated with each term, displays the number of pages associated with each term, then lists the content to which each term is assigned. - -```go-html-template {file="layouts/_default/taxonomy.html"} -{{ define "main" }} - <h1>{{ .Title }}</h1> - {{ .Content }} - {{ range .Data.Terms.ByCount }} - <h2><a href="{{ .Page.RelPermalink }}">{{ .Page.LinkTitle }}</a> ({{ .Count }})</h2> - <ul> - {{ range .WeightedPages }} - <li><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></li> - {{ end }} - </ul> - {{ end }} -{{ end }} -``` - -## Display metadata - -Display metadata about each term by creating a corresponding branch bundle in the `content` directory. - -For example, create an "authors" taxonomy: - -{{< code-toggle file=hugo >}} -[taxonomies] -author = 'authors' -{{< /code-toggle >}} - -Then create content with one [branch bundle](g) for each term: - -```text -content/ -└── authors/ - ├── jsmith/ - │ ├── _index.md - │ └── portrait.jpg - └── rjones/ - ├── _index.md - └── portrait.jpg -``` - -Then add front matter to each term page: - -{{< code-toggle file=content/authors/jsmith/_index.md fm=true >}} -title = "John Smith" -affiliation = "University of Chicago" -{{< /code-toggle >}} - -Then create a taxonomy template specific to the "authors" taxonomy: - -```go-html-template {file="layouts/authors/taxonomy.html"} -{{ define "main" }} - <h1>{{ .Title }}</h1> - {{ .Content }} - {{ range .Data.Terms.Alphabetical }} - <h2><a href="{{ .Page.RelPermalink }}">{{ .Page.LinkTitle }}</a></h2> - <p>Affiliation: {{ .Page.Params.Affiliation }}</p> - {{ with .Page.Resources.Get "portrait.jpg" }} - {{ with .Fill "100x100" }} - <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="portrait"> - {{ end }} - {{ end }} - {{ end }} -{{ end }} -``` - -In the example above we list each author including their affiliation and portrait. diff --git a/docs/content/en/templates/term.md b/docs/content/en/templates/term.md deleted file mode 100644 index cf1097e86..000000000 --- a/docs/content/en/templates/term.md +++ /dev/null @@ -1,107 +0,0 @@ ---- -title: Term templates -description: Create a term template to render a list of pages associated with the current term. -categories: [] -keywords: [] -weight: 90 ---- - -The [term](g) template below inherits the site's shell from the [base template], and renders a list of pages associated with the current term. - -[base template]: /templates/types/ - -```go-html-template {file="layouts/_default/term.html"} -{{ define "main" }} - <h1>{{ .Title }}</h1> - {{ .Content }} - {{ range .Pages }} - <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2> - {{ end }} -{{ end }} -``` - -Review the [template lookup order] to select a template path that provides the desired level of specificity. - -[template lookup order]: /templates/lookup-order/#taxonomy-templates - -In the example above, the term will be capitalized if its respective page is not backed by a file. You can disable this in your site configuration: - -{{< code-toggle file=hugo >}} -capitalizeListTitles = false -{{< /code-toggle >}} - -## Data object - -Use these methods on the `Data` object within a term template. - -Singular -: (`string`) Returns the singular name of the taxonomy. - -```go-html-template -{{ .Data.Singular }} → tag -``` - -Plural -: (`string`) Returns the plural name of the taxonomy. - -```go-html-template -{{ .Data.Plural }} → tags -``` - -Term -: (`string`) Returns the name of the term. - -```go-html-template -{{ .Data.Term }} → fiction -``` - -## Display metadata - -Display metadata about each term by creating a corresponding branch bundle in the `content` directory. - -For example, create an "authors" taxonomy: - -{{< code-toggle file=hugo >}} -[taxonomies] -author = 'authors' -{{< /code-toggle >}} - -Then create content with one [branch bundle](g) for each term: - -```text -content/ -└── authors/ - ├── jsmith/ - │ ├── _index.md - │ └── portrait.jpg - └── rjones/ - ├── _index.md - └── portrait.jpg -``` - -Then add front matter to each term page: - -{{< code-toggle file=content/authors/jsmith/_index.md fm=true >}} -title = "John Smith" -affiliation = "University of Chicago" -{{< /code-toggle >}} - -Then create a term template specific to the "authors" taxonomy: - -```go-html-template {file="layouts/authors/term.html"} -{{ define "main" }} - <h1>{{ .Title }}</h1> - <p>Affiliation: {{ .Params.affiliation }}</p> - {{ with .Resources.Get "portrait.jpg" }} - {{ with .Fill "100x100" }} - <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="portrait"> - {{ end }} - {{ end }} - {{ .Content }} - {{ range .Pages }} - <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2> - {{ end }} -{{ end }} -``` - -In the example above we display the author with their affiliation and portrait, then a list of associated content. diff --git a/docs/content/en/templates/types.md b/docs/content/en/templates/types.md index b44d3eb47..8c533a56f 100644 --- a/docs/content/en/templates/types.md +++ b/docs/content/en/templates/types.md @@ -4,7 +4,17 @@ description: Create templates of different types to render your content, resourc categories: [] keywords: [] weight: 30 -aliases: ['/templates/lists/'] +aliases: [ + '/templates/base/', + '/templates/content-view/', + '/templates/home/', + '/templates/lists/', + '/templates/partial/', + '/templates/section/', + '/templates/single/', + '/templates/taxonomy/', + '/templates/term/', +] --- ## Structure @@ -15,24 +25,28 @@ Although your site may not require each of these templates, the example below is ```text layouts/ -├── _default/ -│ ├── _markup/ -│ │ ├── render-image.html <-- render hook -│ │ └── render-link.html <-- render hook -│ ├── baseof.html -│ ├── home.html -│ ├── section.html -│ ├── single.html -│ ├── taxonomy.html -│ └── term.html -├── articles/ -│ └── card.html <-- content view -├── partials/ +├── _markup/ +│ ├── render-image.html <-- render hook +│ └── render-link.html <-- render hook +├── _partials/ │ ├── footer.html │ └── header.html -└── shortcodes/ - ├── audio.html - └── video.html +├── _shortcodes/ +│ ├── audio.html +│ └── video.html +├── books/ +│ ├── page.html +│ └── section.html +├── films/ +│ ├── card.html <-- content view +│ ├── page.html +│ └── section.html +├── baseof.html +├── home.html +├── page.html +├── section.html +├── taxonomy.html +└── term.html ``` Hugo's [template lookup order] determines the template path, allowing you to create unique templates for any page. @@ -44,11 +58,11 @@ The purpose of each template type is described below. ## Base -Base templates reduce duplicate code by wrapping other templates within a shell. +A base template reduces duplicate code by wrapping other templates within a shell. -For example, the base template below calls the [partial] function to include partial templates for the `head`, `header`, and `footer` elements of each page, and it uses the [block] function to include `home`, `single`, `section`, `taxonomy`, and `term` templates within the `main` element of each page. +For example, the base template below calls the [`partial`] function to include partial templates for the `head`, `header`, and `footer` elements of each page, and it calls the [`block`] function to include `home`, `page`, `section`, `taxonomy`, and `term` templates within the `main` element of each page. -```go-html-template {file="layouts/_default/baseof.html"} +```go-html-template {file="layouts/baseof.html"} <!DOCTYPE html> <html lang="{{ or site.Language.LanguageCode }}" dir="{{ or site.Language.LanguageDirection `ltr` }}"> <head> @@ -68,16 +82,16 @@ For example, the base template below calls the [partial] function to include par </html> ``` -Learn more about [base templates](/templates/base/). +The `block` construct above is used to define a set of root templates that are then customized by redefining the block templates within. See [details](/functions/go-template/block/) ## Home -A home page template is used to render your site's home page, and is the only template required for a single-page website. For example, the home page template below inherits the site's shell from the base template and renders the home page content, such as a list of other pages. +A home template renders your site's home page. For example, the home template below inherits the site's shell from the [base template] and renders the home page content, such as a list of other pages. -```go-html-template {file="layouts/_default/home.html"} +```go-html-template {file="layouts/home.html"} {{ define "main" }} {{ .Content }} - {{ range site.RegularPages }} + {{ range .Site.RegularPages }} <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2> {{ end }} {{ end }} @@ -85,30 +99,26 @@ A home page template is used to render your site's home page, and is the only te {{% include "/_common/filter-sort-group.md" %}} -Learn more about [home page templates](/templates/home/). +## Page -## Single - -A single template renders a single page. +A page template renders a regular page. -For example, the single template below inherits the site's shell from the base template, and renders the title and content of each page. +For example, the page template below inherits the site's shell from the [base template] and renders the page title and page content. -```go-html-template {file="layouts/_default/single.html"} +```go-html-template {file="layouts/page.html"} {{ define "main" }} <h1>{{ .Title }}</h1> {{ .Content }} {{ end }} ``` -Learn more about [single templates](/templates/single/). - ## Section -A section template typically renders a list of pages within a section. +A section template renders a list of pages within a section. -For example, the section template below inherits the site's shell from the base template, and renders a list of pages in the current section. +For example, the section template below inherits the site's shell from the [base template] and renders a list of pages in the current section. -```go-html-template {file="layouts/_default/section.html"} +```go-html-template {file="layouts/section.html"} {{ define "main" }} <h1>{{ .Title }}</h1> {{ .Content }} @@ -120,15 +130,13 @@ For example, the section template below inherits the site's shell from the base {{% include "/_common/filter-sort-group.md" %}} -Learn more about [section templates](/templates/section/). - ## Taxonomy A taxonomy template renders a list of terms in a [taxonomy](g). -For example, the taxonomy template below inherits the site's shell from the base template, and renders a list of terms in the current taxonomy. +For example, the taxonomy template below inherits the site's shell from the [base template] and renders a list of terms in the current taxonomy. -```go-html-template {file="layouts/_default/taxonomy.html"} +```go-html-template {file="layouts/taxonomy.html"} {{ define "main" }} <h1>{{ .Title }}</h1> {{ .Content }} @@ -140,15 +148,31 @@ For example, the taxonomy template below inherits the site's shell from the base {{% include "/_common/filter-sort-group.md" %}} -Learn more about [taxonomy templates](/templates/taxonomy/). +Within a taxonomy template, the [`Data`] object provides these taxonomy-specific methods: + +- [`Singular`][taxonomy-singular] +- [`Plural`][taxonomy-plural] +- [`Terms`]. + +The `Terms` method returns a [taxonomy object](g), allowing you to call any of its methods including [`Alphabetical`] and [`ByCount`]. For example, use the `ByCount` method to render a list of terms sorted by the number of pages associated with each term: + +```go-html-template {file="layouts/taxonomy.html"} +{{ define "main" }} + <h1>{{ .Title }}</h1> + {{ .Content }} + {{ range .Data.Terms.ByCount }} + <h2><a href="{{ .Page.RelPermalink }}">{{ .Page.LinkTitle }}</a> ({{ .Count }})</h2> + {{ end }} +{{ end }} +``` ## Term A term template renders a list of pages associated with a [term](g). -For example, the term template below inherits the site's shell from the base template, and renders a list of pages associated with the current term. +For example, the term template below inherits the site's shell from the [base template] and renders a list of pages associated with the current term. -```go-html-template {file="layouts/_default/term.html"} +```go-html-template {file="layouts/term.html"} {{ define "main" }} <h1>{{ .Title }}</h1> {{ .Content }} @@ -160,78 +184,163 @@ For example, the term template below inherits the site's shell from the base tem {{% include "/_common/filter-sort-group.md" %}} -Learn more about [term templates](/templates/term/). +Within a term template, the [`Data`] object provides these term-specific methods: + +- [`Singular`][term-singular] +- [`Plural`][term-plural] +- [`Term`]. + +## Single + +A single template is a fallback for [page templates](#page). If a page template does not exist, Hugo will look for a single template instead. + +Like a page template, a single template renders a regular page. + +For example, the single template below inherits the site's shell from the [base template] and renders the page title and page content. + +```go-html-template {file="layouts/single.html"} +{{ define "main" }} + <h1>{{ .Title }}</h1> + {{ .Content }} +{{ end }} +``` + +## List + +A list template is a fallback for these template types: [home](#home), [section](#section), [taxonomy](#taxonomy), and [term](#term). If one of these template types does not exist, Hugo will look for a list template instead. + +For example, the list template below inherits the site's shell from the [base template] and renders a list of pages: + +```go-html-template {file="layouts/list.html"} +{{ define "main" }} + <h1>{{ .Title }}</h1> + {{ .Content }} + {{ range .Pages }} + <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2> + {{ end }} +{{ end }} +``` + +## All + +An "all" template is a fallback for these template types: [home](#home), [page](#page), [section](#section), [taxonomy](#taxonomy), [term](#term), [single](#single), and [list](#list). If one of these template types does not exist, Hugo will look for an "all" template instead. + +For example, the contrived "all" template below inherits the site's shell from the [base template] and conditionally renders a page based on its page kind: + +```go-html-template {file="layouts/all.html"} +{{ define "main" }} + {{ if eq .Kind "home" }} + {{ .Content }} + {{ range .Site.RegularPages }} + <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2> + {{ end }} + {{ else if eq .Kind "page" }} + <h1>{{ .Title }}</h1> + {{ .Content }} + {{ else if in (slice "section" "taxonomy" "term") .Kind }} + <h1>{{ .Title }}</h1> + {{ .Content }} + {{ range .Pages }} + <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2> + {{ end }} + {{ else }} + {{ errorf "Unsupported page kind: %s" .Kind }} + {{ end }} +{{ end }} +``` ## Partial A partial template is typically used to render a component of your site, though you may also create partial templates that return values. -> [!note] -> Unlike other template types, you cannot create partial templates to target a particular page kind, content type, section, language, or output format. Partial templates do not follow Hugo's [template lookup order]. -For example, the partial template below renders copyright information. +For example, the partial template below renders copyright information: -```go-html-template {file="layouts/partials/footer.html"} +```go-html-template {file="layouts/_partials/footer.html"} <p>Copyright {{ now.Year }}. All rights reserved.</p> ``` -Learn more about [partial templates](/templates/partial/). +Execute the partial template by calling the [`partial`] or [`partialCached`] function, optionally passing context as the second argument: + +```go-html-template {file="layouts/baseof.html"} +{{ partial "footer.html" . }} +``` + +Unlike other template types, partial template selection is based on the file name passed in the partial call. Hugo does not consider the current page kind, content type, logical path, language, or output format when searching for a matching partial template. However, Hugo _does_ apply the same name matching logic it uses for other templates. This means it tries to find the most specific match first, then progressively looks for more general versions if the specific one isn't found. + +For example, with this partial call: + +```go-html-template {file="layouts/baseof.html"} +{{ partial "footer.section.de.html" . }} +``` + +Hugo uses this lookup order to find a matching template: + +1. `layouts/_partials/footer.section.de.html` +1. `layouts/_partials/footer.section.html` +1. `layouts/_partials/footer.de.html` +1. `layouts/_partials/footer.html` + +Partials can also be defined inline within a template. However, it's important to note that the template namespace is global; ensuring unique names for these partials is necessary to prevent conflicts. + +```go-html-template +Value: {{ partial "my-inline-partial.html" . }} + +{{ define "_partials/my-inline-partial.html" }} + {{ $value := 32 }} + {{ return $value }} +{{ end }} +``` ## Content view A content view template is similar to a partial template, invoked by calling the [`Render`] method on a `Page` object. Unlike partial templates, content view templates: -- Automatically inherit the context of the current page -- Follow a lookup order allowing you to target a given content type or section +- Inherit the context of the current page +- Can target any page kind, content type, logical path, language, or output format -For example, the home template below inherits the site's shell from the base template, and renders a card component for each page within the "articles" section of your site. +For example, the home template below inherits the site's shell from the [base template], and renders a card component for each page within the "films" section of your site. -```go-html-template {file="layouts/_default/home.html"} +```go-html-template {file="layouts/home.html"} {{ define "main" }} {{ .Content }} <ul> - {{ range where site.RegularPages "Section" "articles" }} + {{ range where site.RegularPages "Section" "films" }} {{ .Render "card" }} {{ end }} </ul> {{ end }} ``` -```go-html-template {file="layouts/articles/card.html"} +```go-html-template {file="layouts/films/card.html"} <div class="card"> <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2> {{ .Summary }} </div> ``` -Learn more about [content view templates](/templates/content-view/). - ## Render hook A render hook template overrides the conversion of Markdown to HTML. -For example, the render hook template below adds a `rel` attribute to external links. - -```go-html-template {file="layouts/_default/_markup/render-link.html"} -{{- $u := urls.Parse .Destination -}} -<a href="{{ .Destination | safeURL }}" - {{- with .Title }} title="{{ . }}"{{ end -}} - {{- if $u.IsAbs }} rel="external"{{ end -}} -> - {{- with .Text }}{{ . }}{{ end -}} -</a> -{{- /* chomp trailing newline */ -}} +For example, the render hook template below adds an anchor link to the right of each heading. + +```go-html-template {file="layouts/_markup/heading.html"} +<h{{ .Level }} id="{{ .Anchor }}" {{- with .Attributes.class }} class="{{ . }}" {{- end }}> + {{ .Text }} + <a href="#{{ .Anchor }}">#</a> +</h{{ .Level }}> ``` Learn more about [render hook templates](/render-hooks/). ## Shortcode -A shortcode template is used to render a component of your site. Unlike partial templates, shortcode templates are called from content pages. +A shortcode template is used to render a component of your site. Unlike [partial templates](#partial) or [content view templates](#content-view), shortcode templates are called from content pages. For example, the shortcode template below renders an audio element from a [global resource](g). -```go-html-template {file="layouts/shortcodes/audio.html"} +```go-html-template {file="layouts/_shortcodes/audio.html"} {{ with resources.Get (.Get "src") }} <audio controls preload="auto" src="{{ .RelPermalink }}"></audio> {{ end }} @@ -254,8 +363,19 @@ Use other specialized templates to create: - [404 error pages](/templates/404/) - [robots.txt files](/templates/robots/) +[`Alphabetical`]: /methods/taxonomy/alphabetical/ +[`block`]: /functions/go-template/block/ +[`ByCount`]: /methods/taxonomy/bycount/ +[`Data`]: /methods/page/data/ +[`partial`]: /functions/partials/include/ +[`partialCached`]: /functions/partials/includeCached/ [`Render`]: /methods/page/render/ -[block]: /functions/go-template/block/ -[partial]: /functions/partials/include/ -[template lookup order]: /templates/lookup-order/ +[`Taxonomy`]: /methods/taxonomy/ +[`Terms`]: /methods/page/data/#terms +[`Term`]: /methods/page/data/#term +[taxonomy-plural]: /methods/page/data/#plural +[taxonomy-singular]: /methods/page/data/#singular [template lookup order]: /templates/lookup-order/ +[term-plural]: /methods/page/data/#plural-1 +[term-singular]: /methods/page/data/#singular-1 +[base template]: #base diff --git a/docs/content/en/troubleshooting/faq.md b/docs/content/en/troubleshooting/faq.md index 6992af5d3..e1a23610c 100644 --- a/docs/content/en/troubleshooting/faq.md +++ b/docs/content/en/troubleshooting/faq.md @@ -53,10 +53,10 @@ Why is my partial template not rendered as expected? ```go-html-template {{/* incorrect */}} - {{ partial "_internal/pagination.html" }} + {{ partial "pagination.html" }} {{/* correct */}} - {{ partial "_internal/pagination.html" . }} + {{ partial "pagination.html" . }} ``` In a template, what's the difference between `:=` and `=` when assigning values to variables? @@ -84,8 +84,8 @@ Why isn't Hugo's development server detecting file changes? In these cases, instead of monitoring native file system events, use the `--poll` command line flag. For example, to poll the project files every 700 milliseconds, use `--poll 700ms`. -Why is my page Scratch or Store missing a value? -: The [`Scratch`] and [`Store`] methods on a `Page` object allow you to create a [scratch pad](g) on the given page to store and manipulate data. Values are often set within a shortcode, a partial template called by a shortcode, or by a Markdown render hook. In all three cases, the scratch pad values are not determinate until Hugo renders the page content. +Why is my page Store missing a value? +: The [`Store`] method on a `Page` object allows you to create a [scratch pad](g) on the given page to store and manipulate data. Values are often set within a shortcode, a partial template called by a shortcode, or by a Markdown render hook. In all three cases, the scratch pad values are not determinate until Hugo renders the page content. If you need to access a scratch pad value from a parent template, and the parent template has not yet rendered the page content, you can trigger content rendering by assigning the returned value to a [noop](g) variable: @@ -104,7 +104,6 @@ Which page methods trigger content rendering? [`Paginate`]: /methods/page/paginate/ [`Paginator`]: /methods/page/paginator/ -[`Scratch`]: /methods/page/scratch [`Store`]: /methods/page/store [forum]: https://discourse.gohugo.io [forum]: https://discourse.gohugo.io diff --git a/docs/content/en/troubleshooting/performance.md b/docs/content/en/troubleshooting/performance.md index e366eba81..f22758646 100644 --- a/docs/content/en/troubleshooting/performance.md +++ b/docs/content/en/troubleshooting/performance.md @@ -39,24 +39,22 @@ Template Metrics: cumulative average maximum cache percent cached total duration duration duration potential cached count count template ---------- -------- -------- --------- ------- ------ ----- -------- - 36.037476822s 135.990478ms 225.765245ms 11 0 0 265 partials/head.html - 35.920040902s 164.018451ms 233.475072ms 0 0 0 219 articles/single.html - 34.163268129s 128.917992ms 224.816751ms 23 0 0 265 partials/head/meta/opengraph.html - 1.041227437s 3.92916ms 186.303376ms 47 0 0 265 partials/head/meta/schema.html - 805.628827ms 27.780304ms 114.678523ms 0 0 0 29 _default/list.html - 624.08354ms 15.221549ms 108.420729ms 8 0 0 41 partials/utilities/render-page-collection.html - 545.968801ms 775.523µs 105.045775ms 0 0 0 704 _default/summary.html - 334.680981ms 1.262947ms 127.412027ms 100 0 0 265 partials/head/js.html - 272.763205ms 2.050851ms 24.371757ms 0 0 0 133 _default/_markup/render-codeblock.html - 230.490038ms 8.865001ms 177.4615ms 0 0 0 26 shortcodes/template.html - 176.921913ms 176.921913ms 176.921913ms 0 0 0 1 examples.tmpl - 163.951469ms 14.904679ms 70.267953ms 0 0 0 11 articles/list.html - 153.07021ms 577.623µs 73.593597ms 100 0 0 265 partials/head/init.html - 150.910984ms 150.910984ms 150.910984ms 0 0 0 1 _default/single.html - 146.785804ms 146.785804ms 146.785804ms 0 0 0 1 _default/contact.html + 36.037476822s 135.990478ms 225.765245ms 11 0 0 265 _partials/head.html + 35.920040902s 164.018451ms 233.475072ms 0 0 0 219 articles/page.html + 34.163268129s 128.917992ms 224.816751ms 23 0 0 265 _partials/head/meta/opengraph.html + 1.041227437s 3.92916ms 186.303376ms 47 0 0 265 _partials/head/meta/schema.html + 805.628827ms 27.780304ms 114.678523ms 0 0 0 29 section.html + 624.08354ms 15.221549ms 108.420729ms 8 0 0 41 _partials/utilities/render-page-collection.html + 545.968801ms 775.523µs 105.045775ms 0 0 0 704 summary.html + 334.680981ms 1.262947ms 127.412027ms 100 0 0 265 _partials/head/js.html + 272.763205ms 2.050851ms 24.371757ms 0 0 0 133 _markup/render-codeblock.html + 163.951469ms 14.904679ms 70.267953ms 0 0 0 11 articles/section.html + 153.07021ms 577.623µs 73.593597ms 100 0 0 265 _partials/head/init.html + 150.910984ms 150.910984ms 150.910984ms 0 0 0 1 page.html + 146.785804ms 146.785804ms 146.785804ms 0 0 0 1 contact.html 115.364617ms 115.364617ms 115.364617ms 0 0 0 1 authors/term.html - 87.392071ms 329.781µs 10.687132ms 100 0 0 265 partials/head/css.html - 86.803122ms 86.803122ms 86.803122ms 0 0 0 1 _default/home.html + 87.392071ms 329.781µs 10.687132ms 100 0 0 265 _partials/head/css.html + 86.803122ms 86.803122ms 86.803122ms 0 0 0 1 home.html ``` From left to right, the columns represent: diff --git a/docs/data/docs.yaml b/docs/data/docs.yaml index 0db4c7fe9..62c8919a0 100644 --- a/docs/data/docs.yaml +++ b/docs/data/docs.yaml @@ -414,6 +414,9 @@ chroma: - j Name: J - Aliases: + - janet + Name: Janet + - Aliases: - java Name: Java - Aliases: @@ -440,6 +443,10 @@ chroma: - kotlin Name: Kotlin - Aliases: + - lean4 + - lean + Name: Lean4 + - Aliases: - lighty - lighttpd Name: Lighttpd configuration file @@ -448,6 +455,7 @@ chroma: Name: LLVM - Aliases: - lua + - luau Name: Lua - Aliases: - make @@ -501,6 +509,10 @@ chroma: - m2 Name: Modula-2 - Aliases: + - mojo + - "\U0001F525" + Name: Mojo + - Aliases: - monkeyc Name: MonkeyC - Aliases: @@ -724,6 +736,10 @@ chroma: - arexx Name: Rexx - Aliases: + - SQLRPGLE + - RPG IV + Name: RPGLE + - Aliases: - spec Name: RPMSpec - Aliases: @@ -844,6 +860,7 @@ chroma: - Aliases: - terraform - tf + - hcl Name: Terraform - Aliases: - tex @@ -959,6 +976,7 @@ chroma: - zig Name: Zig styles: + - RPGLE - abap - algol - algol_nu @@ -1042,7 +1060,7 @@ config: low: 0s archeTypeDir: archetypes assetDir: assets - author: {} + author: null baseURL: "" build: buildStats: @@ -1148,7 +1166,7 @@ config: hasCJKLanguage: false i18nDir: i18n ignoreCache: false - ignoreFiles: [] + ignoreFiles: null ignoreLogs: null ignoreVendorPaths: "" imaging: @@ -1401,6 +1419,10 @@ config: delimiter: . suffixes: - ts + text/x-gotmpl: + delimiter: . + suffixes: + - gotmpl text/x-sass: delimiter: . suffixes: @@ -1537,6 +1559,34 @@ config: noChmod: false noTimes: false outputFormats: + "404": + baseName: "" + isHTML: true + isPlainText: false + mediaType: text/html + noUgly: false + notAlternative: true + path: "" + permalinkable: true + protocol: "" + rel: "" + root: false + ugly: true + weight: 0 + alias: + baseName: "" + isHTML: true + isPlainText: false + mediaType: text/html + noUgly: false + notAlternative: false + path: "" + permalinkable: false + protocol: "" + rel: "" + root: false + ugly: true + weight: 0 amp: baseName: index isHTML: true @@ -1593,6 +1643,20 @@ config: root: false ugly: false weight: 0 + gotmpl: + baseName: "" + isHTML: false + isPlainText: true + mediaType: text/x-gotmpl + noUgly: false + notAlternative: true + path: "" + permalinkable: false + protocol: "" + rel: "" + root: false + ugly: false + weight: 0 html: baseName: index isHTML: true @@ -1677,6 +1741,20 @@ config: root: false ugly: true weight: 0 + sitemapindex: + baseName: sitemap + isHTML: false + isPlainText: false + mediaType: application/xml + noUgly: false + notAlternative: false + path: "" + permalinkable: false + protocol: "" + rel: sitemap + root: true + ugly: true + weight: 0 webappmanifest: baseName: manifest isHTML: false @@ -1808,7 +1886,7 @@ config: - (?i)GET|POST urls: - .* - segments: {} + segments: null server: headers: null redirects: @@ -1860,10 +1938,10 @@ config: theme: null themesDir: themes timeZone: "" - timeout: 30s + timeout: 60s title: "" titleCaseStyle: AP - uglyURLs: false + uglyURLs: null workingDir: "" config_helpers: mergeStrategy: @@ -1930,535 +2008,7 @@ config_helpers: taxonomies: _merge: none output: - layouts: - - Example: Single page in "posts" section - Kind: page - OutputFormat: html - Suffix: html - Template Lookup Order: - - layouts/posts/single.html.html - - layouts/posts/single.html - - layouts/_default/single.html.html - - layouts/_default/single.html - - Example: Base template for single page in "posts" section - Kind: page - OutputFormat: html - Suffix: html - Template Lookup Order: - - layouts/posts/single-baseof.html.html - - layouts/posts/baseof.html.html - - layouts/posts/single-baseof.html - - layouts/posts/baseof.html - - layouts/_default/single-baseof.html.html - - layouts/_default/baseof.html.html - - layouts/_default/single-baseof.html - - layouts/_default/baseof.html - - Example: Single page in "posts" section with layout set to "demolayout" - Kind: page - OutputFormat: html - Suffix: html - Template Lookup Order: - - layouts/posts/demolayout.html.html - - layouts/posts/single.html.html - - layouts/posts/demolayout.html - - layouts/posts/single.html - - layouts/_default/demolayout.html.html - - layouts/_default/single.html.html - - layouts/_default/demolayout.html - - layouts/_default/single.html - - Example: Base template for single page in "posts" section with layout set to "demolayout" - Kind: page - OutputFormat: html - Suffix: html - Template Lookup Order: - - layouts/posts/demolayout-baseof.html.html - - layouts/posts/single-baseof.html.html - - layouts/posts/baseof.html.html - - layouts/posts/demolayout-baseof.html - - layouts/posts/single-baseof.html - - layouts/posts/baseof.html - - layouts/_default/demolayout-baseof.html.html - - layouts/_default/single-baseof.html.html - - layouts/_default/baseof.html.html - - layouts/_default/demolayout-baseof.html - - layouts/_default/single-baseof.html - - layouts/_default/baseof.html - - Example: AMP single page in "posts" section - Kind: page - OutputFormat: amp - Suffix: html - Template Lookup Order: - - layouts/posts/single.amp.html - - layouts/posts/single.html - - layouts/_default/single.amp.html - - layouts/_default/single.html - - Example: AMP single page in "posts" section, French language - Kind: page - OutputFormat: amp - Suffix: html - Template Lookup Order: - - layouts/posts/single.fr.amp.html - - layouts/posts/single.amp.html - - layouts/posts/single.fr.html - - layouts/posts/single.html - - layouts/_default/single.fr.amp.html - - layouts/_default/single.amp.html - - layouts/_default/single.fr.html - - layouts/_default/single.html - - Example: Home page - Kind: home - OutputFormat: html - Suffix: html - Template Lookup Order: - - layouts/index.html.html - - layouts/home.html.html - - layouts/list.html.html - - layouts/index.html - - layouts/home.html - - layouts/list.html - - layouts/_default/index.html.html - - layouts/_default/home.html.html - - layouts/_default/list.html.html - - layouts/_default/index.html - - layouts/_default/home.html - - layouts/_default/list.html - - Example: Base template for home page - Kind: home - OutputFormat: html - Suffix: html - Template Lookup Order: - - layouts/index-baseof.html.html - - layouts/home-baseof.html.html - - layouts/list-baseof.html.html - - layouts/baseof.html.html - - layouts/index-baseof.html - - layouts/home-baseof.html - - layouts/list-baseof.html - - layouts/baseof.html - - layouts/_default/index-baseof.html.html - - layouts/_default/home-baseof.html.html - - layouts/_default/list-baseof.html.html - - layouts/_default/baseof.html.html - - layouts/_default/index-baseof.html - - layouts/_default/home-baseof.html - - layouts/_default/list-baseof.html - - layouts/_default/baseof.html - - Example: Home page with type set to "demotype" - Kind: home - OutputFormat: html - Suffix: html - Template Lookup Order: - - layouts/demotype/index.html.html - - layouts/demotype/home.html.html - - layouts/demotype/list.html.html - - layouts/demotype/index.html - - layouts/demotype/home.html - - layouts/demotype/list.html - - layouts/index.html.html - - layouts/home.html.html - - layouts/list.html.html - - layouts/index.html - - layouts/home.html - - layouts/list.html - - layouts/_default/index.html.html - - layouts/_default/home.html.html - - layouts/_default/list.html.html - - layouts/_default/index.html - - layouts/_default/home.html - - layouts/_default/list.html - - Example: Base template for home page with type set to "demotype" - Kind: home - OutputFormat: html - Suffix: html - Template Lookup Order: - - layouts/demotype/index-baseof.html.html - - layouts/demotype/home-baseof.html.html - - layouts/demotype/list-baseof.html.html - - layouts/demotype/baseof.html.html - - layouts/demotype/index-baseof.html - - layouts/demotype/home-baseof.html - - layouts/demotype/list-baseof.html - - layouts/demotype/baseof.html - - layouts/index-baseof.html.html - - layouts/home-baseof.html.html - - layouts/list-baseof.html.html - - layouts/baseof.html.html - - layouts/index-baseof.html - - layouts/home-baseof.html - - layouts/list-baseof.html - - layouts/baseof.html - - layouts/_default/index-baseof.html.html - - layouts/_default/home-baseof.html.html - - layouts/_default/list-baseof.html.html - - layouts/_default/baseof.html.html - - layouts/_default/index-baseof.html - - layouts/_default/home-baseof.html - - layouts/_default/list-baseof.html - - layouts/_default/baseof.html - - Example: Home page with layout set to "demolayout" - Kind: home - OutputFormat: html - Suffix: html - Template Lookup Order: - - layouts/demolayout.html.html - - layouts/index.html.html - - layouts/home.html.html - - layouts/list.html.html - - layouts/demolayout.html - - layouts/index.html - - layouts/home.html - - layouts/list.html - - layouts/_default/demolayout.html.html - - layouts/_default/index.html.html - - layouts/_default/home.html.html - - layouts/_default/list.html.html - - layouts/_default/demolayout.html - - layouts/_default/index.html - - layouts/_default/home.html - - layouts/_default/list.html - - Example: AMP home, French language - Kind: home - OutputFormat: amp - Suffix: html - Template Lookup Order: - - layouts/index.fr.amp.html - - layouts/home.fr.amp.html - - layouts/list.fr.amp.html - - layouts/index.amp.html - - layouts/home.amp.html - - layouts/list.amp.html - - layouts/index.fr.html - - layouts/home.fr.html - - layouts/list.fr.html - - layouts/index.html - - layouts/home.html - - layouts/list.html - - layouts/_default/index.fr.amp.html - - layouts/_default/home.fr.amp.html - - layouts/_default/list.fr.amp.html - - layouts/_default/index.amp.html - - layouts/_default/home.amp.html - - layouts/_default/list.amp.html - - layouts/_default/index.fr.html - - layouts/_default/home.fr.html - - layouts/_default/list.fr.html - - layouts/_default/index.html - - layouts/_default/home.html - - layouts/_default/list.html - - Example: JSON home - Kind: home - OutputFormat: json - Suffix: json - Template Lookup Order: - - layouts/index.json.json - - layouts/home.json.json - - layouts/list.json.json - - layouts/index.json - - layouts/home.json - - layouts/list.json - - layouts/_default/index.json.json - - layouts/_default/home.json.json - - layouts/_default/list.json.json - - layouts/_default/index.json - - layouts/_default/home.json - - layouts/_default/list.json - - Example: RSS home - Kind: home - OutputFormat: rss - Suffix: xml - Template Lookup Order: - - layouts/index.rss.xml - - layouts/home.rss.xml - - layouts/rss.xml - - layouts/list.rss.xml - - layouts/index.xml - - layouts/home.xml - - layouts/list.xml - - layouts/_default/index.rss.xml - - layouts/_default/home.rss.xml - - layouts/_default/rss.xml - - layouts/_default/list.rss.xml - - layouts/_default/index.xml - - layouts/_default/home.xml - - layouts/_default/list.xml - - layouts/_internal/_default/rss.xml - - Example: Section list for "posts" - Kind: section - OutputFormat: html - Suffix: html - Template Lookup Order: - - layouts/posts/posts.html.html - - layouts/posts/section.html.html - - layouts/posts/list.html.html - - layouts/posts/posts.html - - layouts/posts/section.html - - layouts/posts/list.html - - layouts/section/posts.html.html - - layouts/section/section.html.html - - layouts/section/list.html.html - - layouts/section/posts.html - - layouts/section/section.html - - layouts/section/list.html - - layouts/_default/posts.html.html - - layouts/_default/section.html.html - - layouts/_default/list.html.html - - layouts/_default/posts.html - - layouts/_default/section.html - - layouts/_default/list.html - - Example: Section list for "posts" with type set to "blog" - Kind: section - OutputFormat: html - Suffix: html - Template Lookup Order: - - layouts/blog/posts.html.html - - layouts/blog/section.html.html - - layouts/blog/list.html.html - - layouts/blog/posts.html - - layouts/blog/section.html - - layouts/blog/list.html - - layouts/posts/posts.html.html - - layouts/posts/section.html.html - - layouts/posts/list.html.html - - layouts/posts/posts.html - - layouts/posts/section.html - - layouts/posts/list.html - - layouts/section/posts.html.html - - layouts/section/section.html.html - - layouts/section/list.html.html - - layouts/section/posts.html - - layouts/section/section.html - - layouts/section/list.html - - layouts/_default/posts.html.html - - layouts/_default/section.html.html - - layouts/_default/list.html.html - - layouts/_default/posts.html - - layouts/_default/section.html - - layouts/_default/list.html - - Example: Section list for "posts" with layout set to "demolayout" - Kind: section - OutputFormat: html - Suffix: html - Template Lookup Order: - - layouts/posts/demolayout.html.html - - layouts/posts/posts.html.html - - layouts/posts/section.html.html - - layouts/posts/list.html.html - - layouts/posts/demolayout.html - - layouts/posts/posts.html - - layouts/posts/section.html - - layouts/posts/list.html - - layouts/section/demolayout.html.html - - layouts/section/posts.html.html - - layouts/section/section.html.html - - layouts/section/list.html.html - - layouts/section/demolayout.html - - layouts/section/posts.html - - layouts/section/section.html - - layouts/section/list.html - - layouts/_default/demolayout.html.html - - layouts/_default/posts.html.html - - layouts/_default/section.html.html - - layouts/_default/list.html.html - - layouts/_default/demolayout.html - - layouts/_default/posts.html - - layouts/_default/section.html - - layouts/_default/list.html - - Example: Section list for "posts" - Kind: section - OutputFormat: rss - Suffix: xml - Template Lookup Order: - - layouts/posts/section.rss.xml - - layouts/posts/rss.xml - - layouts/posts/list.rss.xml - - layouts/posts/section.xml - - layouts/posts/list.xml - - layouts/section/section.rss.xml - - layouts/section/rss.xml - - layouts/section/list.rss.xml - - layouts/section/section.xml - - layouts/section/list.xml - - layouts/_default/section.rss.xml - - layouts/_default/rss.xml - - layouts/_default/list.rss.xml - - layouts/_default/section.xml - - layouts/_default/list.xml - - layouts/_internal/_default/rss.xml - - Example: Taxonomy list for "categories" - Kind: taxonomy - OutputFormat: html - Suffix: html - Template Lookup Order: - - layouts/categories/category.terms.html.html - - layouts/categories/terms.html.html - - layouts/categories/taxonomy.html.html - - layouts/categories/list.html.html - - layouts/categories/category.terms.html - - layouts/categories/terms.html - - layouts/categories/taxonomy.html - - layouts/categories/list.html - - layouts/category/category.terms.html.html - - layouts/category/terms.html.html - - layouts/category/taxonomy.html.html - - layouts/category/list.html.html - - layouts/category/category.terms.html - - layouts/category/terms.html - - layouts/category/taxonomy.html - - layouts/category/list.html - - layouts/taxonomy/category.terms.html.html - - layouts/taxonomy/terms.html.html - - layouts/taxonomy/taxonomy.html.html - - layouts/taxonomy/list.html.html - - layouts/taxonomy/category.terms.html - - layouts/taxonomy/terms.html - - layouts/taxonomy/taxonomy.html - - layouts/taxonomy/list.html - - layouts/_default/category.terms.html.html - - layouts/_default/terms.html.html - - layouts/_default/taxonomy.html.html - - layouts/_default/list.html.html - - layouts/_default/category.terms.html - - layouts/_default/terms.html - - layouts/_default/taxonomy.html - - layouts/_default/list.html - - Example: Taxonomy list for "categories" - Kind: taxonomy - OutputFormat: rss - Suffix: xml - Template Lookup Order: - - layouts/categories/category.terms.rss.xml - - layouts/categories/terms.rss.xml - - layouts/categories/taxonomy.rss.xml - - layouts/categories/rss.xml - - layouts/categories/list.rss.xml - - layouts/categories/category.terms.xml - - layouts/categories/terms.xml - - layouts/categories/taxonomy.xml - - layouts/categories/list.xml - - layouts/category/category.terms.rss.xml - - layouts/category/terms.rss.xml - - layouts/category/taxonomy.rss.xml - - layouts/category/rss.xml - - layouts/category/list.rss.xml - - layouts/category/category.terms.xml - - layouts/category/terms.xml - - layouts/category/taxonomy.xml - - layouts/category/list.xml - - layouts/taxonomy/category.terms.rss.xml - - layouts/taxonomy/terms.rss.xml - - layouts/taxonomy/taxonomy.rss.xml - - layouts/taxonomy/rss.xml - - layouts/taxonomy/list.rss.xml - - layouts/taxonomy/category.terms.xml - - layouts/taxonomy/terms.xml - - layouts/taxonomy/taxonomy.xml - - layouts/taxonomy/list.xml - - layouts/_default/category.terms.rss.xml - - layouts/_default/terms.rss.xml - - layouts/_default/taxonomy.rss.xml - - layouts/_default/rss.xml - - layouts/_default/list.rss.xml - - layouts/_default/category.terms.xml - - layouts/_default/terms.xml - - layouts/_default/taxonomy.xml - - layouts/_default/list.xml - - layouts/_internal/_default/rss.xml - - Example: Term list for "categories" - Kind: term - OutputFormat: html - Suffix: html - Template Lookup Order: - - layouts/categories/term.html.html - - layouts/categories/category.html.html - - layouts/categories/taxonomy.html.html - - layouts/categories/list.html.html - - layouts/categories/term.html - - layouts/categories/category.html - - layouts/categories/taxonomy.html - - layouts/categories/list.html - - layouts/term/term.html.html - - layouts/term/category.html.html - - layouts/term/taxonomy.html.html - - layouts/term/list.html.html - - layouts/term/term.html - - layouts/term/category.html - - layouts/term/taxonomy.html - - layouts/term/list.html - - layouts/taxonomy/term.html.html - - layouts/taxonomy/category.html.html - - layouts/taxonomy/taxonomy.html.html - - layouts/taxonomy/list.html.html - - layouts/taxonomy/term.html - - layouts/taxonomy/category.html - - layouts/taxonomy/taxonomy.html - - layouts/taxonomy/list.html - - layouts/category/term.html.html - - layouts/category/category.html.html - - layouts/category/taxonomy.html.html - - layouts/category/list.html.html - - layouts/category/term.html - - layouts/category/category.html - - layouts/category/taxonomy.html - - layouts/category/list.html - - layouts/_default/term.html.html - - layouts/_default/category.html.html - - layouts/_default/taxonomy.html.html - - layouts/_default/list.html.html - - layouts/_default/term.html - - layouts/_default/category.html - - layouts/_default/taxonomy.html - - layouts/_default/list.html - - Example: Term list for "categories" - Kind: term - OutputFormat: rss - Suffix: xml - Template Lookup Order: - - layouts/categories/term.rss.xml - - layouts/categories/category.rss.xml - - layouts/categories/taxonomy.rss.xml - - layouts/categories/rss.xml - - layouts/categories/list.rss.xml - - layouts/categories/term.xml - - layouts/categories/category.xml - - layouts/categories/taxonomy.xml - - layouts/categories/list.xml - - layouts/term/term.rss.xml - - layouts/term/category.rss.xml - - layouts/term/taxonomy.rss.xml - - layouts/term/rss.xml - - layouts/term/list.rss.xml - - layouts/term/term.xml - - layouts/term/category.xml - - layouts/term/taxonomy.xml - - layouts/term/list.xml - - layouts/taxonomy/term.rss.xml - - layouts/taxonomy/category.rss.xml - - layouts/taxonomy/taxonomy.rss.xml - - layouts/taxonomy/rss.xml - - layouts/taxonomy/list.rss.xml - - layouts/taxonomy/term.xml - - layouts/taxonomy/category.xml - - layouts/taxonomy/taxonomy.xml - - layouts/taxonomy/list.xml - - layouts/category/term.rss.xml - - layouts/category/category.rss.xml - - layouts/category/taxonomy.rss.xml - - layouts/category/rss.xml - - layouts/category/list.rss.xml - - layouts/category/term.xml - - layouts/category/category.xml - - layouts/category/taxonomy.xml - - layouts/category/list.xml - - layouts/_default/term.rss.xml - - layouts/_default/category.rss.xml - - layouts/_default/taxonomy.rss.xml - - layouts/_default/rss.xml - - layouts/_default/list.rss.xml - - layouts/_default/term.xml - - layouts/_default/category.xml - - layouts/_default/taxonomy.xml - - layouts/_default/list.xml - - layouts/_internal/_default/rss.xml + layouts: {} tpl: funcs: cast: @@ -3631,6 +3181,13 @@ tpl: Examples: - - '{{ math.Max 1 2 }}' - "2" + MaxInt64: + Aliases: null + Args: null + Description: MaxInt64 returns the maximum value for a signed 64-bit integer. + Examples: + - - '{{ math.MaxInt64 }}' + - "9223372036854775807" Min: Aliases: null Args: @@ -4596,6 +4153,11 @@ tpl: - - '{{ "With [Markdown](/markdown) inside." | markdownify | truncate 14 }}' - With <a href="/markdown">Markdown …</a> templates: + Current: + Aliases: null + Args: null + Description: "" + Examples: null Defer: Aliases: null Args: @@ -4663,6 +4225,11 @@ tpl: Examples: - - 'dateFormat: {{ dateFormat "Monday, Jan 2, 2006" "2015-01-21" }}' - 'dateFormat: Wednesday, Jan 21, 2015' + In: + Aliases: null + Args: null + Description: "" + Examples: null Now: Aliases: - now @@ -4773,6 +4340,11 @@ tpl: Examples: - - '{{ plainify "Hello <strong>world</strong>, gophers!" }}' - Hello world, gophers! + PortableText: + Aliases: null + Args: null + Description: "" + Examples: null Remarshal: Aliases: null Args: diff --git a/docs/data/sponsors.toml b/docs/data/sponsors.toml index 705ca9746..033042e93 100644 --- a/docs/data/sponsors.toml +++ b/docs/data/sponsors.toml @@ -1,22 +1,21 @@ [[banners]] - name = "Linode" - link = "https://www.linode.com/" - logo = "images/sponsors/linode-logo.svg" - utm_campaign = "hugosponsor" - bgcolor = "#ffffff" + name = "Linode" + link = "https://www.linode.com/" + logo = "images/sponsors/linode-logo.svg" + utm_campaign = "hugosponsor" + bgcolor = "#ffffff" [[banners]] - name = "GoLand" - title = "The complete IDE crafted for professional Go developers." - no_query_params = true - link = "https://www.jetbrains.com/go/?utm_source=OSS&utm_medium=referral&utm_campaign=hugo" - logo = "images/sponsors/goland.svg" - bgcolor = "#f4f4f4" + name = "GoLand" + title = "The complete IDE crafted for professional Go developers." + no_query_params = true + link = "https://www.jetbrains.com/go/?utm_source=OSS&utm_medium=referral&utm_campaign=hugo" + logo = "images/sponsors/goland.svg" + bgcolor = "#f4f4f4" [[banners]] - name = "Your Company?" - link = "https://bep.is/en/hugo-sponsor-2023-01/" - utm_campaign = "hugosponsor" - show_on_hover = true - bgcolor = "#4e4f4f" - link_attr = "style='color: #ffffff; font-weight: bold; text-decoration: none; text-align: center'" + name = "PinMe" + link = "https://pinme.eth.limo/?s=hugo" + logo = "images/sponsors/logo-pinme.svg" + no_query_params = true + bgcolor = "#fafafa" diff --git a/docs/hugo.toml b/docs/hugo.toml index e8373a87c..5e0b697ef 100644 --- a/docs/hugo.toml +++ b/docs/hugo.toml @@ -8,164 +8,179 @@ title = "Hugo" # We do redirects via Netlify's _redirects file, generated by Hugo (see "outputs" below). disableAliases = true +# See https://github.com/gohugoio/hugo/issues/13806. +ignoreLogs = ['warning-frontmatter-params-overrides'] + [build] - [build.buildStats] - disableIDs = true - enable = true - [[build.cachebusters]] - source = "assets/notwatching/hugo_stats\\.json" - target = "css" - [[build.cachebusters]] - source = "(postcss|tailwind)\\.config\\.js" - target = "css" + [build.buildStats] + disableIDs = true + enable = true + [[build.cachebusters]] + source = "assets/notwatching/hugo_stats\\.json" + target = "css" + [[build.cachebusters]] + source = "(postcss|tailwind)\\.config\\.js" + target = "css" [caches] - [caches.images] - dir = ":cacheDir/images" - maxAge = "1440h" - [caches.getresource] - dir = ':cacheDir/:project' - maxAge = "1h" - -[cascade] - [cascade.params] - hide_in_this_section = true - show_publish_date = true - [cascade.target] - kind = 'page' - path = '{/news/**}' + [caches.images] + dir = ":cacheDir/images" + maxAge = "1440h" + [caches.getresource] + dir = ':cacheDir/:project' + maxAge = "1h" + +[[cascade]] + [cascade.params] + hide_in_this_section = true + show_publish_date = true + [cascade.target] + kind = 'page' + path = '{/news/**}' +[[cascade]] + [cascade.params] + searchable = true + [cascade.target] + kind = 'page' +[[cascade]] + [cascade.params] + searchable = false + [cascade.target] + kind = '{home,section,taxonomy,term}' [frontmatter] - date = ['date'] # do not add publishdate; it will affect page sorting - expiryDate = ['expirydate'] - lastmod = [':git', 'lastmod', 'publishdate', 'date'] - publishDate = ['publishdate', 'date'] + date = ['date'] # do not add publishdate; it will affect page sorting + expiryDate = ['expirydate'] + lastmod = [':git', 'lastmod', 'publishdate', 'date'] + publishDate = ['publishdate', 'date'] [languages] - [languages.en] - languageCode = "en-US" - languageName = "English" - weight = 1 + [languages.en] + languageCode = "en-US" + languageName = "English" + weight = 1 [markup] - [markup.goldmark] - [markup.goldmark.extensions] - [markup.goldmark.extensions.typographer] - disable = false - [markup.goldmark.extensions.passthrough] - enable = true - [markup.goldmark.extensions.passthrough.delimiters] - block = [['\[', '\]'], ['$$', '$$']] - inline = [['\(', '\)']] - [markup.goldmark.parser] - autoDefinitionTermID = true - [markup.goldmark.parser.attribute] - block = true - [markup.highlight] - lineNumbersInTable = false - noClasses = false - style = 'solarized-dark' - wrapperClass = 'highlight not-prose' + [markup.goldmark] + [markup.goldmark.extensions] + [markup.goldmark.extensions.typographer] + disable = false + [markup.goldmark.extensions.passthrough] + enable = true + [markup.goldmark.extensions.passthrough.delimiters] + block = [['\[', '\]'], ['$$', '$$']] + inline = [['\(', '\)']] + [markup.goldmark.parser] + autoDefinitionTermID = true + [markup.goldmark.parser.attribute] + block = true + [markup.highlight] + lineNumbersInTable = false + noClasses = false + style = 'solarized-dark' + wrapperClass = 'highlight not-prose' [mediaTypes] - [mediaTypes."text/netlify"] - delimiter = "" + [mediaTypes."text/netlify"] + delimiter = "" [module] - [module.hugoVersion] - min = "0.144.0" - [[module.mounts]] - source = "assets" - target = "assets" - [[module.mounts]] - lang = 'en' - source = 'content/en' - target = 'content' - [[module.mounts]] - disableWatch = true - source = "hugo_stats.json" - target = "assets/notwatching/hugo_stats.json" + [module.hugoVersion] + min = "0.144.0" + [[module.mounts]] + source = "assets" + target = "assets" + [[module.mounts]] + lang = 'en' + source = 'content/en' + target = 'content' + [[module.mounts]] + disableWatch = true + source = "hugo_stats.json" + target = "assets/notwatching/hugo_stats.json" [outputFormats] - [outputFormats.redir] - baseName = "_redirects" - isPlainText = true - mediatype = "text/netlify" - [outputFormats.headers] - baseName = "_headers" - isPlainText = true - mediatype = "text/netlify" - notAlternative = true + [outputFormats.redir] + baseName = "_redirects" + isPlainText = true + mediatype = "text/netlify" + [outputFormats.headers] + baseName = "_headers" + isPlainText = true + mediatype = "text/netlify" + notAlternative = true [outputs] - home = ["html", "rss", "redir", "headers"] - page = ["html"] - section = ["html"] - taxonomy = ["html"] - term = ["html"] + home = ["html", "rss", "redir", "headers"] + page = ["html"] + section = ["html"] + taxonomy = ["html"] + term = ["html"] [params] - description = "The world’s fastest framework for building websites" - ghrepo = "https://github.com/gohugoio/hugoDocs/" - [params.render_hooks.link] - errorLevel = 'warning' # ignore (default), warning, or error (fails the build) + description = "The world’s fastest framework for building websites" + ghrepo = "https://github.com/gohugoio/hugoDocs/" + [params.render_hooks.link] + errorLevel = 'warning' # ignore (default), warning, or error (fails the build) + [params.social.mastodon] + url = "https://fosstodon.org/@gohugoio" [related] - includeNewer = true - threshold = 80 - toLower = true - [[related.indices]] - name = 'keywords' - weight = 1 + includeNewer = true + threshold = 80 + toLower = true + [[related.indices]] + name = 'keywords' + weight = 1 [security] - [security.funcs] - getenv = ['^HUGO_', '^REPOSITORY_URL$', '^BRANCH$'] + [security.funcs] + getenv = ['^HUGO_', '^REPOSITORY_URL$', '^BRANCH$'] [server] - [[server.headers]] - for = "/*" - [server.headers.values] - X-Frame-Options = "DENY" - X-XSS-Protection = "1; mode=block" - X-Content-Type-Options = "nosniff" - Referrer-Policy = "no-referrer" - [[server.headers]] - for = "/**.{css,js}" + [[server.headers]] + for = "/*" + [server.headers.values] + X-Frame-Options = "DENY" + X-XSS-Protection = "1; mode=block" + X-Content-Type-Options = "nosniff" + Referrer-Policy = "no-referrer" + [[server.headers]] + for = "/**.{css,js}" [services] - [services.googleAnalytics] - ID = 'G-MBZGKNMDWC' + [services.googleAnalytics] + ID = 'G-MBZGKNMDWC' [taxonomies] -category = 'categories' + category = 'categories' ######## GLOBAL ITEMS TO BE SHARED WITH THE HUGO SITES ######## [menus] - [[menus.global]] - identifier = 'news' - name = 'News' - pageRef = '/news/' - weight = 1 - [[menus.global]] - identifier = 'docs' - name = 'Docs' - url = '/documentation/' - weight = 5 - [[menus.global]] - identifier = 'themes' - name = 'Themes' - url = 'https://themes.gohugo.io/' - weight = 10 - [[menus.global]] - identifier = 'community' - name = 'Community' - post = 'external' - url = 'https://discourse.gohugo.io/' - weight = 150 - [[menus.global]] - identifier = 'github' - name = 'GitHub' - post = 'external' - url = 'https://github.com/gohugoio/hugo' - weight = 200 + [[menus.global]] + identifier = 'news' + name = 'News' + pageRef = '/news/' + weight = 1 + [[menus.global]] + identifier = 'docs' + name = 'Docs' + url = '/documentation/' + weight = 5 + [[menus.global]] + identifier = 'themes' + name = 'Themes' + url = 'https://themes.gohugo.io/' + weight = 10 + [[menus.global]] + identifier = 'community' + name = 'Community' + post = 'external' + url = 'https://discourse.gohugo.io/' + weight = 150 + [[menus.global]] + identifier = 'github' + name = 'GitHub' + post = 'external' + url = 'https://github.com/gohugoio/hugo' + weight = 200 diff --git a/docs/layouts/_partials/layouts/blocks/alert.html b/docs/layouts/_partials/layouts/blocks/alert.html index 45f0044d9..710226ebb 100644 --- a/docs/layouts/_partials/layouts/blocks/alert.html +++ b/docs/layouts/_partials/layouts/blocks/alert.html @@ -4,7 +4,7 @@ {{- $text := .text | default "" }} {{- $class := .class | default "mt-6 mb-8" }} <div - class="border-l-4 overflow-x-auto border-{{ $color }}-400 bg-{{ $color }}-50 dark:bg-{{ $color }}-950 border-1 border-{{ $color }}-100 dark:border-{{ $color }}-900 p-4 {{ $class }}"> + class="border-l-4 overflow-x-auto border-{{ $color }}-400 bg-{{ $color }}-50 dark:bg-{{ $color }}-800 border-1 dark:border-{{ $color }}-700 p-4 {{ $class }}"> <div class="flex"> <div class="shrink-0"> <svg class="fill-{{ $color }}-500 dark:fill-{{ $color }}-400 h-7 w-7"> diff --git a/docs/layouts/_partials/layouts/head/head.html b/docs/layouts/_partials/layouts/head/head.html index bb27f6a24..550636095 100644 --- a/docs/layouts/_partials/layouts/head/head.html +++ b/docs/layouts/_partials/layouts/head/head.html @@ -28,21 +28,11 @@ href="{{ .RelPermalink | safeURL }}" /> {{ end -}} - -<meta - name="description" - content="{{ with .Description }} - {{ . }} - {{ else }} - {{ with .Site.Params.description }}{{ . }}{{ end }} - {{ end }} - " /> - - +<meta name="description" content="{{ or .Description site.Params.description }}"> {{ partial "opengraph/opengraph.html" . }} -{{- template "_internal/schema.html" . -}} -{{- template "_internal/twitter_cards.html" . -}} +{{ partial "schema.html" . }} +{{ partial "twitter_cards.html" . }} {{ if hugo.IsProduction }} {{ partial "helpers/gtag.html" . }} diff --git a/docs/layouts/_partials/layouts/header/header.html b/docs/layouts/_partials/layouts/header/header.html index 0d2e720d7..5d27a20b3 100644 --- a/docs/layouts/_partials/layouts/header/header.html +++ b/docs/layouts/_partials/layouts/header/header.html @@ -22,6 +22,23 @@ > {{ end }} + + <div class="hidden 2xl:block ml-8 text-xs text-gray-400 dark:text-gray-400"> + {{ with hugo.Version }} + + Built with Hugo + {{ if strings.Contains . "-DEV" }} + v{{ . }} + {{ else }} + <a + class="text-blue-600 hover:text-blue-500 ml-1" + href="{{ printf `https://github.com/gohugoio/hugo/releases/tag/v%s` . }}" + >v{{ . }}</a + > + {{ end }} + {{ end }} + + </div> </div> <div class="-my-5 pl-2 grow-0"> @@ -29,7 +46,7 @@ {{ partial "layouts/search/input.html" . }} </div> <div - class="relative ml-0 md:ml-8 flex basis-0 justify-end gap-0 sm:gap-1 xl:grow-1"> + class="relative ml-0 md:ml-8 flex content-center basis-0 justify-end gap-0 sm:gap-1 xl:grow-1"> {{/* QR code. */}} {{ partial "layouts/header/qr.html" . }} {{/* Theme selector. */}} @@ -40,5 +57,9 @@ class="hidden sm:block ml-2 sm:ml-6 h-6 fill-slate-400 group-hover:fill-slate-500 dark:group-hover:fill-slate-300"> {{ partial "layouts/header/githubstars.html" . }} </div> + <div + class="hidden sm:block ml-2 sm:ml-6 h-6"> + {{ partial "layouts/header/mastodon.html" . }} + </div> </div> </header> diff --git a/docs/layouts/_partials/layouts/header/mastodon.html b/docs/layouts/_partials/layouts/header/mastodon.html new file mode 100644 index 000000000..7e6af8ea9 --- /dev/null +++ b/docs/layouts/_partials/layouts/header/mastodon.html @@ -0,0 +1,29 @@ +<a + href="{{ site.Params.social.mastodon.url }}" + target="_blank" + aria-label="Link to Mastodon"> + <svg + class="h-10" + viewBox="0 0 75 79" + fill="none" + xmlns="http://www.w3.org/2000/svg"> + <path + d="M73.8393 17.4898C72.6973 9.00165 65.2994 2.31235 56.5296 1.01614C55.05 0.797115 49.4441 0 36.4582 0H36.3612C23.3717 0 20.585 0.797115 19.1054 1.01614C10.5798 2.27644 2.79399 8.28712 0.904997 16.8758C-0.00358524 21.1056 -0.100549 25.7949 0.0682394 30.0965C0.308852 36.2651 0.355538 42.423 0.91577 48.5665C1.30307 52.6474 1.97872 56.6957 2.93763 60.6812C4.73325 68.042 12.0019 74.1676 19.1233 76.6666C26.7478 79.2728 34.9474 79.7055 42.8039 77.9162C43.6682 77.7151 44.5217 77.4817 45.3645 77.216C47.275 76.6092 49.5123 75.9305 51.1571 74.7385C51.1797 74.7217 51.1982 74.7001 51.2112 74.6753C51.2243 74.6504 51.2316 74.6229 51.2325 74.5948V68.6416C51.2321 68.6154 51.2259 68.5896 51.2142 68.5661C51.2025 68.5426 51.1858 68.522 51.1651 68.5058C51.1444 68.4896 51.1204 68.4783 51.0948 68.4726C51.0692 68.4669 51.0426 68.467 51.0171 68.4729C45.9835 69.675 40.8254 70.2777 35.6502 70.2682C26.7439 70.2682 24.3486 66.042 23.6626 64.2826C23.1113 62.762 22.7612 61.1759 22.6212 59.5646C22.6197 59.5375 22.6247 59.5105 22.6357 59.4857C22.6466 59.4609 22.6633 59.4391 22.6843 59.422C22.7053 59.4048 22.73 59.3929 22.7565 59.3871C22.783 59.3813 22.8104 59.3818 22.8367 59.3886C27.7864 60.5826 32.8604 61.1853 37.9522 61.1839C39.1768 61.1839 40.3978 61.1839 41.6224 61.1516C46.7435 61.008 52.1411 60.7459 57.1796 59.7621C57.3053 59.7369 57.431 59.7154 57.5387 59.6831C65.4861 58.157 73.0493 53.3672 73.8178 41.2381C73.8465 40.7606 73.9184 36.2364 73.9184 35.7409C73.9219 34.0569 74.4606 23.7949 73.8393 17.4898Z" + fill="url(#paint0_linear_549_34)" /> + <path + d="M61.2484 27.0263V48.114H52.8916V27.6475C52.8916 23.3388 51.096 21.1413 47.4437 21.1413C43.4287 21.1413 41.4177 23.7409 41.4177 28.8755V40.0782H33.1111V28.8755C33.1111 23.7409 31.0965 21.1413 27.0815 21.1413C23.4507 21.1413 21.6371 23.3388 21.6371 27.6475V48.114H13.2839V27.0263C13.2839 22.7176 14.384 19.2946 16.5843 16.7572C18.8539 14.2258 21.8311 12.926 25.5264 12.926C29.8036 12.926 33.0357 14.5705 35.1905 17.8559L37.2698 21.346L39.3527 17.8559C41.5074 14.5705 44.7395 12.926 49.0095 12.926C52.7013 12.926 55.6784 14.2258 57.9553 16.7572C60.1531 19.2922 61.2508 22.7152 61.2484 27.0263Z" + fill="white" /> + <defs> + <linearGradient + id="paint0_linear_549_34" + x1="37.0692" + y1="0" + x2="37.0692" + y2="79" + gradientUnits="userSpaceOnUse"> + <stop stop-color="#6364FF" /> + <stop offset="1" stop-color="#563ACC" /> + </linearGradient> + </defs> + </svg> +</a> diff --git a/docs/layouts/_partials/layouts/hooks/body-main-start.html b/docs/layouts/_partials/layouts/hooks/body-main-start.html index b28dd21c8..19f4ed872 100644 --- a/docs/layouts/_partials/layouts/hooks/body-main-start.html +++ b/docs/layouts/_partials/layouts/hooks/body-main-start.html @@ -1,8 +1,8 @@ {{ if or .IsSection .IsPage }} <div class="hidden print:flex justify-between border-b-1 border-b-gray-400 mb-4"> <p class="flex flex-col justify-end text-4xl mb-3">Hugo Documentation</p> - {{ with images.QR .Permalink (dict "scale" 3) }} - <img class="mb-2 -mr-2" src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="Link to {{ $.Permalink }}"> + {{ with images.QR .Permalink (dict "targetDir" "images/qr") }} + <img class="mb-2 -mr-2" src="{{ .RelPermalink }}" width="{{ .Width | mul 0.75 | int }}" height="{{ .Height | mul 0.75 | int }}" alt="Link to {{ $.Permalink }}"> {{ end }} </div> {{end }} diff --git a/docs/layouts/_partials/layouts/related.html b/docs/layouts/_partials/layouts/related.html index 0245ba771..dac5b8d5b 100644 --- a/docs/layouts/_partials/layouts/related.html +++ b/docs/layouts/_partials/layouts/related.html @@ -14,7 +14,7 @@ <a class="text-sm text-blue-600 hover:text-blue-500 dark:text-blue-500 dark:hover:text-blue-400" href="{{ .RelPermalink }}" - >{{ or .Params.altTitle .Title }}</a + >{{ or .Params.alt_title .Title }}</a > </li> {{- end }} diff --git a/docs/layouts/_shortcodes/datatable-filtered.html b/docs/layouts/_shortcodes/datatable-filtered.html deleted file mode 100644 index de8b0cf55..000000000 --- a/docs/layouts/_shortcodes/datatable-filtered.html +++ /dev/null @@ -1,47 +0,0 @@ -{{ $package := (index .Params 0) }} -{{ $listname := (index .Params 1) }} -{{ $filter := split (index .Params 2) " " }} -{{ $filter1 := index $filter 0 }} -{{ $filter2 := index $filter 1 }} -{{ $filter3 := index $filter 2 }} - -{{ $list := (index (index .Site.Data.docs $package) $listname) }} -{{ $fields := after 3 .Params }} -{{ $list := where $list $filter1 $filter2 $filter3 }} - - -<div class="overflow-x-auto"> - <table> - <thead> - <tr> - {{ range $fields }} - <th>{{ . }}</th> - {{ end }} - </tr> - </thead> - <tbody> - {{ range $list }} - <tr> - {{ range $k, $v := . }} - {{ $.Scratch.Set $k $v }} - {{ end }} - {{ range $k, $v := $fields }} - <td> - {{ $tdContent := $.Scratch.Get . }} - {{ if eq $k 3 }} - {{ printf "%v" $tdContent | - strings.ReplaceRE `\[` "<ol><li>" | - strings.ReplaceRE `\s` "</li><li>" | - strings.ReplaceRE `\]` "</li></ol>" | - safeHTML - }} - {{ else }} - {{ $tdContent }} - {{ end }} - </td> - {{ end }} - </tr> - {{ end }} - </tbody> - </table> -</div> diff --git a/docs/layouts/_shortcodes/new-in.html b/docs/layouts/_shortcodes/new-in.html index 955d0a710..51399064e 100644 --- a/docs/layouts/_shortcodes/new-in.html +++ b/docs/layouts/_shortcodes/new-in.html @@ -46,9 +46,6 @@ button will be hidden if any of the following conditions is true: {{- else }} <span class="not-prose inline-flex items-center px-2 mr-1 rounded text-sm font-medium bg-green-200 dark:bg-green-400 fill-green-600"> - <svg class="mr-1.5 h-2 w-2" viewBox="0 0 8 8"> - <circle cx="4" cy="4" r="3" /> - </svg> <a class="text-green-800 dark:text-black hover:text-green-600 no-underline" href="{{ $href }}" diff --git a/docs/layouts/_shortcodes/newtemplatesystem.html b/docs/layouts/_shortcodes/newtemplatesystem.html new file mode 100644 index 000000000..d4b0ad375 --- /dev/null +++ b/docs/layouts/_shortcodes/newtemplatesystem.html @@ -0,0 +1,11 @@ +{{ $text := `We did a complete overhaul of Hugo's template system in v0.146.0. + We're working on getting all of the relevant documentation up to date, but until + then, see [this page](/templates/new-templatesystem-overview/). ` +}} +{{ partial "layouts/blocks/alert.html" + (dict + "color" "orange" + "icon" "information-circle" + "text" ($text | $.Page.RenderString ) + "title" "") +}} diff --git a/docs/layouts/baseof.html b/docs/layouts/baseof.html index 4c14a6b6d..c5df69a92 100644 --- a/docs/layouts/baseof.html +++ b/docs/layouts/baseof.html @@ -12,17 +12,12 @@ display: none !important; } </style> - <meta - name="description" - content="{{ .Description | default site.Params.description }}"> + {{ partial "layouts/head/head-js.html" . }} {{ with (templates.Defer (dict "key" "global")) }} {{ $t := debug.Timer "tailwindcss" }} {{ with resources.Get "css/styles.css" }} - {{ $opts := dict - "inlineImports" true - "minify" (not hugo.IsDevelopment) - }} + {{ $opts := dict "minify" (not hugo.IsDevelopment) }} {{ with . | css.TailwindCSS $opts }} {{ partial "helpers/linkcss.html" (dict "r" .) }} {{ end }} @@ -37,8 +32,13 @@ {{ end }} {{ partial "layouts/head/head.html" . }} </head> - <body - class="flex flex-col min-h-full bg-white dark:bg-blue-950 kind-{{ .Kind }}"> + + {{ $bodyClass := printf "flex flex-col min-h-full bg-white dark:bg-blue-950 kind-%s" .Kind }} + {{ if .Params.searchable }} + {{ $bodyClass = printf "%s searchable" $bodyClass }} + {{ end }} + + <body class="{{ $bodyClass }}"> {{ partial "layouts/hooks/body-start.html" . }} {{/* Layout. */}} {{ block "header" . }} diff --git a/docs/netlify.toml b/docs/netlify.toml index c24a32a60..ad4dd525e 100644 --- a/docs/netlify.toml +++ b/docs/netlify.toml @@ -3,7 +3,7 @@ command = "hugo --gc --minify" [build.environment] - HUGO_VERSION = "0.146.7" + HUGO_VERSION = "0.147.9" [context.production.environment] HUGO_ENV = "production" diff --git a/docs/tailwind.config.js b/docs/tailwind.config.js deleted file mode 100644 index 9d3c29050..000000000 --- a/docs/tailwind.config.js +++ /dev/null @@ -1 +0,0 @@ -/* Empty for now. */ @@ -2,13 +2,13 @@ module github.com/gohugoio/hugo require ( github.com/BurntSushi/locker v0.0.0-20171006230638-a6e239ea1c69 - github.com/alecthomas/chroma/v2 v2.18.0 + github.com/alecthomas/chroma/v2 v2.19.0 github.com/armon/go-radix v1.0.1-0.20221118154546-54df44f2176c github.com/aws/aws-sdk-go-v2 v1.36.4 github.com/aws/aws-sdk-go-v2/service/cloudfront v1.44.10 github.com/bep/clocks v0.5.0 github.com/bep/debounce v1.2.0 - github.com/bep/gitmap v1.6.0 + github.com/bep/gitmap v1.7.0 github.com/bep/goat v0.5.0 github.com/bep/godartsass/v2 v2.5.0 github.com/bep/golibsass v1.2.0 @@ -54,8 +54,8 @@ require ( github.com/mattn/go-isatty v0.0.20 github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c github.com/muesli/smartcrop v0.3.0 - github.com/niklasfasching/go-org v1.8.0 - github.com/olekukonko/tablewriter v1.0.7 + github.com/niklasfasching/go-org v1.9.0 + github.com/olekukonko/tablewriter v1.0.8 github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 github.com/pelletier/go-toml/v2 v2.2.4 github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c @@ -89,8 +89,8 @@ github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapp github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.50.0/go.mod h1:otE2jQekW/PqXk1Awf5lmfokJx4uwuqcj1ab5SpGeW0= github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0= github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= -github.com/alecthomas/chroma/v2 v2.18.0 h1:6h53Q4hW83SuF+jcsp7CVhLsMozzvQvO8HBbKQW+gn4= -github.com/alecthomas/chroma/v2 v2.18.0/go.mod h1:RVX6AvYm4VfYe/zsk7mjHueLDZor3aWCNE14TFlepBk= +github.com/alecthomas/chroma/v2 v2.19.0 h1:Im+SLRgT8maArxv81mULDWN8oKxkzboH07CHesxElq4= +github.com/alecthomas/chroma/v2 v2.19.0/go.mod h1:RVX6AvYm4VfYe/zsk7mjHueLDZor3aWCNE14TFlepBk= github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/armon/go-radix v1.0.1-0.20221118154546-54df44f2176c h1:651/eoCRnQ7YtSjAnSzRucrJz+3iGEFt+ysraELS81M= @@ -141,8 +141,8 @@ github.com/bep/clocks v0.5.0 h1:hhvKVGLPQWRVsBP/UB7ErrHYIO42gINVbvqxvYTPVps= github.com/bep/clocks v0.5.0/go.mod h1:SUq3q+OOq41y2lRQqH5fsOoxN8GbxSiT6jvoVVLCVhU= github.com/bep/debounce v1.2.0 h1:wXds8Kq8qRfwAOpAxHrJDbCXgC5aHSzgQb/0gKsHQqo= github.com/bep/debounce v1.2.0/go.mod h1:H8yggRPQKLUhUoqrJC1bO2xNya7vanpDl7xR3ISbCJ0= -github.com/bep/gitmap v1.6.0 h1:sDuQMm9HoTL0LtlrfxjbjgAg2wHQd4nkMup2FInYzhA= -github.com/bep/gitmap v1.6.0/go.mod h1:n+3W1f/rot2hynsqEGxGMErPRgT41n9CkGuzPvz9cIw= +github.com/bep/gitmap v1.7.0 h1:jvPnRQv5RG6IDPrwoDiwAhTE/DmdEkOW4poFeUYmjI8= +github.com/bep/gitmap v1.7.0/go.mod h1:n+3W1f/rot2hynsqEGxGMErPRgT41n9CkGuzPvz9cIw= github.com/bep/goat v0.5.0 h1:S8jLXHCVy/EHIoCY+btKkmcxcXFd34a0Q63/0D4TKeA= github.com/bep/goat v0.5.0/go.mod h1:Md9x7gRxiWKs85yHlVTvHQw9rg86Bm+Y4SuYE8CTH7c= github.com/bep/godartsass/v2 v2.5.0 h1:tKRvwVdyjCIr48qgtLa4gHEdtRkPF8H1OeEhJAEv7xg= @@ -416,8 +416,8 @@ github.com/muesli/smartcrop v0.3.0/go.mod h1:i2fCI/UorTfgEpPPLWiFBv4pye+YAG78Rwc github.com/neurosnap/sentences v1.0.6/go.mod h1:pg1IapvYpWCJJm/Etxeh0+gtMf1rI1STY9S7eUCPbDc= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= -github.com/niklasfasching/go-org v1.8.0 h1:WyGLaajLLp8JbQzkmapZ1y0MOzKuKV47HkZRloi+HGY= -github.com/niklasfasching/go-org v1.8.0/go.mod h1:e2A9zJs7cdONrEGs3gvxCcaAEpwwPNPG7csDpXckMNg= +github.com/niklasfasching/go-org v1.9.0 h1:4/Sr68Qx06hjC9MVDB/4etGP67JionLHGscLMOClpnk= +github.com/niklasfasching/go-org v1.9.0/go.mod h1:ZAGFFkWvUQcpazmi/8nHqwvARpr1xpb+Es67oUGX/48= github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY= github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037/go.mod h1:2bpvgLBZEtENV5scfDFEtB/5+1M4hkQhDQrccEJ/qGw= github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletIKwUIt4x3t8n2SxavmoclizMb8c= @@ -426,8 +426,8 @@ github.com/olekukonko/errors v0.0.0-20250405072817-4e6d85265da6 h1:r3FaAI0NZK3hS github.com/olekukonko/errors v0.0.0-20250405072817-4e6d85265da6/go.mod h1:ppzxA5jBKcO1vIpCXQ9ZqgDh8iwODz6OXIGKU8r5m4Y= github.com/olekukonko/ll v0.0.8 h1:sbGZ1Fx4QxJXEqL/6IG8GEFnYojUSQ45dJVwN2FH2fc= github.com/olekukonko/ll v0.0.8/go.mod h1:En+sEW0JNETl26+K8eZ6/W4UQ7CYSrrgg/EdIYT2H8g= -github.com/olekukonko/tablewriter v1.0.7 h1:HCC2e3MM+2g72M81ZcJU11uciw6z/p82aEnm4/ySDGw= -github.com/olekukonko/tablewriter v1.0.7/go.mod h1:H428M+HzoUXC6JU2Abj9IT9ooRmdq9CxuDmKMtrOCMs= +github.com/olekukonko/tablewriter v1.0.8 h1:f6wJzHg4QUtJdvrVPKco4QTrAylgaU0+b9br/lJxEiQ= +github.com/olekukonko/tablewriter v1.0.8/go.mod h1:H428M+HzoUXC6JU2Abj9IT9ooRmdq9CxuDmKMtrOCMs= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= diff --git a/helpers/general.go b/helpers/general.go index 76275a6b9..5c3af9712 100644 --- a/helpers/general.go +++ b/helpers/general.go @@ -255,6 +255,27 @@ func SliceToLower(s []string) []string { return l } +// StringSliceToList formats a string slice into a human-readable list. +// It joins the elements of the slice s with commas, using an Oxford comma, +// and precedes the final element with the conjunction c. +func StringSliceToList(s []string, c string) string { + const defaultConjunction = "and" + + if c == "" { + c = defaultConjunction + } + if len(s) == 0 { + return "" + } + if len(s) == 1 { + return s[0] + } + if len(s) == 2 { + return fmt.Sprintf("%s %s %s", s[0], c, s[1]) + } + return fmt.Sprintf("%s, %s %s", strings.Join(s[:len(s)-1], ", "), c, s[len(s)-1]) +} + // IsWhitespace determines if the given rune is whitespace. func IsWhitespace(r rune) bool { return r == ' ' || r == '\t' || r == '\n' || r == '\r' diff --git a/helpers/general_test.go b/helpers/general_test.go index 686e95ded..6d2a78e02 100644 --- a/helpers/general_test.go +++ b/helpers/general_test.go @@ -18,9 +18,8 @@ import ( "strings" "testing" - "github.com/gohugoio/hugo/helpers" - qt "github.com/frankban/quicktest" + "github.com/gohugoio/hugo/helpers" ) func TestResolveMarkup(t *testing.T) { @@ -304,3 +303,26 @@ func BenchmarkUniqueStrings(b *testing.B) { } }) } + +func TestStringSliceToList(t *testing.T) { + for _, tt := range []struct { + slice []string + conjunction string + want string + }{ + {[]string{}, "", ""}, + {[]string{"foo"}, "", "foo"}, + {[]string{"foo"}, "and", "foo"}, + {[]string{"foo", "bar"}, "", "foo and bar"}, + {[]string{"foo", "bar"}, "and", "foo and bar"}, + {[]string{"foo", "bar"}, "or", "foo or bar"}, + {[]string{"foo", "bar", "baz"}, "", "foo, bar, and baz"}, + {[]string{"foo", "bar", "baz"}, "and", "foo, bar, and baz"}, + {[]string{"foo", "bar", "baz"}, "or", "foo, bar, or baz"}, + } { + got := helpers.StringSliceToList(tt.slice, tt.conjunction) + if got != tt.want { + t.Errorf("StringSliceToList() got: %q, want: %q", got, tt.want) + } + } +} diff --git a/hugolib/gitinfo.go b/hugolib/gitinfo.go index 6b5261084..4786a9509 100644 --- a/hugolib/gitinfo.go +++ b/hugolib/gitinfo.go @@ -30,14 +30,14 @@ type gitInfo struct { repo *gitmap.GitRepo } -func (g *gitInfo) forPage(p page.Page) source.GitInfo { +func (g *gitInfo) forPage(p page.Page) *source.GitInfo { name := strings.TrimPrefix(filepath.ToSlash(p.File().Filename()), g.contentDir) name = strings.TrimPrefix(name, "/") gi, found := g.repo.Files[name] if !found { - return source.GitInfo{} + return nil } - return source.NewGitInfo(*gi) + return gi } func newGitInfo(d *deps.Deps) (*gitInfo, error) { diff --git a/hugolib/hugo_sites.go b/hugolib/hugo_sites.go index 0b68af2ec..a79a77d36 100644 --- a/hugolib/hugo_sites.go +++ b/hugolib/hugo_sites.go @@ -230,13 +230,13 @@ func (h *HugoSites) RegularPages() page.Pages { return v } -func (h *HugoSites) gitInfoForPage(p page.Page) (source.GitInfo, error) { +func (h *HugoSites) gitInfoForPage(p page.Page) (*source.GitInfo, error) { if _, err := h.init.gitInfo.Do(context.Background()); err != nil { - return source.GitInfo{}, err + return nil, err } if h.gitInfo == nil { - return source.GitInfo{}, nil + return nil, nil } return h.gitInfo.forPage(p), nil diff --git a/hugolib/page.go b/hugolib/page.go index dc0d9f4bc..5387c021d 100644 --- a/hugolib/page.go +++ b/hugolib/page.go @@ -238,7 +238,7 @@ func (p *pageState) ApplyFilterToHeadings(ctx context.Context, fn func(*tableofc } } -func (p *pageState) GitInfo() source.GitInfo { +func (p *pageState) GitInfo() *source.GitInfo { return p.gitInfo } diff --git a/hugolib/page__common.go b/hugolib/page__common.go index f6f01bbe2..0b9cf0200 100644 --- a/hugolib/page__common.go +++ b/hugolib/page__common.go @@ -86,7 +86,7 @@ type pageCommon struct { targetPathDescriptor page.TargetPathDescriptor // Set if feature enabled and this is in a Git repo. - gitInfo source.GitInfo + gitInfo *source.GitInfo codeowners []string // Positional navigation diff --git a/hugolib/page__meta.go b/hugolib/page__meta.go index 1af489f18..5a27d1913 100644 --- a/hugolib/page__meta.go +++ b/hugolib/page__meta.go @@ -405,7 +405,7 @@ func (p *pageState) setMetaPostParams() error { } var gitAuthorDate time.Time - if !p.gitInfo.IsZero() { + if p.gitInfo != nil { gitAuthorDate = p.gitInfo.AuthorDate } @@ -675,7 +675,7 @@ params: params["iscjklanguage"] = pcfg.IsCJKLanguage - if err := pcfg.Validate(false); err != nil { + if err := pcfg.Init(false); err != nil { return err } diff --git a/hugolib/page__per_output.go b/hugolib/page__per_output.go index 1f7f3411e..15e9a890c 100644 --- a/hugolib/page__per_output.go +++ b/hugolib/page__per_output.go @@ -29,6 +29,7 @@ import ( "github.com/spf13/cast" "github.com/gohugoio/hugo/markup/converter/hooks" + gc "github.com/gohugoio/hugo/markup/goldmark/goldmark_config" "github.com/gohugoio/hugo/markup/tableofcontents" "github.com/gohugoio/hugo/markup/converter" @@ -304,12 +305,17 @@ func (pco *pageContentOutput) initRenderHooks() error { } renderHookConfig := pco.po.p.s.conf.Markup.Goldmark.RenderHooks - var ignoreInternal bool + var ignoreEmbedded bool + + // For multilingual single-host sites, "auto" becomes "fallback" + // earlier in the process. switch layoutDescriptor.Variant1 { case "link": - ignoreInternal = !renderHookConfig.Link.IsEnableDefault() + ignoreEmbedded = renderHookConfig.Link.UseEmbedded == gc.RenderHookUseEmbeddedNever || + renderHookConfig.Link.UseEmbedded == gc.RenderHookUseEmbeddedAuto case "image": - ignoreInternal = !renderHookConfig.Image.IsEnableDefault() + ignoreEmbedded = renderHookConfig.Image.UseEmbedded == gc.RenderHookUseEmbeddedNever || + renderHookConfig.Image.UseEmbedded == gc.RenderHookUseEmbeddedAuto } candidates := pco.po.p.s.renderFormats @@ -323,8 +329,8 @@ func (pco *pageContentOutput) initRenderHooks() error { return false } - if ignoreInternal && candidate.SubCategory() == tplimpl.SubCategoryEmbedded { - // Don't consider the internal hook templates. + if ignoreEmbedded && candidate.SubCategory() == tplimpl.SubCategoryEmbedded { + // Don't consider the embedded hook templates. return false } diff --git a/hugolib/pagesfromdata/pagesfromgotmpl.go b/hugolib/pagesfromdata/pagesfromgotmpl.go index 72909a40b..6b369567b 100644 --- a/hugolib/pagesfromdata/pagesfromgotmpl.go +++ b/hugolib/pagesfromdata/pagesfromgotmpl.go @@ -68,12 +68,9 @@ func (p *pagesFromDataTemplateContext) toPathMap(v any) (string, map[string]any, if err != nil { return "", nil, err } - pathv, ok := m["path"] - if !ok { - return "", nil, fmt.Errorf("path not set") - } - path, err := cast.ToStringE(pathv) - if err != nil || path == "" { + + path, err := cast.ToStringE(m["path"]) + if err != nil { return "", nil, fmt.Errorf("invalid path %q", path) } return path, m, nil @@ -99,7 +96,7 @@ func (p *pagesFromDataTemplateContext) AddPage(v any) (string, error) { return "", err } - if err := pd.Validate(true); err != nil { + if err := pd.Init(true); err != nil { return "", err } @@ -336,5 +333,3 @@ func (p *PagesFromTemplate) Execute(ctx context.Context) (BuildInfo, error) { return bi, nil } - -////////////// diff --git a/hugolib/pagesfromdata/pagesfromgotmpl_integration_test.go b/hugolib/pagesfromdata/pagesfromgotmpl_integration_test.go index db06fb4a4..ffd0c5f5b 100644 --- a/hugolib/pagesfromdata/pagesfromgotmpl_integration_test.go +++ b/hugolib/pagesfromdata/pagesfromgotmpl_integration_test.go @@ -195,14 +195,7 @@ baseURL = "https://example.com" b, err := hugolib.TestE(t, files) b.Assert(err, qt.IsNotNil) b.Assert(err.Error(), qt.Contains, "_content.gotmpl:1:4") - b.Assert(err.Error(), qt.Contains, "error calling AddPage: path not set") - }) - - t.Run("AddPage, path starting with slash", func(t *testing.T) { - files := strings.ReplaceAll(filesTemplate, "DICT", `(dict "kind" "page" "title" "p1" "path" "/foo")`) - b, err := hugolib.TestE(t, files) - b.Assert(err, qt.IsNotNil) - b.Assert(err.Error(), qt.Contains, `path "/foo" must not start with a /`) + b.Assert(err.Error(), qt.Contains, "error calling AddPage: empty path is reserved for the home page") }) t.Run("AddPage, lang set", func(t *testing.T) { @@ -233,23 +226,6 @@ baseURL = "https://example.com" }) } -func TestPagesFromGoTmplAddResourceErrors(t *testing.T) { - filesTemplate := ` --- hugo.toml -- -disableKinds = ["taxonomy", "term", "rss", "sitemap"] -baseURL = "https://example.com" --- content/docs/_content.gotmpl -- -{{ $.AddResource DICT }} -` - - t.Run("missing Path", func(t *testing.T) { - files := strings.ReplaceAll(filesTemplate, "DICT", `(dict "name" "r1")`) - b, err := hugolib.TestE(t, files) - b.Assert(err, qt.IsNotNil) - b.Assert(err.Error(), qt.Contains, "error calling AddResource: path not set") - }) -} - func TestPagesFromGoTmplEditGoTmpl(t *testing.T) { t.Parallel() b := hugolib.TestRunning(t, filesPagesFromDataTempleBasic) @@ -915,3 +891,21 @@ Title: {{ .Title }}|Content: {{ .Content }}| b.AssertFileContent("public/s1/index.html", "Title: baz|") } + +func TestPagesFromGoTmplHome(t *testing.T) { + t.Parallel() + + files := ` +-- hugo.toml -- +disableKinds = ["taxonomy", "term", "rss", "sitemap"] +baseURL = "https://example.com" +-- layouts/all.html -- +{{ .Kind }}: {{ .Title }}| +-- content/_content.gotmpl -- +{{ $.AddPage (dict "title" "My Home!" "kind" "home" ) }} + +` + b := hugolib.Test(t, files) + + b.AssertFileContent("public/index.html", "home: My Home!|") +} diff --git a/hugolib/site.go b/hugolib/site.go index acd3b5410..e37dbd5ef 100644 --- a/hugolib/site.go +++ b/hugolib/site.go @@ -406,6 +406,7 @@ func newHugoSites(cfg deps.DepsCfg, d *deps.Deps, pageTrees *pageTrees, sites [] MediaTypes: s.conf.MediaTypes.Config, DefaultOutputFormat: s.conf.DefaultOutputFormat, TaxonomySingularPlural: s.conf.Taxonomies, + RenderHooks: s.conf.Markup.Goldmark.RenderHooks, }, tplimpl.SiteOptions{ Site: s, TemplateFuncs: tplimplinit.CreateFuncMap(s.Deps), diff --git a/hugolib/site_test.go b/hugolib/site_test.go index 199c878cd..7e3452b1c 100644 --- a/hugolib/site_test.go +++ b/hugolib/site_test.go @@ -511,12 +511,13 @@ func TestSectionNaming(t *testing.T) { func doTestSectionNaming(t *testing.T, canonify, uglify, pluralize bool) { c := qt.New(t) - var expectedPathSuffix string - - if uglify { - expectedPathSuffix = ".html" - } else { - expectedPathSuffix = "/index.html" + expectedPathSuffix := func(kind string) string { + isUgly := uglify && (kind == kinds.KindPage || kind == kinds.KindTerm) + if isUgly { + return ".html" + } else { + return "/index.html" + } } sources := [][2]string{ @@ -554,12 +555,12 @@ func doTestSectionNaming(t *testing.T, canonify, uglify, pluralize bool) { pluralAware bool expected string }{ - {filepath.FromSlash(fmt.Sprintf("sect/doc1%s", expectedPathSuffix)), false, "doc1"}, - {filepath.FromSlash(fmt.Sprintf("sect%s", expectedPathSuffix)), true, "Sect"}, - {filepath.FromSlash(fmt.Sprintf("fish-and-chips/doc2%s", expectedPathSuffix)), false, "doc2"}, - {filepath.FromSlash(fmt.Sprintf("fish-and-chips%s", expectedPathSuffix)), true, "Fish and Chips"}, - {filepath.FromSlash(fmt.Sprintf("ラーメン/doc3%s", expectedPathSuffix)), false, "doc3"}, - {filepath.FromSlash(fmt.Sprintf("ラーメン%s", expectedPathSuffix)), true, "ラーメン"}, + {filepath.FromSlash(fmt.Sprintf("sect/doc1%s", expectedPathSuffix(kinds.KindPage))), false, "doc1"}, + {filepath.FromSlash(fmt.Sprintf("sect%s", expectedPathSuffix(kinds.KindSection))), true, "Sect"}, + {filepath.FromSlash(fmt.Sprintf("fish-and-chips/doc2%s", expectedPathSuffix(kinds.KindPage))), false, "doc2"}, + {filepath.FromSlash(fmt.Sprintf("fish-and-chips%s", expectedPathSuffix(kinds.KindSection))), true, "Fish and Chips"}, + {filepath.FromSlash(fmt.Sprintf("ラーメン/doc3%s", expectedPathSuffix(kinds.KindPage))), false, "doc3"}, + {filepath.FromSlash(fmt.Sprintf("ラーメン%s", expectedPathSuffix(kinds.KindSection))), true, "ラーメン"}, } for _, test := range tests { diff --git a/hugolib/taxonomy_test.go b/hugolib/taxonomy_test.go index 7aeaa780c..272735367 100644 --- a/hugolib/taxonomy_test.go +++ b/hugolib/taxonomy_test.go @@ -65,151 +65,6 @@ YAML frontmatter with tags and categories taxonomy.` } } -func TestTaxonomiesWithAndWithoutContentFile(t *testing.T) { - for _, uglyURLs := range []bool{false, true} { - uglyURLs := uglyURLs - t.Run(fmt.Sprintf("uglyURLs=%t", uglyURLs), func(t *testing.T) { - t.Parallel() - doTestTaxonomiesWithAndWithoutContentFile(t, uglyURLs) - }) - } -} - -func doTestTaxonomiesWithAndWithoutContentFile(t *testing.T, uglyURLs bool) { - t.Helper() - - siteConfig := ` -baseURL = "http://example.com/blog" -titleCaseStyle = "firstupper" -uglyURLs = %t -defaultContentLanguage = "en" -[pagination] -pagerSize = 1 -[Taxonomies] -tag = "tags" -category = "categories" -other = "others" -empty = "empties" -permalinked = "permalinkeds" -[permalinks] -permalinkeds = "/perma/:slug/" -` - - pageTemplate := `--- -title: "%s" -tags: -%s -categories: -%s -others: -%s -permalinkeds: -%s ---- -# Doc -` - - siteConfig = fmt.Sprintf(siteConfig, uglyURLs) - - b := newTestSitesBuilder(t).WithConfigFile("toml", siteConfig) - - b.WithContent( - "p1.md", fmt.Sprintf(pageTemplate, "t1/c1", "- Tag1", "- cAt1", "- o1", "- Pl1"), - "p2.md", fmt.Sprintf(pageTemplate, "t2/c1", "- tag2", "- cAt1", "- o1", "- Pl1"), - "p3.md", fmt.Sprintf(pageTemplate, "t2/c12", "- tag2", "- cat2", "- o1", "- Pl1"), - "p4.md", fmt.Sprintf(pageTemplate, "Hello World", "", "", "- \"Hello Hugo world\"", "- Pl1"), - "categories/_index.md", newTestPage("Category Terms", "2017-01-01", 10), - "tags/Tag1/_index.md", newTestPage("Tag1 List", "2017-01-01", 10), - // https://github.com/gohugoio/hugo/issues/5847 - "/tags/not-used/_index.md", newTestPage("Unused Tag List", "2018-01-01", 10), - ) - - b.Build(BuildCfg{}) - - // So what we have now is: - // 1. categories with terms content page, but no content page for the only c1 category - // 2. tags with no terms content page, but content page for one of 2 tags (tag1) - // 3. the "others" taxonomy with no content pages. - // 4. the "permalinkeds" taxonomy with permalinks configuration. - - pathFunc := func(s string) string { - if uglyURLs { - return strings.Replace(s, "/index.html", ".html", 1) - } - return s - } - - // 1. - b.AssertFileContent(pathFunc("public/categories/cat1/index.html"), "List", "CAt1") - b.AssertFileContent(pathFunc("public/categories/index.html"), "Taxonomy Term Page", "Category Terms") - - // 2. - b.AssertFileContent(pathFunc("public/tags/tag2/index.html"), "List", "tag2") - b.AssertFileContent(pathFunc("public/tags/tag1/index.html"), "List", "Tag1") - b.AssertFileContent(pathFunc("public/tags/index.html"), "Taxonomy Term Page", "Tags") - - // 3. - b.AssertFileContent(pathFunc("public/others/o1/index.html"), "List", "o1") - b.AssertFileContent(pathFunc("public/others/index.html"), "Taxonomy Term Page", "Others") - - // 4. - b.AssertFileContent(pathFunc("public/perma/pl1/index.html"), "List", "Pl1") - - // This looks kind of funky, but the taxonomy terms do not have a permalinks definition, - // for good reasons. - b.AssertFileContent(pathFunc("public/permalinkeds/index.html"), "Taxonomy Term Page", "Permalinkeds") - - s := b.H.Sites[0] - - // Make sure that each kinds.KindTaxonomyTerm page has an appropriate number - // of kinds.KindTaxonomy pages in its Pages slice. - taxonomyTermPageCounts := map[string]int{ - "tags": 3, - "categories": 2, - "others": 2, - "empties": 0, - "permalinkeds": 1, - } - - for taxonomy, count := range taxonomyTermPageCounts { - msg := qt.Commentf(taxonomy) - term := s.getPageOldVersion(kinds.KindTaxonomy, taxonomy) - b.Assert(term, qt.Not(qt.IsNil), msg) - b.Assert(len(term.Pages()), qt.Equals, count, msg) - - for _, p := range term.Pages() { - b.Assert(p.Kind(), qt.Equals, kinds.KindTerm) - } - } - - cat1 := s.getPageOldVersion(kinds.KindTerm, "categories", "cat1") - b.Assert(cat1, qt.Not(qt.IsNil)) - if uglyURLs { - b.Assert(cat1.RelPermalink(), qt.Equals, "/blog/categories/cat1.html") - } else { - b.Assert(cat1.RelPermalink(), qt.Equals, "/blog/categories/cat1/") - } - - pl1 := s.getPageOldVersion(kinds.KindTerm, "permalinkeds", "pl1") - permalinkeds := s.getPageOldVersion(kinds.KindTaxonomy, "permalinkeds") - b.Assert(pl1, qt.Not(qt.IsNil)) - b.Assert(permalinkeds, qt.Not(qt.IsNil)) - if uglyURLs { - b.Assert(pl1.RelPermalink(), qt.Equals, "/blog/perma/pl1.html") - b.Assert(permalinkeds.RelPermalink(), qt.Equals, "/blog/permalinkeds.html") - } else { - b.Assert(pl1.RelPermalink(), qt.Equals, "/blog/perma/pl1/") - b.Assert(permalinkeds.RelPermalink(), qt.Equals, "/blog/permalinkeds/") - } - - helloWorld := s.getPageOldVersion(kinds.KindTerm, "others", "hello-hugo-world") - b.Assert(helloWorld, qt.Not(qt.IsNil)) - b.Assert(helloWorld.Title(), qt.Equals, "Hello Hugo world") - - // Issue #2977 - b.AssertFileContent(pathFunc("public/empties/index.html"), "Taxonomy Term Page", "Empties") -} - // https://github.com/gohugoio/hugo/issues/5513 // https://github.com/gohugoio/hugo/issues/5571 func TestTaxonomiesPathSeparation(t *testing.T) { diff --git a/markup/goldmark/goldmark_config/config.go b/markup/goldmark/goldmark_config/config.go index 04eb371d9..168a3b8fa 100644 --- a/markup/goldmark/goldmark_config/config.go +++ b/markup/goldmark/goldmark_config/config.go @@ -15,9 +15,13 @@ package goldmark_config const ( - AutoIDTypeGitHub = "github" - AutoIDTypeGitHubAscii = "github-ascii" - AutoIDTypeBlackfriday = "blackfriday" + AutoIDTypeBlackfriday = "blackfriday" + AutoIDTypeGitHub = "github" + AutoIDTypeGitHubAscii = "github-ascii" + RenderHookUseEmbeddedAlways = "always" + RenderHookUseEmbeddedAuto = "auto" + RenderHookUseEmbeddedFallback = "fallback" + RenderHookUseEmbeddedNever = "never" ) // Default holds the default Goldmark configuration. @@ -87,6 +91,14 @@ var Default = Config{ Block: false, }, }, + RenderHooks: RenderHooks{ + Image: ImageRenderHook{ + UseEmbedded: RenderHookUseEmbeddedAuto, + }, + Link: LinkRenderHook{ + UseEmbedded: RenderHookUseEmbeddedAuto, + }, + }, } // Config configures Goldmark. @@ -118,22 +130,24 @@ type RenderHooks struct { type ImageRenderHook struct { // Enable the default image render hook. // We need to know if it is set or not, hence the pointer. + // Deprecated: Use UseEmbedded instead. EnableDefault *bool -} -func (h ImageRenderHook) IsEnableDefault() bool { - return h.EnableDefault != nil && *h.EnableDefault + // When to use the embedded image render hook. + // One of auto, never, always, or fallback. Default is auto. + UseEmbedded string } // LinkRenderHook contains configuration for the link render hook. type LinkRenderHook struct { // Disable the default image render hook. // We need to know if it is set or not, hence the pointer. + // Deprecated: Use UseEmbedded instead. EnableDefault *bool -} -func (h LinkRenderHook) IsEnableDefault() bool { - return h.EnableDefault != nil && *h.EnableDefault + // When to use the embedded link render hook. + // One of auto, never, always, or fallback. Default is auto. + UseEmbedded string } type Extensions struct { diff --git a/resources/page/page.go b/resources/page/page.go index cbcfad557..490afd890 100644 --- a/resources/page/page.go +++ b/resources/page/page.go @@ -135,7 +135,7 @@ type GetPageProvider interface { // GitInfoProvider provides Git info. type GitInfoProvider interface { // GitInfo returns the Git info for this object. - GitInfo() source.GitInfo + GitInfo() *source.GitInfo // CodeOwners returns the code owners for this object. CodeOwners() []string } diff --git a/resources/page/page_nop.go b/resources/page/page_nop.go index 398a7df02..0fc9628c9 100644 --- a/resources/page/page_nop.go +++ b/resources/page/page_nop.go @@ -178,8 +178,8 @@ func (p *nopPage) GetTerms(taxonomy string) Pages { return nil } -func (p *nopPage) GitInfo() source.GitInfo { - return source.GitInfo{} +func (p *nopPage) GitInfo() *source.GitInfo { + return nil } func (p *nopPage) CodeOwners() []string { diff --git a/resources/page/page_paths.go b/resources/page/page_paths.go index 973754360..354292e1a 100644 --- a/resources/page/page_paths.go +++ b/resources/page/page_paths.go @@ -140,6 +140,8 @@ func CreateTargetPaths(d TargetPathDescriptor) (tp TargetPaths) { pb.isUgly = (d.UglyURLs || d.Type.Ugly) && !d.Type.NoUgly pb.baseNameSameAsType = !d.Path.IsBundle() && d.BaseName != "" && d.BaseName == d.Type.BaseName + indexIsUglyKind := d.Kind == kinds.KindHome || d.Kind == kinds.KindSection || d.Kind == kinds.KindTaxonomy + indexIsUglyKind = indexIsUglyKind && pb.isUgly if d.ExpandedPermalink == "" && pb.baseNameSameAsType { pb.isUgly = true @@ -233,13 +235,13 @@ func CreateTargetPaths(d TargetPathDescriptor) (tp TargetPaths) { needsBase = needsBase && d.Addends == "" - if needsBase || !pb.isUgly { + if needsBase || (!pb.isUgly || indexIsUglyKind) { pb.Add(d.Type.BaseName + pb.fullSuffix) } else { pb.ConcatLast(pb.fullSuffix) } - if pb.IsHtmlIndex() { + if !indexIsUglyKind && pb.IsHtmlIndex() { pb.linkUpperOffset = 1 } @@ -261,6 +263,7 @@ func CreateTargetPaths(d TargetPathDescriptor) (tp TargetPaths) { } link := pb.Link() + pagePath := pb.PathFile() tp.TargetFilename = filepath.FromSlash(pagePath) diff --git a/resources/page/pagemeta/page_frontmatter.go b/resources/page/pagemeta/page_frontmatter.go index 9018acb71..5cbef5681 100644 --- a/resources/page/pagemeta/page_frontmatter.go +++ b/resources/page/pagemeta/page_frontmatter.go @@ -149,13 +149,12 @@ var DefaultPageConfig = PageConfig{ Build: DefaultBuildConfig, } -func (p *PageConfig) Validate(pagesFromData bool) error { +func (p *PageConfig) Init(pagesFromData bool) error { if pagesFromData { - if p.Path == "" { - return errors.New("path must be set") - } - if strings.HasPrefix(p.Path, "/") { - return fmt.Errorf("path %q must not start with a /", p.Path) + p.Path = strings.TrimPrefix(p.Path, "/") + + if p.Path == "" && p.Kind != kinds.KindHome { + return fmt.Errorf("empty path is reserved for the home page") } if p.Lang != "" { return errors.New("lang must not be set") @@ -295,9 +294,6 @@ type ResourceConfig struct { } func (rc *ResourceConfig) Validate() error { - if rc.Path == "" { - return errors.New("path must be set") - } if rc.Content.Markup != "" { return errors.New("markup must not be set, use mediaType") } diff --git a/resources/page/path_integration_test.go b/resources/page/path_integration_test.go index 961cfb33f..3bd8ccf1f 100644 --- a/resources/page/path_integration_test.go +++ b/resources/page/path_integration_test.go @@ -55,10 +55,11 @@ title: p#2 b.AssertFileContentExact("public/index.html", "/|/s1/p%231/|/s2/p%232/|/tags/test%23tag%23/|") } -func TestOutputFormatWithPathIssue13829(t *testing.T) { +// Issues: 13829, 4428, 7497. +func TestMiscPathIssues(t *testing.T) { t.Parallel() - files := ` + filesTemplate := ` -- hugo.toml -- uglyURLs = false @@ -115,9 +116,11 @@ title: red const code string = "TITLE: {{ .Title }} | AOFRP: {{ range .AlternativeOutputFormats }}{{ .RelPermalink }}{{ end }} | TEMPLATE: {{ templates.Current.Name }}" for _, template := range templates { - files += "-- " + template + " --\n" + code + "\n" + filesTemplate += "-- " + template + " --\n" + code + "\n" } + files := filesTemplate + b := hugolib.Test(t, files) // uglyURLs: false, outputFormat: html @@ -134,14 +137,11 @@ title: red b.AssertFileContent("public/print/tags/index.txt", "TITLE: tags | AOFRP: /tags/ | TEMPLATE: taxonomy.print.txt") b.AssertFileContent("public/print/tags/red/index.txt", "TITLE: red | AOFRP: /tags/red/ | TEMPLATE: term.print.txt") - files = strings.ReplaceAll(files, "uglyURLs = false", "uglyURLs = true") + files = strings.ReplaceAll(filesTemplate, "uglyURLs = false", "uglyURLs = true") b = hugolib.Test(t, files) - // The assertions below assume that https://github.com/gohugoio/hugo/issues/4428 - // and https://github.com/gohugoio/hugo/issues/7497 have been fixed. - // uglyURLs: true, outputFormat: html - /*b.AssertFileContent("public/index.html", "TITLE: home | AOFRP: /print/index.txt | TEMPLATE: home.html") + b.AssertFileContent("public/index.html", "TITLE: home | AOFRP: /print/index.txt | TEMPLATE: home.html") b.AssertFileContent("public/s1/index.html", "TITLE: s1 | AOFRP: /print/s1/index.txt | TEMPLATE: section.html") b.AssertFileContent("public/s1/p1.html", "TITLE: p1 | AOFRP: /print/s1/p1.txt | TEMPLATE: page.html") b.AssertFileContent("public/tags/index.html", "TITLE: tags | AOFRP: /print/tags/index.txt | TEMPLATE: taxonomy.html") @@ -152,5 +152,5 @@ title: red b.AssertFileContent("public/print/s1/index.txt", "TITLE: s1 | AOFRP: /s1/index.html | TEMPLATE: section.print.txt") b.AssertFileContent("public/print/s1/p1.txt", "TITLE: p1 | AOFRP: /s1/p1.html | TEMPLATE: page.print.txt") b.AssertFileContent("public/print/tags/index.txt", "TITLE: tags | AOFRP: /tags/index.html | TEMPLATE: taxonomy.print.txt") - b.AssertFileContent("public/print/tags/red.txt", "TITLE: red | AOFRP: /tags/red.html | TEMPLATE: term.print.txt")*/ + b.AssertFileContent("public/print/tags/red.txt", "TITLE: red | AOFRP: /tags/red.html | TEMPLATE: term.print.txt") } diff --git a/resources/page/testhelpers_test.go b/resources/page/testhelpers_test.go index 1d2ee6223..5e1ec9a58 100644 --- a/resources/page/testhelpers_test.go +++ b/resources/page/testhelpers_test.go @@ -225,8 +225,8 @@ func (p *testPage) GetInternalRelatedDocsHandler() *RelatedDocsHandler { return relatedDocsHandler } -func (p *testPage) GitInfo() source.GitInfo { - return source.GitInfo{} +func (p *testPage) GitInfo() *source.GitInfo { + return nil } func (p *testPage) CodeOwners() []string { diff --git a/source/fileInfo.go b/source/fileInfo.go index dfa5cda26..fff78e2fe 100644 --- a/source/fileInfo.go +++ b/source/fileInfo.go @@ -16,7 +16,6 @@ package source import ( "path/filepath" "sync" - "time" "github.com/bep/gitmap" "github.com/gohugoio/hugo/common/hashing" @@ -154,32 +153,5 @@ func NewFileInfo(fi hugofs.FileMetaInfo) *File { } } -func NewGitInfo(info gitmap.GitInfo) GitInfo { - return GitInfo(info) -} - // GitInfo provides information about a version controlled source file. -type GitInfo struct { - // Commit hash. - Hash string `json:"hash"` - // Abbreviated commit hash. - AbbreviatedHash string `json:"abbreviatedHash"` - // The commit message's subject/title line. - Subject string `json:"subject"` - // The author name, respecting .mailmap. - AuthorName string `json:"authorName"` - // The author email address, respecting .mailmap. - AuthorEmail string `json:"authorEmail"` - // The author date. - AuthorDate time.Time `json:"authorDate"` - // The commit date. - CommitDate time.Time `json:"commitDate"` - // The commit message's body. - Body string `json:"body"` -} - -// IsZero returns true if the GitInfo is empty, -// meaning it will also be falsy in the Go templates. -func (g GitInfo) IsZero() bool { - return g.Hash == "" -} +type GitInfo = gitmap.GitInfo diff --git a/tpl/page/page_integration_test.go b/tpl/page/page_integration_test.go index 0f48ecd28..f96c87f98 100644 --- a/tpl/page/page_integration_test.go +++ b/tpl/page/page_integration_test.go @@ -220,3 +220,23 @@ disableLiveReload = true b.AssertFileContent("public/index.html", "1\n2\n3") } + +func TestThatPageGitInfoShouldBeNil(t *testing.T) { + t.Parallel() + + files := ` +-- hugo.toml -- +disableKinds = ["taxonomy", "term"] +-- content/p1.md -- +--- +title: "P1" +--- +-- layouts/all.html -- +GitInfo: {{ with .GitInfo }}FAIL{{ end }} + +` + + b := hugolib.Test(t, files) + + b.AssertFileContent("public/p1/index.html", "! FAIL") +} diff --git a/tpl/tplimpl/render_hook_integration_test.go b/tpl/tplimpl/render_hook_integration_test.go index 45c6cced1..e67701594 100644 --- a/tpl/tplimpl/render_hook_integration_test.go +++ b/tpl/tplimpl/render_hook_integration_test.go @@ -192,3 +192,115 @@ iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAA `<img src="/dir/p1/pixel.png" alt="alt4" id=""><script>alert()</script>">`, ) } + +// Issue 13535 +func TestEmbeddedLinkAndImageRenderHookConfig(t *testing.T) { + t.Parallel() + + files := ` +-- hugo.toml -- +disableKinds = ['home','rss','section','sitemap','taxonomy','term'] + +[markup.goldmark] +duplicateResourceFiles = false + +[markup.goldmark.renderHooks.image] +#KEY_VALUE + +[markup.goldmark.renderHooks.link] +#KEY_VALUE + +#LANGUAGES +-- content/s1/p1/index.md -- +--- +title: p1 +--- +[p2](p2) + +[a](a.txt) + + +-- content/s1/p1/a.txt -- +-- content/s1/p1/b.jpg -- +-- content/s1/p2.md -- +--- +title: p2 +--- +-- layouts/all.html -- +{{ .Content }} +` + + const customHooks string = ` +-- layouts/s1/_markup/render-link.html -- +custom link render hook: {{ .Text }}|{{ .Destination }} +-- layouts/s1/_markup/render-image.html -- +custom image render hook: {{ .Text }}|{{ .Destination }} +` + + const languages string = ` +[languages.en] +[languages.fr] +` + + const ( + fileToCheck = "public/s1/p1/index.html" + wantCustom string = "<p>custom link render hook: p2|p2</p>\n<p>custom link render hook: a|a.txt</p>\n<p>custom image render hook: b|b.jpg</p>" + wantEmbedded string = "<p><a href=\"/s1/p2/\">p2</a></p>\n<p><a href=\"/s1/p1/a.txt\">a</a></p>\n<p><img src=\"/s1/p1/b.jpg\" alt=\"b\"></p>" + wantGoldmark string = "<p><a href=\"p2\">p2</a></p>\n<p><a href=\"a.txt\">a</a></p>\n<p><img src=\"b.jpg\" alt=\"b\"></p>" + ) + + tests := []struct { + id string // the test id + isMultilingual bool // whether the site is multilingual single-host + hasCustomHooks bool // whether the site has custom link and image render hooks + keyValuePair string // the enableDefault (deprecated in v0.148.0) or useEmbedded key-value pair + want string // the expected content of public/s1/p1/index.html + }{ + {"01", false, false, "", wantGoldmark}, // monolingual + {"02", false, false, "enableDefault = false", wantGoldmark}, // monolingual, enableDefault = false + {"03", false, false, "enableDefault = true", wantEmbedded}, // monolingual, enableDefault = true + {"04", false, false, "useEmbedded = 'always'", wantEmbedded}, // monolingual, useEmbedded = 'always' + {"05", false, false, "useEmbedded = 'auto'", wantGoldmark}, // monolingual, useEmbedded = 'auto' + {"06", false, false, "useEmbedded = 'fallback'", wantEmbedded}, // monolingual, useEmbedded = 'fallback' + {"07", false, false, "useEmbedded = 'never'", wantGoldmark}, // monolingual, useEmbedded = 'never' + {"08", false, true, "", wantCustom}, // monolingual, with custom hooks + {"09", false, true, "enableDefault = false", wantCustom}, // monolingual, with custom hooks, enableDefault = false + {"10", false, true, "enableDefault = true", wantCustom}, // monolingual, with custom hooks, enableDefault = true + {"11", false, true, "useEmbedded = 'always'", wantEmbedded}, // monolingual, with custom hooks, useEmbedded = 'always' + {"12", false, true, "useEmbedded = 'auto'", wantCustom}, // monolingual, with custom hooks, useEmbedded = 'auto' + {"13", false, true, "useEmbedded = 'fallback'", wantCustom}, // monolingual, with custom hooks, useEmbedded = 'fallback' + {"14", false, true, "useEmbedded = 'never'", wantCustom}, // monolingual, with custom hooks, useEmbedded = 'never' + {"15", true, false, "", wantEmbedded}, // multilingual + {"16", true, false, "enableDefault = false", wantGoldmark}, // multilingual, enableDefault = false + {"17", true, false, "enableDefault = true", wantEmbedded}, // multilingual, enableDefault = true + {"18", true, false, "useEmbedded = 'always'", wantEmbedded}, // multilingual, useEmbedded = 'always' + {"19", true, false, "useEmbedded = 'auto'", wantEmbedded}, // multilingual, useEmbedded = 'auto' + {"20", true, false, "useEmbedded = 'fallback'", wantEmbedded}, // multilingual, useEmbedded = 'fallback' + {"21", true, false, "useEmbedded = 'never'", wantGoldmark}, // multilingual, useEmbedded = 'never' + {"22", true, true, "", wantCustom}, // multilingual, with custom hooks + {"23", true, true, "enableDefault = false", wantCustom}, // multilingual, with custom hooks, enableDefault = false + {"24", true, true, "enableDefault = true", wantCustom}, // multilingual, with custom hooks, enableDefault = true + {"25", true, true, "useEmbedded = 'always'", wantEmbedded}, // multilingual, with custom hooks, useEmbedded = 'always' + {"26", true, true, "useEmbedded = 'auto'", wantCustom}, // multilingual, with custom hooks, useEmbedded = 'auto' + {"27", true, true, "useEmbedded = 'fallback'", wantCustom}, // multilingual, with custom hooks, useEmbedded = 'fallback' + {"28", true, true, "useEmbedded = 'never'", wantCustom}, // multilingual, with custom hooks, useEmbedded = 'never' + } + + for _, tt := range tests { + t.Run(tt.id, func(t *testing.T) { + t.Parallel() + + f := files + if tt.isMultilingual { + f = strings.ReplaceAll(f, "#LANGUAGES", languages) + } + if tt.hasCustomHooks { + f = f + customHooks + } + f = strings.ReplaceAll(f, "#KEY_VALUE", tt.keyValuePair) + + b := hugolib.Test(t, f) + b.AssertFileContent(fileToCheck, tt.want) + }) + } +} diff --git a/tpl/tplimpl/templatestore.go b/tpl/tplimpl/templatestore.go index 23c821cac..008b743c7 100644 --- a/tpl/tplimpl/templatestore.go +++ b/tpl/tplimpl/templatestore.go @@ -44,6 +44,7 @@ import ( "github.com/gohugoio/hugo/hugofs/files" "github.com/gohugoio/hugo/hugolib/doctree" "github.com/gohugoio/hugo/identity" + gc "github.com/gohugoio/hugo/markup/goldmark/goldmark_config" "github.com/gohugoio/hugo/media" "github.com/gohugoio/hugo/metrics" "github.com/gohugoio/hugo/output" @@ -202,6 +203,9 @@ type StoreOptions struct { // Whether we are in watch or server mode. Watching bool + // The render hook configuration. + RenderHooks gc.RenderHooks + // compiled. legacyMappingTaxonomy map[string]legacyOrdinalMapping legacyMappingTerm map[string]legacyOrdinalMapping @@ -1422,20 +1426,36 @@ func (s *TemplateStore) insertTemplates(include func(fi hugofs.FileMetaInfo) boo var ti *TemplInfo var err error - if pi.Type() == paths.TypeShortcode { - ti, err = s.insertShortcode(pi, fi, partialRebuild, s.treeShortcodes) - if err != nil || ti == nil { - return err + var insertFunc func() (*TemplInfo, error) + + insertFunc = func() (*TemplInfo, error) { + return s.insertTemplate(pi, fi, SubCategoryMain, partialRebuild, s.treeMain) + } + + switch pi.Type() { + case paths.TypeShortcode: + insertFunc = func() (*TemplInfo, error) { + return s.insertShortcode(pi, fi, partialRebuild, s.treeShortcodes) } - } else { - ti, err = s.insertTemplate(pi, fi, SubCategoryMain, partialRebuild, s.treeMain) + case paths.TypeMarkup: + skipImageRenderHook := pi.Name() == "render-image.html" && s.opts.RenderHooks.Image.UseEmbedded == "always" + skipLinkRenderHook := pi.Name() == "render-link.html" && s.opts.RenderHooks.Link.UseEmbedded == "always" + if skipImageRenderHook || skipLinkRenderHook { + insertFunc = nil + } + } + + if insertFunc != nil { + ti, err = insertFunc() if err != nil || ti == nil { return err } } - if err := s.tns.readTemplateInto(ti); err != nil { - return err + if ti != nil { + if err := s.tns.readTemplateInto(ti); err != nil { + return err + } } return nil |