// Copyright 2025 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package tpl contains template functions and related types. package tpl import ( "context" "slices" "strings" "sync" "unicode" bp "github.com/gohugoio/hugo/bufferpool" "github.com/gohugoio/hugo/common/hcontext" "github.com/gohugoio/hugo/identity" "github.com/gohugoio/hugo/langs" htmltemplate "github.com/gohugoio/hugo/tpl/internal/go_templates/htmltemplate" texttemplate "github.com/gohugoio/hugo/tpl/internal/go_templates/texttemplate" ) // Template is the common interface between text/template and html/template. type Template interface { Name() string Prepare() (*texttemplate.Template, error) } // RenderingContext represents the currently rendered site/language. type RenderingContext struct { Site site SiteOutIdx int } type ( contextKey uint8 ) const ( contextKeyDependencyManagerScopedProvider contextKey = iota contextKeyDependencyScope contextKeyPage contextKeyIsInGoldmark cntextKeyCurrentTemplateInfo ) // Context manages values passed in the context to templates. var Context = struct { DependencyManagerScopedProvider hcontext.ContextDispatcher[identity.DependencyManagerScopedProvider] GetDependencyManagerInCurrentScope func(context.Context) identity.Manager DependencyScope hcontext.ContextDispatcher[int] Page hcontext.ContextDispatcher[page] IsInGoldmark hcontext.ContextDispatcher[bool] CurrentTemplate hcontext.ContextDispatcher[*CurrentTemplateInfo] }{ DependencyManagerScopedProvider: hcontext.NewContextDispatcher[identity.DependencyManagerScopedProvider](contextKeyDependencyManagerScopedProvider), DependencyScope: hcontext.NewContextDispatcher[int](contextKeyDependencyScope), Page: hcontext.NewContextDispatcher[page](contextKeyPage), IsInGoldmark: hcontext.NewContextDispatcher[bool](contextKeyIsInGoldmark), CurrentTemplate: hcontext.NewContextDispatcher[*CurrentTemplateInfo](cntextKeyCurrentTemplateInfo), } func init() { Context.GetDependencyManagerInCurrentScope = func(ctx context.Context) identity.Manager { idmsp := Context.DependencyManagerScopedProvider.Get(ctx) if idmsp != nil { return idmsp.GetDependencyManagerForScope(Context.DependencyScope.Get(ctx)) } return nil } } type page interface { IsNode() bool } type site interface { Language() *langs.Language } const ( // HugoDeferredTemplatePrefix is the prefix for placeholders for deferred templates. HugoDeferredTemplatePrefix = "__hdeferred/" // HugoDeferredTemplateSuffix is the suffix for placeholders for deferred templates. HugoDeferredTemplateSuffix = "__d=" ) const hugoNewLinePlaceholder = "___hugonl_" var stripHTMLReplacerPre = strings.NewReplacer("\n", " ", "
", hugoNewLinePlaceholder, "