// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package page contains the core interfaces and types for the Page resource, // a core component in Hugo. package page import ( "context" "html/template" "github.com/gohugoio/hugo/identity" "github.com/gohugoio/hugo/markup/converter" "github.com/gohugoio/hugo/markup/tableofcontents" "github.com/gohugoio/hugo/config" "github.com/gohugoio/hugo/tpl" "github.com/gohugoio/hugo/common/maps" "github.com/gohugoio/hugo/compare" "github.com/gohugoio/hugo/hugofs/files" "github.com/gohugoio/hugo/navigation" "github.com/gohugoio/hugo/related" "github.com/gohugoio/hugo/resources/resource" "github.com/gohugoio/hugo/source" ) // Clear clears any global package state. func Clear() error { spc.clear() return nil } // AlternativeOutputFormatsProvider provides alternative output formats for a // Page. type AlternativeOutputFormatsProvider interface { // AlternativeOutputFormats gives the alternative output formats for the // current output. // Note that we use the term "alternative" and not "alternate" here, as it // does not necessarily replace the other format, it is an alternative representation. AlternativeOutputFormats() OutputFormats } // AuthorProvider provides author information. type AuthorProvider interface { // Deprecated. Author() Author // Deprecated. Authors() AuthorList } // ChildCareProvider provides accessors to child resources. type ChildCareProvider interface { // Pages returns a list of pages of all kinds. Pages() Pages // RegularPages returns a list of pages of kind 'Page'. RegularPages() Pages // RegularPagesRecursive returns all regular pages below the current // section. RegularPagesRecursive() Pages // Resources returns a list of all resources. Resources() resource.Resources } // ContentProvider provides the content related values for a Page. type ContentProvider interface { Content(context.Context) (any, error) // Plain returns the Page Content stripped of HTML markup. Plain(context.Context) string // PlainWords returns a string slice from splitting Plain using https://pkg.go.dev/strings#Fields. PlainWords(context.Context) []string // Summary returns a generated summary of the content. // The breakpoint can be set manually by inserting a summary separator in the source file. Summary(context.Context) template.HTML // Truncated returns whether the Summary is truncated or not. Truncated(context.Context) bool // FuzzyWordCount returns the approximate number of words in the content. FuzzyWordCount(context.Context) int // WordCount returns the number of words in the content. WordCount(context.Context) int // ReadingTime returns the reading time based on the length of plain text. ReadingTime(context.Context) int // Len returns the length of the content. // This is for internal use only. Len(context.Context) int } // ContentRenderer provides the content rendering methods for some content. type ContentRenderer interface { // ParseAndRenderContent renders the given content. // For internal use only. ParseAndRenderContent(ctx context.Context, content []byte, enableTOC bool) (converter.ResultRender, error) // For internal use only. ParseContent(ctx context.Context, content []byte) (converter.ResultParse, bool, error) // For internal use only. RenderContent(ctx context.Context, content []byte, doc any) (converter.ResultRender, bool, error) } // FileProvider provides the source file. type FileProvider interface { // File returns the source file for this Page, // or a zero File if this Page is not backed by a file. File() source.File } // GetPageProvider provides the GetPage method. type GetPageProvider interface { // GetPage looks up a page for the given ref. // {{ with .GetPage "blog" }}{{ .Title }}{{ end }} // // This will return nil when no page could be found, and will return // an error if the ref is ambiguous. GetPage(ref string) (Page, error) // GetPageWithTemplateInfo is for internal use only. GetPageWithTemplateInfo(info tpl.Info, ref string) (Page, error) } // GitInfoProvider provides Git info. type GitInfoProvider interface { // GitInfo returns the Git info for this object. GitInfo() source.GitInfo // CodeOwners returns the code owners for this object. CodeOwners() []string } // InSectionPositioner provides section navigation. type InSectionPositioner interface { // NextInSection returns the next page in the same section. NextInSection() Page // PrevInSection returns the previous page in the same section. PrevInSection() Page } // InternalDependencies is considered an internal interface. type InternalDependencies interface { // GetRelatedDocsHandler is for internal use only. GetRelatedDocsHandler() *RelatedDocsHandler } // OutputFormatsProvider provides the OutputFormats of a Page. type OutputFormatsProvider interface { // OutputFormats returns the OutputFormats for this Page. OutputFormats() OutputFormats } // Page is the core interface in Hugo and what you get as the top level data context in your templates. type Page interface { ContentProvider TableOfContentsProvider PageWithoutContent } type PageFragment interface { resource.ResourceLinksProvider resource.ResourceMetaProvider } // PageMetaProvider provides page metadata, typically provided via front matter. type PageMetaProvider interface { // The 4 page dates resource.Dated // Aliases forms the base for redirects generation. Aliases() []string // BundleType returns the bundle type: `leaf`, `branch` or an empty string. BundleType() files.ContentClass // A configured description. Description() string // Whether this is a draft. Will only be true if run with the --buildDrafts (-D) flag. Draft() bool // IsHome returns whether this is the home page. IsHome() bool // Configured keywords. Keywords() []string // The Page Kind. One of page, home, section, taxonomy, term. Kind() string // The configured layout to use to render this page. Typically set in front matter. Layout() string // The title used for links. LinkTitle() string // IsNode returns whether this is an item of one of the list types in Hugo, // i.e. not a regular content IsNode() bool // IsPage returns whether this is a regular content IsPage() bool // Param looks for a param in Page and then in Site config. Param(key any) (any, error) // Path gets the relative path, including file name and extension if relevant, // to the source of this Page. It will be relative to any content root. Path() string // This is just a temporary bridge method. Use Path in templates. // Pathc is for internal usage only. Pathc() string // The slug, typically defined in front matter. Slug() string // This page's language code. Will be the same as the site's. Lang() string // IsSection returns whether this is a section IsSection() bool // Section returns the first path element below the content root. Section() string // Returns a slice of sections (directories if it's a file) to this // Page. SectionsEntries() []string // SectionsPath is SectionsEntries joined with a /. SectionsPath() string // Sitemap returns the sitemap configuration for this page. // This is for internal use only. Sitemap() config.SitemapConfig // Type is a discriminator used to select layouts etc. It is typically set // in front matter, but will fall back to the root section. Type() string // The configured weight, used as the first sort value in the default // page sort if non-zero. Weight() int } // PageRenderProvider provides a way for a Page to render content. type PageRenderProvider interface { // Render renders the given layout with this Page as context. Render(ctx context.Context, layout ...string) (template.HTML, error) // RenderString renders the first value in args with tPaginatorhe content renderer defined // for this Page. // It takes an optional map as a second argument: // // display (“inline”): // - inline or block. If inline (default), surrounding
on short snippets will be trimmed. // markup (defaults to the Page’s markup) RenderString(ctx context.Context, args ...any) (template.HTML, error) } // PageWithoutContent is the Page without any of the content methods. type PageWithoutContent interface { RawContentProvider resource.Resource PageMetaProvider resource.LanguageProvider // For pages backed by a file. FileProvider GitInfoProvider // Output formats OutputFormatsProvider AlternativeOutputFormatsProvider // Tree navigation ChildCareProvider TreeProvider // Horizontal navigation InSectionPositioner PageRenderProvider PaginatorProvider Positioner navigation.PageMenusProvider // TODO(bep) AuthorProvider // Page lookups/refs GetPageProvider RefProvider resource.TranslationKeyProvider TranslationsProvider SitesProvider // Helper methods ShortcodeInfoProvider compare.Eqer // Scratch returns a Scratch that can be used to store temporary state. // Note that this Scratch gets reset on server rebuilds. See Store() for a variant that survives. maps.Scratcher // Store returns a Scratch that can be used to store temporary state. // In contrast to Scratch(), this Scratch is not reset on server rebuilds. Store() *maps.Scratch RelatedKeywordsProvider // GetTerms gets the terms of a given taxonomy, // e.g. GetTerms("categories") GetTerms(taxonomy string) Pages // Used in change/dependency tracking. identity.Provider // HeadingsFiltered returns the headings for this page when a filter is set. // This is currently only triggered with the Related content feature // and the "fragments" type of index. HeadingsFiltered(context.Context) tableofcontents.Headings DeprecatedWarningPageMethods } // Positioner provides next/prev navigation. type Positioner interface { // Next points up to the next regular page (sorted by Hugo’s default sort). Next() Page // Prev points down to the previous regular page (sorted by Hugo’s default sort). Prev() Page // Deprecated: Use Prev. Will be removed in Hugo 0.57 PrevPage() Page // Deprecated: Use Next. Will be removed in Hugo 0.57 NextPage() Page } // RawContentProvider provides the raw, unprocessed content of the page. type RawContentProvider interface { // RawContent returns the raw, unprocessed content of the page excluding any front matter. RawContent() string } // RefProvider provides the methods needed to create reflinks to pages. type RefProvider interface { // Ref returns an absolute URl to a page. Ref(argsm map[string]any) (string, error) // RefFrom is for internal use only. RefFrom(argsm map[string]any, source any) (string, error) // RelRef returns a relative URL to a page. RelRef(argsm map[string]any) (string, error) // RelRefFrom is for internal use only. RelRefFrom(argsm map[string]any, source any) (string, error) } // RelatedKeywordsProvider allows a Page to be indexed. type RelatedKeywordsProvider interface { // Make it indexable as a related.Document // RelatedKeywords is meant for internal usage only. RelatedKeywords(cfg related.IndexConfig) ([]related.Keyword, error) } // ShortcodeInfoProvider provides info about the shortcodes in a Page. type ShortcodeInfoProvider interface { // HasShortcode return whether the page has a shortcode with the given name. // This method is mainly motivated with the Hugo Docs site's need for a list // of pages with the `todo` shortcode in it. HasShortcode(name string) bool } // SitesProvider provide accessors to get sites. type SitesProvider interface { // Site returns the current site. Site() Site // Sites returns all sites. Sites() Sites } // TableOfContentsProvider provides the table of contents for a Page. type TableOfContentsProvider interface { // TableOfContents returns the table of contents for the page rendered as HTML. TableOfContents(context.Context) template.HTML // Fragments returns the fragments for this page. Fragments(context.Context) *tableofcontents.Fragments } // TranslationsProvider provides access to any translations. type TranslationsProvider interface { // IsTranslated returns whether this content file is translated to // other language(s). IsTranslated() bool // AllTranslations returns all translations, including the current Page. AllTranslations() Pages // Translations returns the translations excluding the current Page. Translations() Pages } // TreeProvider provides section tree navigation. type TreeProvider interface { // IsAncestor returns whether the current page is an ancestor of other. // Note that this method is not relevant for taxonomy lists and taxonomy terms pages. IsAncestor(other any) (bool, error) // CurrentSection returns the page's current section or the page itself if home or a section. // Note that this will return nil for pages that is not regular, home or section pages. CurrentSection() Page // IsDescendant returns whether the current page is a descendant of other. // Note that this method is not relevant for taxonomy lists and taxonomy terms pages. IsDescendant(other any) (bool, error) // FirstSection returns the section on level 1 below home, e.g. "/docs". // For the home page, this will return itself. FirstSection() Page // InSection returns whether other is in the current section. // Note that this will always return false for pages that are // not either regular, home or section pages. InSection(other any) (bool, error) // Parent returns a section's parent section or a page's section. // To get a section's subsections, see Page's Sections method. Parent() Page // Ancestors returns the ancestors of each page Ancestors() Pages // Sections returns this section's subsections, if any. // Note that for non-sections, this method will always return an empty list. Sections() Pages // Page returns a reference to the Page itself, kept here mostly // for legacy reasons. Page() Page } // DeprecatedWarningPageMethods lists deprecated Page methods that will trigger // a WARNING if invoked. // This was added in Hugo 0.55. type DeprecatedWarningPageMethods any // This was emptied in Hugo 0.93.0. // Move here to trigger ERROR instead of WARNING. // TODO(bep) create wrappers and put into the Page once it has some methods. type DeprecatedErrorPageMethods any // PageWithContext is a Page with a context.Context. type PageWithContext struct { Page Ctx context.Context } func (p PageWithContext) Content() (any, error) { return p.Page.Content(p.Ctx) } func (p PageWithContext) Plain() string { return p.Page.Plain(p.Ctx) } func (p PageWithContext) PlainWords() []string { return p.Page.PlainWords(p.Ctx) } func (p PageWithContext) Summary() template.HTML { return p.Page.Summary(p.Ctx) } func (p PageWithContext) Truncated() bool { return p.Page.Truncated(p.Ctx) } func (p PageWithContext) FuzzyWordCount() int { return p.Page.FuzzyWordCount(p.Ctx) } func (p PageWithContext) WordCount() int { return p.Page.WordCount(p.Ctx) } func (p PageWithContext) ReadingTime() int { return p.Page.ReadingTime(p.Ctx) } func (p PageWithContext) Len() int { return p.Page.Len(p.Ctx) }