Misc doc, code refactoring to improve documentation

This commit is contained in:
Bjørn Erik Pedersen 2022-12-30 09:20:58 +01:00
parent 3c51625c71
commit e402d91ee1
47 changed files with 238 additions and 95 deletions

View file

@ -452,12 +452,16 @@ func collectMethodsRecursive(pkg string, f []*ast.Field) []string {
} }
if ident, ok := m.Type.(*ast.Ident); ok && ident.Obj != nil { if ident, ok := m.Type.(*ast.Ident); ok && ident.Obj != nil {
// Embedded interface switch tt := ident.Obj.Decl.(*ast.TypeSpec).Type.(type) {
methodNames = append( case *ast.InterfaceType:
methodNames, // Embedded interface
collectMethodsRecursive( methodNames = append(
pkg, methodNames,
ident.Obj.Decl.(*ast.TypeSpec).Type.(*ast.InterfaceType).Methods.List)...) collectMethodsRecursive(
pkg,
tt.Methods.List)...)
}
} else { } else {
// Embedded, but in a different file/package. Return the // Embedded, but in a different file/package. Return the
// package.Name and deal with that later. // package.Name and deal with that later.

View file

@ -126,6 +126,7 @@ type modMount struct {
Lang string `json:"lang,omitempty"` Lang string `json:"lang,omitempty"`
} }
// MarshalJSON is for internal use only.
func (m *modMounts) MarshalJSON() ([]byte, error) { func (m *modMounts) MarshalJSON() ([]byte, error) {
var mounts []modMount var mounts []modMount

2
common/docs.go Normal file
View file

@ -0,0 +1,2 @@
// Package common provides common helper functionality for Hugo.
package common

View file

@ -30,6 +30,7 @@ type Scratch struct {
// Scratcher provides a scratching service. // Scratcher provides a scratching service.
type Scratcher interface { type Scratcher interface {
// Scratch returns a "scratch pad" that can be used to store state.
Scratch() *Scratch Scratch() *Scratch
} }

View file

@ -263,3 +263,14 @@ func (n NamedSlice) String() string {
} }
return fmt.Sprintf("%s%s{%s}", n.Name, FilePathSeparator, strings.Join(n.Slice, ",")) return fmt.Sprintf("%s%s{%s}", n.Name, FilePathSeparator, strings.Join(n.Slice, ","))
} }
// DirFile holds the result from path.Split.
type DirFile struct {
Dir string
File string
}
// Used in test.
func (df DirFile) String() string {
return fmt.Sprintf("%s|%s", df.Dir, df.File)
}

View file

@ -24,6 +24,8 @@ import (
// Positioner represents a thing that knows its position in a text file or stream, // Positioner represents a thing that knows its position in a text file or stream,
// typically an error. // typically an error.
type Positioner interface { type Positioner interface {
// Position returns the current position.
// Useful in error logging, e.g. {{ errorf "error in code block: %s" .Position }}.
Position() Position Position() Position
} }

View file

@ -33,6 +33,7 @@ type Whitelist struct {
patternsStrings []string patternsStrings []string
} }
// MarshalJSON is for internal use only.
func (w Whitelist) MarshalJSON() ([]byte, error) { func (w Whitelist) MarshalJSON() ([]byte, error) {
if w.acceptNone { if w.acceptNone {
return json.Marshal(acceptNoneKeyword) return json.Marshal(acceptNoneKeyword)

View file

@ -130,6 +130,7 @@ func (f *FileMeta) JoinStat(name string) (FileMetaInfo, error) {
type FileMetaInfo interface { type FileMetaInfo interface {
os.FileInfo os.FileInfo
// Meta is for internal use.
Meta() *FileMeta Meta() *FileMeta
} }

View file

@ -266,7 +266,7 @@ func (m *pageMap) newResource(fim hugofs.FileMetaInfo, owner *pageState) (resour
} }
func (m *pageMap) createSiteTaxonomies() error { func (m *pageMap) createSiteTaxonomies() error {
m.s.taxonomies = make(TaxonomyList) m.s.taxonomies = make(page.TaxonomyList)
var walkErr error var walkErr error
m.taxonomies.Walk(func(s string, v any) bool { m.taxonomies.Walk(func(s string, v any) bool {
n := v.(*contentNode) n := v.(*contentNode)
@ -275,7 +275,7 @@ func (m *pageMap) createSiteTaxonomies() error {
viewName := t.name viewName := t.name
if t.termKey == "" { if t.termKey == "" {
m.s.taxonomies[viewName.plural] = make(Taxonomy) m.s.taxonomies[viewName.plural] = make(page.Taxonomy)
} else { } else {
taxonomy := m.s.taxonomies[viewName.plural] taxonomy := m.s.taxonomies[viewName.plural]
if taxonomy == nil { if taxonomy == nil {
@ -285,7 +285,7 @@ func (m *pageMap) createSiteTaxonomies() error {
m.taxonomyEntries.WalkPrefix(s, func(ss string, v any) bool { m.taxonomyEntries.WalkPrefix(s, func(ss string, v any) bool {
b2 := v.(*contentNode) b2 := v.(*contentNode)
info := b2.viewInfo info := b2.viewInfo
taxonomy.add(info.termKey, page.NewWeightedPage(info.weight, info.ref.p, n.p)) taxonomy[info.termKey] = append(taxonomy[info.termKey], page.NewWeightedPage(info.weight, info.ref.p, n.p))
return false return false
}) })

View file

@ -20,6 +20,7 @@ import (
"github.com/bep/gitmap" "github.com/bep/gitmap"
"github.com/gohugoio/hugo/config" "github.com/gohugoio/hugo/config"
"github.com/gohugoio/hugo/resources/page" "github.com/gohugoio/hugo/resources/page"
"github.com/gohugoio/hugo/source"
) )
type gitInfo struct { type gitInfo struct {
@ -27,11 +28,14 @@ type gitInfo struct {
repo *gitmap.GitRepo repo *gitmap.GitRepo
} }
func (g *gitInfo) forPage(p page.Page) *gitmap.GitInfo { func (g *gitInfo) forPage(p page.Page) source.GitInfo {
name := strings.TrimPrefix(filepath.ToSlash(p.File().Filename()), g.contentDir) name := strings.TrimPrefix(filepath.ToSlash(p.File().Filename()), g.contentDir)
name = strings.TrimPrefix(name, "/") name = strings.TrimPrefix(name, "/")
gi, found := g.repo.Files[name]
return g.repo.Files[name] if !found {
return source.GitInfo{}
}
return source.NewGitInfo(*gi)
} }
func newGitInfo(cfg config.Provider) (*gitInfo, error) { func newGitInfo(cfg config.Provider) (*gitInfo, error) {

View file

@ -41,7 +41,6 @@ import (
"github.com/gohugoio/hugo/source" "github.com/gohugoio/hugo/source"
"github.com/bep/gitmap"
"github.com/gohugoio/hugo/config" "github.com/gohugoio/hugo/config"
"github.com/gohugoio/hugo/publisher" "github.com/gohugoio/hugo/publisher"
@ -202,13 +201,13 @@ func (h *HugoSites) Data() map[string]any {
return h.data return h.data
} }
func (h *HugoSites) gitInfoForPage(p page.Page) (*gitmap.GitInfo, error) { func (h *HugoSites) gitInfoForPage(p page.Page) (source.GitInfo, error) {
if _, err := h.init.gitInfo.Do(); err != nil { if _, err := h.init.gitInfo.Do(); err != nil {
return nil, err return source.GitInfo{}, err
} }
if h.gitInfo == nil { if h.gitInfo == nil {
return nil, nil return source.GitInfo{}, nil
} }
return h.gitInfo.forPage(p), nil return h.gitInfo.forPage(p), nil

View file

@ -31,8 +31,6 @@ import (
"github.com/gohugoio/hugo/hugofs/files" "github.com/gohugoio/hugo/hugofs/files"
"github.com/bep/gitmap"
"github.com/gohugoio/hugo/helpers" "github.com/gohugoio/hugo/helpers"
"github.com/gohugoio/hugo/common/herrors" "github.com/gohugoio/hugo/common/herrors"
@ -150,7 +148,7 @@ func (p *pageState) GetIdentity() identity.Identity {
return identity.NewPathIdentity(files.ComponentFolderContent, filepath.FromSlash(p.Pathc())) return identity.NewPathIdentity(files.ComponentFolderContent, filepath.FromSlash(p.Pathc()))
} }
func (p *pageState) GitInfo() *gitmap.GitInfo { func (p *pageState) GitInfo() source.GitInfo {
return p.gitInfo return p.gitInfo
} }

View file

@ -16,7 +16,6 @@ package hugolib
import ( import (
"sync" "sync"
"github.com/bep/gitmap"
"github.com/gohugoio/hugo/common/maps" "github.com/gohugoio/hugo/common/maps"
"github.com/gohugoio/hugo/compare" "github.com/gohugoio/hugo/compare"
"github.com/gohugoio/hugo/lazy" "github.com/gohugoio/hugo/lazy"
@ -24,6 +23,7 @@ import (
"github.com/gohugoio/hugo/output" "github.com/gohugoio/hugo/output"
"github.com/gohugoio/hugo/resources/page" "github.com/gohugoio/hugo/resources/page"
"github.com/gohugoio/hugo/resources/resource" "github.com/gohugoio/hugo/resources/resource"
"github.com/gohugoio/hugo/source"
) )
type treeRefProvider interface { type treeRefProvider interface {
@ -106,7 +106,7 @@ type pageCommon struct {
shortcodeState *shortcodeHandler shortcodeState *shortcodeHandler
// Set if feature enabled and this is in a Git repo. // Set if feature enabled and this is in a Git repo.
gitInfo *gitmap.GitInfo gitInfo source.GitInfo
codeowners []string codeowners []string
// Positional navigation // Positional navigation

View file

@ -404,7 +404,7 @@ func (pm *pageMeta) setMetadata(parentBucket *pagesMapBucket, p *pageState, fron
} }
var gitAuthorDate time.Time var gitAuthorDate time.Time
if p.gitInfo != nil { if !p.gitInfo.IsZero() {
gitAuthorDate = p.gitInfo.AuthorDate gitAuthorDate = p.gitInfo.AuthorDate
} }

View file

@ -110,9 +110,9 @@ type Site struct {
*PageCollections *PageCollections
taxonomies TaxonomyList taxonomies page.TaxonomyList
Sections Taxonomy Sections page.Taxonomy
Info *SiteInfo Info *SiteInfo
language *langs.Language language *langs.Language
@ -172,7 +172,7 @@ type Site struct {
init *siteInit init *siteInit
} }
func (s *Site) Taxonomies() TaxonomyList { func (s *Site) Taxonomies() page.TaxonomyList {
s.init.taxonomies.Do() s.init.taxonomies.Do()
return s.taxonomies return s.taxonomies
} }
@ -708,7 +708,7 @@ func (s *SiteInfo) Menus() navigation.Menus {
} }
// TODO(bep) type // TODO(bep) type
func (s *SiteInfo) Taxonomies() any { func (s *SiteInfo) Taxonomies() page.TaxonomyList {
return s.s.Taxonomies() return s.s.Taxonomies()
} }

View file

@ -11,6 +11,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// Package langs contains the language related types and function.
package langs package langs
import ( import (

View file

@ -26,30 +26,56 @@ import (
var _ AttributesOptionsSliceProvider = (*attributes.AttributesHolder)(nil) var _ AttributesOptionsSliceProvider = (*attributes.AttributesHolder)(nil)
type AttributesProvider interface { type AttributesProvider interface {
// Attributes passed in from Markdown (e.g. { attrName1=attrValue1 attrName2="attr Value 2" }).
Attributes() map[string]any Attributes() map[string]any
} }
type LinkContext interface { type LinkContext interface {
// The Page being rendered.
Page() any Page() any
// The link URL.
Destination() string Destination() string
// The link title attribute.
Title() string Title() string
// The rendered (HTML) text.
Text() hstring.RenderedString Text() hstring.RenderedString
// The plain variant of Text.
PlainText() string PlainText() string
} }
type ImageLinkContext interface { type ImageLinkContext interface {
LinkContext LinkContext
// Returns true if this is a standalone image and the config option
// markup.goldmark.parser.wrapStandAloneImageWithinParagraph is disabled.
IsBlock() bool IsBlock() bool
// Zero-based ordinal for all the images in the current document.
Ordinal() int Ordinal() int
} }
// CodeblockContext is the context passed to a code block render hook.
type CodeblockContext interface { type CodeblockContext interface {
AttributesProvider AttributesProvider
text.Positioner text.Positioner
// Chroma highlighting processing options. This will only be filled if Type is a known Chroma Lexer.
Options() map[string]any Options() map[string]any
// The type of code block. This will be the programming language, e.g. bash, when doing code highlighting.
Type() string Type() string
// The text between the code fences.
Inner() string Inner() string
// Zero-based ordinal for all code blocks in the current document.
Ordinal() int Ordinal() int
// The owning Page.
Page() any Page() any
} }

View file

@ -157,10 +157,12 @@ type HightlightResult struct {
highlighted template.HTML highlighted template.HTML
} }
// Wrapped returns the highlighted code wrapped in a <div>, <pre> and <code> tag.
func (h HightlightResult) Wrapped() template.HTML { func (h HightlightResult) Wrapped() template.HTML {
return h.highlighted return h.highlighted
} }
// Inner returns the highlighted code without the wrapping <div>, <pre> and <code> tag, suitable for inline use.
func (h HightlightResult) Inner() template.HTML { func (h HightlightResult) Inner() template.HTML {
return h.highlighted[h.innerLow:h.innerHigh] return h.highlighted[h.innerLow:h.innerHigh]
} }

View file

@ -11,6 +11,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// Package markup contains the markup handling (e.g. Markdown).
package markup package markup
import ( import (

View file

@ -11,6 +11,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// Package media containes Media Type (MIME type) related types and functions.
package media package media
import ( import (

View file

@ -1,4 +1,4 @@
// Copyright 2019 The Hugo Authors. All rights reserved. // Copyright 2023 The Hugo Authors. All rights reserved.
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -11,6 +11,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// Package navigation provides the menu functionality.
package navigation package navigation
import ( import (

View file

@ -10,7 +10,7 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//
package navigation package navigation
import ( import (

View file

@ -11,6 +11,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// Package output contains Output Format types and functions.
package output package output
import ( import (
@ -400,6 +401,7 @@ func (f Format) BaseFilename() string {
} }
// MarshalJSON returns the JSON encoding of f. // MarshalJSON returns the JSON encoding of f.
// For internal use only.
func (f Format) MarshalJSON() ([]byte, error) { func (f Format) MarshalJSON() ([]byte, error) {
type Alias Format type Alias Format
return json.Marshal(&struct { return json.Marshal(&struct {

15
resources/docs.go Normal file
View file

@ -0,0 +1,15 @@
// Copyright 2023 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 resources contains Resource related types.
package resources

View file

@ -254,8 +254,10 @@ func init() {
} }
} }
// Tags is a map of EXIF tags.
type Tags map[string]any type Tags map[string]any
// UnmarshalJSON is for internal use only.
func (v *Tags) UnmarshalJSON(b []byte) error { func (v *Tags) UnmarshalJSON(b []byte) error {
vv := make(map[string]any) vv := make(map[string]any)
if err := tcodec.Unmarshal(b, &vv); err != nil { if err := tcodec.Unmarshal(b, &vv); err != nil {
@ -267,6 +269,7 @@ func (v *Tags) UnmarshalJSON(b []byte) error {
return nil return nil
} }
// MarshalJSON is for internal use only.
func (v Tags) MarshalJSON() ([]byte, error) { func (v Tags) MarshalJSON() ([]byte, error) {
return tcodec.Marshal(v) return tcodec.Marshal(v)
} }

View file

@ -29,6 +29,7 @@ type ImageResource interface {
type ImageResourceOps interface { type ImageResourceOps interface {
// Height returns the height of the Image. // Height returns the height of the Image.
Height() int Height() int
// Width returns the width of the Image. // Width returns the width of the Image.
Width() int Width() int
@ -37,8 +38,17 @@ type ImageResourceOps interface {
// Use the anchor option to change the crop box anchor point. // Use the anchor option to change the crop box anchor point.
// {{ $image := $image.Crop "600x400" }} // {{ $image := $image.Crop "600x400" }}
Crop(spec string) (ImageResource, error) Crop(spec string) (ImageResource, error)
// Fill scales the image to the smallest possible size that will cover the specified dimensions in spec,
// crops the resized image to the specified dimensions using the given anchor point.
// The spec is space delimited, e.g. `200x300 TopLeft`.
Fill(spec string) (ImageResource, error) Fill(spec string) (ImageResource, error)
// Fit scales down the image using the given spec.
Fit(spec string) (ImageResource, error) Fit(spec string) (ImageResource, error)
// Resize resizes the image to the given spec. If one of width or height is 0, the image aspect
// ratio is preserved.
Resize(spec string) (ImageResource, error) Resize(spec string) (ImageResource, error)
// Filter applies one or more filters to an Image. // Filter applies one or more filters to an Image.

View file

@ -21,7 +21,6 @@ import (
"github.com/gohugoio/hugo/identity" "github.com/gohugoio/hugo/identity"
"github.com/gohugoio/hugo/markup/converter" "github.com/gohugoio/hugo/markup/converter"
"github.com/bep/gitmap"
"github.com/gohugoio/hugo/config" "github.com/gohugoio/hugo/config"
"github.com/gohugoio/hugo/tpl" "github.com/gohugoio/hugo/tpl"
@ -61,18 +60,17 @@ type AuthorProvider interface {
// ChildCareProvider provides accessors to child resources. // ChildCareProvider provides accessors to child resources.
type ChildCareProvider interface { type ChildCareProvider interface {
// Pages returns a list of pages of all kinds.
Pages() Pages Pages() Pages
// RegularPages returns a list of pages of kind 'Page'. // RegularPages returns a list of pages of kind 'Page'.
// In Hugo 0.57 we changed the Pages method so it returns all page
// kinds, even sections. If you want the old behaviour, you can
// use RegularPages.
RegularPages() Pages RegularPages() Pages
// RegularPagesRecursive returns all regular pages below the current // RegularPagesRecursive returns all regular pages below the current
// section. // section.
RegularPagesRecursive() Pages RegularPagesRecursive() Pages
// Resources returns a list of all resources.
Resources() resource.Resources Resources() resource.Resources
} }
@ -103,16 +101,21 @@ type ContentProvider interface {
ReadingTime() int ReadingTime() int
// Len returns the length of the content. // Len returns the length of the content.
// This is for internal use only.
Len() int Len() int
} }
// ContentRenderer provides the content rendering methods for some content. // ContentRenderer provides the content rendering methods for some content.
type ContentRenderer interface { type ContentRenderer interface {
// RenderContent renders the given content.
// For internal use only.
RenderContent(content []byte, renderTOC bool) (converter.Result, error) RenderContent(content []byte, renderTOC bool) (converter.Result, error)
} }
// FileProvider provides the source file. // FileProvider provides the source file.
type FileProvider interface { 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 File() source.File
} }
@ -131,13 +134,17 @@ type GetPageProvider interface {
// GitInfoProvider provides Git info. // GitInfoProvider provides Git info.
type GitInfoProvider interface { type GitInfoProvider interface {
GitInfo() *gitmap.GitInfo // GitInfo returns the Git info for this object.
GitInfo() source.GitInfo
// CodeOwners returns the code owners for this object.
CodeOwners() []string CodeOwners() []string
} }
// InSectionPositioner provides section navigation. // InSectionPositioner provides section navigation.
type InSectionPositioner interface { type InSectionPositioner interface {
// NextInSection returns the next page in the same section.
NextInSection() Page NextInSection() Page
// PrevInSection returns the previous page in the same section.
PrevInSection() Page PrevInSection() Page
} }
@ -149,6 +156,7 @@ type InternalDependencies interface {
// OutputFormatsProvider provides the OutputFormats of a Page. // OutputFormatsProvider provides the OutputFormats of a Page.
type OutputFormatsProvider interface { type OutputFormatsProvider interface {
// OutputFormats returns the OutputFormats for this Page.
OutputFormats() OutputFormats OutputFormats() OutputFormats
} }
@ -229,6 +237,7 @@ type PageMetaProvider interface {
SectionsPath() string SectionsPath() string
// Sitemap returns the sitemap configuration for this page. // Sitemap returns the sitemap configuration for this page.
// This is for internal use only.
Sitemap() config.Sitemap Sitemap() config.Sitemap
// Type is a discriminator used to select layouts etc. It is typically set // Type is a discriminator used to select layouts etc. It is typically set
@ -242,7 +251,15 @@ type PageMetaProvider interface {
// PageRenderProvider provides a way for a Page to render content. // PageRenderProvider provides a way for a Page to render content.
type PageRenderProvider interface { type PageRenderProvider interface {
// Render renders the given layout with this Page as context.
Render(layout ...string) (template.HTML, error) Render(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 <p></p> on short snippets will be trimmed.
// markup (defaults to the Pages markup)
RenderString(args ...any) (template.HTML, error) RenderString(args ...any) (template.HTML, error)
} }
@ -311,7 +328,9 @@ type PageWithoutContent interface {
// Positioner provides next/prev navigation. // Positioner provides next/prev navigation.
type Positioner interface { type Positioner interface {
// Next points up to the next regular page (sorted by Hugos default sort).
Next() Page Next() Page
// Prev points down to the previous regular page (sorted by Hugos default sort).
Prev() Page Prev() Page
// Deprecated: Use Prev. Will be removed in Hugo 0.57 // Deprecated: Use Prev. Will be removed in Hugo 0.57
@ -323,16 +342,19 @@ type Positioner interface {
// RawContentProvider provides the raw, unprocessed content of the page. // RawContentProvider provides the raw, unprocessed content of the page.
type RawContentProvider interface { type RawContentProvider interface {
// RawContent returns the raw, unprocessed content of the page excluding any front matter.
RawContent() string RawContent() string
} }
// RefProvider provides the methods needed to create reflinks to pages. // RefProvider provides the methods needed to create reflinks to pages.
type RefProvider interface { type RefProvider interface {
// Ref returns an absolute URl to a page.
Ref(argsm map[string]any) (string, error) Ref(argsm map[string]any) (string, error)
// RefFrom is for internal use only. // RefFrom is for internal use only.
RefFrom(argsm map[string]any, source any) (string, error) RefFrom(argsm map[string]any, source any) (string, error)
// RelRef returns a relative URL to a page.
RelRef(argsm map[string]any) (string, error) RelRef(argsm map[string]any) (string, error)
// RefFrom is for internal use only. // RefFrom is for internal use only.
@ -356,12 +378,15 @@ type ShortcodeInfoProvider interface {
// SitesProvider provide accessors to get sites. // SitesProvider provide accessors to get sites.
type SitesProvider interface { type SitesProvider interface {
// Site returns the current site.
Site() Site Site() Site
// Sites returns all sites.
Sites() Sites Sites() Sites
} }
// TableOfContentsProvider provides the table of contents for a Page. // TableOfContentsProvider provides the table of contents for a Page.
type TableOfContentsProvider interface { type TableOfContentsProvider interface {
// TableOfContents returns the table of contents for the page rendered as HTML.
TableOfContents() template.HTML TableOfContents() template.HTML
} }
@ -382,7 +407,7 @@ type TranslationsProvider interface {
// TreeProvider provides section tree navigation. // TreeProvider provides section tree navigation.
type TreeProvider interface { type TreeProvider interface {
// IsAncestor returns whether the current page is an ancestor of the given // 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. // Note that this method is not relevant for taxonomy lists and taxonomy terms pages.
IsAncestor(other any) (bool, error) IsAncestor(other any) (bool, error)
@ -390,7 +415,7 @@ type TreeProvider interface {
// Note that this will return nil for pages that is not regular, home or section pages. // Note that this will return nil for pages that is not regular, home or section pages.
CurrentSection() Page CurrentSection() Page
// IsDescendant returns whether the current page is a descendant of the given // 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. // Note that this method is not relevant for taxonomy lists and taxonomy terms pages.
IsDescendant(other any) (bool, error) IsDescendant(other any) (bool, error)
@ -398,7 +423,7 @@ type TreeProvider interface {
// For the home page, this will return itself. // For the home page, this will return itself.
FirstSection() Page FirstSection() Page
// InSection returns whether the given page is in the current section. // InSection returns whether other is in the current section.
// Note that this will always return false for pages that are // Note that this will always return false for pages that are
// not either regular, home or section pages. // not either regular, home or section pages.
InSection(other any) (bool, error) InSection(other any) (bool, error)

View file

@ -17,7 +17,6 @@ package page
import ( import (
"encoding/json" "encoding/json"
"github.com/bep/gitmap"
"github.com/gohugoio/hugo/common/maps" "github.com/gohugoio/hugo/common/maps"
"github.com/gohugoio/hugo/config" "github.com/gohugoio/hugo/config"
"github.com/gohugoio/hugo/hugofs/files" "github.com/gohugoio/hugo/hugofs/files"
@ -82,6 +81,7 @@ func MarshalPageToJSON(p Page) ([]byte, error) {
language := p.Language() language := p.Language()
file := p.File() file := p.File()
gitInfo := p.GitInfo() gitInfo := p.GitInfo()
codeOwners := p.CodeOwners()
outputFormats := p.OutputFormats() outputFormats := p.OutputFormats()
alternativeOutputFormats := p.AlternativeOutputFormats() alternativeOutputFormats := p.AlternativeOutputFormats()
menus := p.Menus() menus := p.Menus()
@ -89,10 +89,11 @@ func MarshalPageToJSON(p Page) ([]byte, error) {
isTranslated := p.IsTranslated() isTranslated := p.IsTranslated()
allTranslations := p.AllTranslations() allTranslations := p.AllTranslations()
translations := p.Translations() translations := p.Translations()
store := p.Store()
getIdentity := p.GetIdentity() getIdentity := p.GetIdentity()
s := struct { s := struct {
Content any Content interface{}
Plain string Plain string
PlainWords []string PlainWords []string
Summary template.HTML Summary template.HTML
@ -110,7 +111,7 @@ func MarshalPageToJSON(p Page) ([]byte, error) {
Name string Name string
Title string Title string
Params maps.Params Params maps.Params
Data any Data interface{}
Date time.Time Date time.Time
Lastmod time.Time Lastmod time.Time
PublishDate time.Time PublishDate time.Time
@ -139,7 +140,8 @@ func MarshalPageToJSON(p Page) ([]byte, error) {
Weight int Weight int
Language *langs.Language Language *langs.Language
File source.File File source.File
GitInfo *gitmap.GitInfo GitInfo source.GitInfo
CodeOwners []string
OutputFormats OutputFormats OutputFormats OutputFormats
AlternativeOutputFormats OutputFormats AlternativeOutputFormats OutputFormats
Menus navigation.PageMenus Menus navigation.PageMenus
@ -147,6 +149,7 @@ func MarshalPageToJSON(p Page) ([]byte, error) {
IsTranslated bool IsTranslated bool
AllTranslations Pages AllTranslations Pages
Translations Pages Translations Pages
Store *maps.Scratch
GetIdentity identity.Identity GetIdentity identity.Identity
}{ }{
Content: content, Content: content,
@ -197,6 +200,7 @@ func MarshalPageToJSON(p Page) ([]byte, error) {
Language: language, Language: language,
File: file, File: file,
GitInfo: gitInfo, GitInfo: gitInfo,
CodeOwners: codeOwners,
OutputFormats: outputFormats, OutputFormats: outputFormats,
AlternativeOutputFormats: alternativeOutputFormats, AlternativeOutputFormats: alternativeOutputFormats,
Menus: menus, Menus: menus,
@ -204,6 +208,7 @@ func MarshalPageToJSON(p Page) ([]byte, error) {
IsTranslated: isTranslated, IsTranslated: isTranslated,
AllTranslations: allTranslations, AllTranslations: allTranslations,
Translations: translations, Translations: translations,
Store: store,
GetIdentity: getIdentity, GetIdentity: getIdentity,
} }

View file

@ -28,7 +28,6 @@ import (
"github.com/gohugoio/hugo/hugofs" "github.com/gohugoio/hugo/hugofs"
"github.com/bep/gitmap"
"github.com/gohugoio/hugo/navigation" "github.com/gohugoio/hugo/navigation"
"github.com/gohugoio/hugo/common/hugo" "github.com/gohugoio/hugo/common/hugo"
@ -200,8 +199,8 @@ func (p *nopPage) GetTerms(taxonomy string) Pages {
return nil return nil
} }
func (p *nopPage) GitInfo() *gitmap.GitInfo { func (p *nopPage) GitInfo() source.GitInfo {
return nil return source.GitInfo{}
} }
func (p *nopPage) CodeOwners() []string { func (p *nopPage) CodeOwners() []string {

View file

@ -27,8 +27,10 @@ import (
// PaginatorProvider provides two ways to create a page paginator. // PaginatorProvider provides two ways to create a page paginator.
type PaginatorProvider interface { type PaginatorProvider interface {
// Paginator creates a paginator with the default page set.
Paginator(options ...any) (*Pager, error) Paginator(options ...any) (*Pager, error)
Paginate(seq any, options ...any) (*Pager, error) // Paginate creates a paginator with the given page set in pages.
Paginate(pages any, options ...any) (*Pager, error)
} }
// Pager represents one of the elements in a paginator. // Pager represents one of the elements in a paginator.

View file

@ -26,8 +26,7 @@ import (
"github.com/gohugoio/hugo/navigation" "github.com/gohugoio/hugo/navigation"
) )
// Site represents a site in the build. This is currently a very narrow interface, // Site represents a site. There can be multople sites in a multilingual setup.
// but the actual implementation will be richer, see hugolib.SiteInfo.
type Site interface { type Site interface {
// Returns the Language configured for this Site. // Returns the Language configured for this Site.
Language() *langs.Language Language() *langs.Language
@ -63,7 +62,7 @@ type Site interface {
BaseURL() template.URL BaseURL() template.URL
// Retuns a taxonomy map. // Retuns a taxonomy map.
Taxonomies() any Taxonomies() TaxonomyList
// Returns the last modification date of the content. // Returns the last modification date of the content.
LastChange() time.Time LastChange() time.Time
@ -142,7 +141,7 @@ func (t testSite) Menus() navigation.Menus {
return nil return nil
} }
func (t testSite) Taxonomies() any { func (t testSite) Taxonomies() TaxonomyList {
return nil return nil
} }

View file

@ -1,4 +1,4 @@
// Copyright 2019 The Hugo Authors. All rights reserved. // Copyright 2023 The Hugo Authors. All rights reserved.
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -11,7 +11,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package hugolib package page
import ( import (
"fmt" "fmt"
@ -19,8 +19,6 @@ import (
"github.com/gohugoio/hugo/compare" "github.com/gohugoio/hugo/compare"
"github.com/gohugoio/hugo/langs" "github.com/gohugoio/hugo/langs"
"github.com/gohugoio/hugo/resources/page"
) )
// The TaxonomyList is a list of all taxonomies and their values // The TaxonomyList is a list of all taxonomies and their values
@ -33,9 +31,10 @@ func (tl TaxonomyList) String() string {
// A Taxonomy is a map of keywords to a list of pages. // A Taxonomy is a map of keywords to a list of pages.
// For example // For example
// TagTaxonomy['technology'] = page.WeightedPages //
// TagTaxonomy['go'] = page.WeightedPages // TagTaxonomy['technology'] = WeightedPages
type Taxonomy map[string]page.WeightedPages // TagTaxonomy['go'] = WeightedPages
type Taxonomy map[string]WeightedPages
// OrderedTaxonomy is another representation of an Taxonomy using an array rather than a map. // OrderedTaxonomy is another representation of an Taxonomy using an array rather than a map.
// Important because you can't order a map. // Important because you can't order a map.
@ -43,7 +42,7 @@ type OrderedTaxonomy []OrderedTaxonomyEntry
// getOneOPage returns one page in the taxonomy, // getOneOPage returns one page in the taxonomy,
// nil if there is none. // nil if there is none.
func (t OrderedTaxonomy) getOneOPage() page.Page { func (t OrderedTaxonomy) getOneOPage() Page {
if len(t) == 0 { if len(t) == 0 {
return nil return nil
} }
@ -51,24 +50,20 @@ func (t OrderedTaxonomy) getOneOPage() page.Page {
} }
// OrderedTaxonomyEntry is similar to an element of a Taxonomy, but with the key embedded (as name) // OrderedTaxonomyEntry is similar to an element of a Taxonomy, but with the key embedded (as name)
// e.g: {Name: Technology, page.WeightedPages: TaxonomyPages} // e.g: {Name: Technology, WeightedPages: TaxonomyPages}
type OrderedTaxonomyEntry struct { type OrderedTaxonomyEntry struct {
Name string Name string
page.WeightedPages WeightedPages
} }
// Get the weighted pages for the given key. // Get the weighted pages for the given key.
func (i Taxonomy) Get(key string) page.WeightedPages { func (i Taxonomy) Get(key string) WeightedPages {
return i[key] return i[key]
} }
// Count the weighted pages for the given key. // Count the weighted pages for the given key.
func (i Taxonomy) Count(key string) int { return len(i[key]) } func (i Taxonomy) Count(key string) int { return len(i[key]) }
func (i Taxonomy) add(key string, w page.WeightedPage) {
i[key] = append(i[key], w)
}
// TaxonomyArray returns an ordered taxonomy with a non defined order. // TaxonomyArray returns an ordered taxonomy with a non defined order.
func (i Taxonomy) TaxonomyArray() OrderedTaxonomy { func (i Taxonomy) TaxonomyArray() OrderedTaxonomy {
ies := make([]OrderedTaxonomyEntry, len(i)) ies := make([]OrderedTaxonomyEntry, len(i))
@ -117,7 +112,7 @@ func (i Taxonomy) ByCount() OrderedTaxonomy {
} }
// Pages returns the Pages for this taxonomy. // Pages returns the Pages for this taxonomy.
func (ie OrderedTaxonomyEntry) Pages() page.Pages { func (ie OrderedTaxonomyEntry) Pages() Pages {
return ie.WeightedPages.Pages() return ie.WeightedPages.Pages()
} }

View file

@ -26,7 +26,6 @@ import (
"github.com/gohugoio/hugo/modules" "github.com/gohugoio/hugo/modules"
"github.com/bep/gitmap"
"github.com/gohugoio/hugo/helpers" "github.com/gohugoio/hugo/helpers"
"github.com/gohugoio/hugo/resources/resource" "github.com/gohugoio/hugo/resources/resource"
@ -250,8 +249,8 @@ func (p *testPage) GetRelatedDocsHandler() *RelatedDocsHandler {
return relatedDocsHandler return relatedDocsHandler
} }
func (p *testPage) GitInfo() *gitmap.GitInfo { func (p *testPage) GitInfo() source.GitInfo {
return nil return source.GitInfo{}
} }
func (p *testPage) CodeOwners() []string { func (p *testPage) CodeOwners() []string {

View file

@ -1,4 +1,4 @@
// Copyright 2019 The Hugo Authors. All rights reserved. // Copyright 2023 The Hugo Authors. All rights reserved.
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -11,6 +11,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// Package resource contains Resource related types.
package resource package resource
import ( import (

View file

@ -64,6 +64,9 @@ type ResourceError interface {
// ErrProvider provides an Err. // ErrProvider provides an Err.
type ErrProvider interface { type ErrProvider interface {
// Err returns an error if this resource is in an error state.
// This will currently only be set for resources obtained from resources.GetRemote.
Err() ResourceError Err() ResourceError
} }

View file

@ -18,7 +18,9 @@ import (
"path/filepath" "path/filepath"
"strings" "strings"
"sync" "sync"
"time"
"github.com/bep/gitmap"
"github.com/gohugoio/hugo/common/paths" "github.com/gohugoio/hugo/common/paths"
"github.com/gohugoio/hugo/hugofs/files" "github.com/gohugoio/hugo/hugofs/files"
@ -294,3 +296,31 @@ func (sp *SourceSpec) NewFileInfo(fi hugofs.FileMetaInfo) (*FileInfo, error) {
return f, nil return f, nil
} }
func NewGitInfo(info gitmap.GitInfo) GitInfo {
return GitInfo(info)
}
// GitInfo provides information about a version controled 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"`
}
// 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 == ""
}

View file

@ -1,4 +1,4 @@
// Copyright 2017-present The Hugo Authors. All rights reserved. // Copyright 2023 The Hugo Authors. All rights reserved.
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -11,6 +11,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// Package source contains the types and functions related to source files.
package source package source
import ( import (

View file

@ -11,6 +11,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// Package diagrams provides template functions for generating diagrams.
package diagrams package diagrams
import ( import (

View file

@ -91,6 +91,7 @@ func (ns *Namespace) Config(path any) (image.Config, error) {
return config, nil return config, nil
} }
// Filter applies the given filters to the image given as the last element in args.
func (ns *Namespace) Filter(args ...any) (images.ImageResource, error) { func (ns *Namespace) Filter(args ...any) (images.ImageResource, error) {
if len(args) < 2 { if len(args) < 2 {
return nil, errors.New("must provide an image and one or more filters") return nil, errors.New("must provide an image and one or more filters")

2
tpl/openapi/docs.go Normal file
View file

@ -0,0 +1,2 @@
// Package openapi provides functions for generating OpenAPI (Swagger) documentation.
package openapi

View file

@ -11,6 +11,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// Package openapi3 provides functions for generating OpenAPI v3 (Swagger) documentation.
package openapi3 package openapi3
import ( import (
@ -54,6 +55,7 @@ type OpenAPIDocument struct {
*kopenapi3.T *kopenapi3.T
} }
// Unmarshal unmarshals the given resource into an OpenAPI 3 document.
func (ns *Namespace) Unmarshal(r resource.UnmarshableResource) (*OpenAPIDocument, error) { func (ns *Namespace) Unmarshal(r resource.UnmarshableResource) (*OpenAPIDocument, error) {
key := r.Key() key := r.Key()
if key == "" { if key == "" {

View file

@ -38,15 +38,15 @@ func TestReadFile(t *testing.T) {
}{ }{
{filepath.FromSlash("/f/f1.txt"), "f1-content"}, {filepath.FromSlash("/f/f1.txt"), "f1-content"},
{filepath.FromSlash("f/f1.txt"), "f1-content"}, {filepath.FromSlash("f/f1.txt"), "f1-content"},
{filepath.FromSlash("../f2.txt"), false}, {filepath.FromSlash("../f2.txt"), ""},
{"", false}, {"", false},
{"b", false}, {"b", ""},
} { } {
result, err := ns.ReadFile(test.filename) result, err := ns.ReadFile(test.filename)
if bb, ok := test.expect.(bool); ok && !bb { if bb, ok := test.expect.(bool); ok && !bb {
b.Assert(err, qt.Not(qt.IsNil)) b.Assert(err, qt.Not(qt.IsNil), qt.Commentf("filename: %q", test.filename))
continue continue
} }

View file

@ -15,11 +15,11 @@
package path package path
import ( import (
"fmt"
_path "path" _path "path"
"path/filepath" "path/filepath"
"strings" "strings"
"github.com/gohugoio/hugo/common/paths"
"github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/deps"
"github.com/spf13/cast" "github.com/spf13/cast"
) )
@ -36,17 +36,6 @@ type Namespace struct {
deps *deps.Deps deps *deps.Deps
} }
// DirFile holds the result from path.Split.
type DirFile struct {
Dir string
File string
}
// Used in test.
func (df DirFile) String() string {
return fmt.Sprintf("%s|%s", df.Dir, df.File)
}
// Ext returns the file name extension used by path. // Ext returns the file name extension used by path.
// The extension is the suffix beginning at the final dot // The extension is the suffix beginning at the final dot
// in the final slash-separated element of path; // in the final slash-separated element of path;
@ -117,15 +106,15 @@ func (ns *Namespace) BaseName(path any) (string, error) {
// The input path is passed into filepath.ToSlash converting any Windows slashes // The input path is passed into filepath.ToSlash converting any Windows slashes
// to forward slashes. // to forward slashes.
// The returned values have the property that path = dir+file. // The returned values have the property that path = dir+file.
func (ns *Namespace) Split(path any) (DirFile, error) { func (ns *Namespace) Split(path any) (paths.DirFile, error) {
spath, err := cast.ToStringE(path) spath, err := cast.ToStringE(path)
if err != nil { if err != nil {
return DirFile{}, err return paths.DirFile{}, err
} }
spath = filepath.ToSlash(spath) spath = filepath.ToSlash(spath)
dir, file := _path.Split(spath) dir, file := _path.Split(spath)
return DirFile{Dir: dir, File: file}, nil return paths.DirFile{Dir: dir, File: file}, nil
} }
// Join joins any number of path elements into a single path, adding a // Join joins any number of path elements into a single path, adding a

View file

@ -18,6 +18,7 @@ import (
"testing" "testing"
qt "github.com/frankban/quicktest" qt "github.com/frankban/quicktest"
"github.com/gohugoio/hugo/common/paths"
"github.com/gohugoio/hugo/config" "github.com/gohugoio/hugo/config"
"github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/deps"
) )
@ -157,7 +158,7 @@ func TestJoin(t *testing.T) {
`baz/foo/bar.txt`, `baz/foo/bar.txt`,
}, },
{ {
[]any{"", "baz", DirFile{"big", "john"}, filepath.FromSlash(`foo/bar.txt`)}, []any{"", "baz", paths.DirFile{Dir: "big", File: "john"}, filepath.FromSlash(`foo/bar.txt`)},
`baz/big|john/foo/bar.txt`, `baz/big|john/foo/bar.txt`,
}, },
{nil, ""}, {nil, ""},
@ -186,10 +187,10 @@ func TestSplit(t *testing.T) {
path any path any
expect any expect any
}{ }{
{filepath.FromSlash(`foo/bar.txt`), DirFile{`foo/`, `bar.txt`}}, {filepath.FromSlash(`foo/bar.txt`), paths.DirFile{Dir: `foo/`, File: `bar.txt`}},
{filepath.FromSlash(`foo/bar/txt `), DirFile{`foo/bar/`, `txt `}}, {filepath.FromSlash(`foo/bar/txt `), paths.DirFile{Dir: `foo/bar/`, File: `txt `}},
{`foo.bar.txt`, DirFile{``, `foo.bar.txt`}}, {`foo.bar.txt`, paths.DirFile{Dir: ``, File: `foo.bar.txt`}},
{``, DirFile{``, ``}}, {``, paths.DirFile{Dir: ``, File: ``}},
// errors // errors
{tstNoStringer{}, false}, {tstNoStringer{}, false},
} { } {

View file

@ -414,6 +414,7 @@ func (ns *Namespace) PostCSS(args ...any) (resource.Resource, error) {
return ns.postcssClient.Process(r, m) return ns.postcssClient.Process(r, m)
} }
// PostProcess processes r after the build.
func (ns *Namespace) PostProcess(r resource.Resource) (postpub.PostPublishedResource, error) { func (ns *Namespace) PostProcess(r resource.Resource) (postpub.PostPublishedResource, error) {
return ns.deps.ResourceSpec.PostProcess(r) return ns.deps.ResourceSpec.PostProcess(r)
} }

View file

@ -39,9 +39,9 @@ type htmlTag struct {
openTag bool openTag bool
} }
// Truncate truncates a given string to the specified length. // Truncate truncates the string in s to the specified length.
func (ns *Namespace) Truncate(a any, options ...any) (template.HTML, error) { func (ns *Namespace) Truncate(s any, options ...any) (template.HTML, error) {
length, err := cast.ToIntE(a) length, err := cast.ToIntE(s)
if err != nil { if err != nil {
return "", err return "", err
} }

View file

@ -11,6 +11,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// Package tpl contains template functions and related types.
package tpl package tpl
import ( import (