page_lazy_contentprovider.go (3381B)
1 // Copyright 2019 The Hugo Authors. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13
14 package page
15
16 import (
17 "html/template"
18
19 "github.com/gohugoio/hugo/lazy"
20 )
21
22 // OutputFormatContentProvider represents the method set that is "outputFormat aware" and that we
23 // provide lazy initialization for in case they get invoked outside of their normal rendering context, e.g. via .Translations.
24 // Note that this set is currently not complete, but should cover the most common use cases.
25 // For the others, the implementation will be from the page.NoopPage.
26 type OutputFormatContentProvider interface {
27 ContentProvider
28 TableOfContentsProvider
29 PageRenderProvider
30 }
31
32 // LazyContentProvider initializes itself when read. Each method of the
33 // ContentProvider interface initializes a content provider and shares it
34 // with other methods.
35 //
36 // Used in cases where we cannot guarantee whether the content provider
37 // will be needed. Must create via NewLazyContentProvider.
38 type LazyContentProvider struct {
39 init *lazy.Init
40 cp OutputFormatContentProvider
41 }
42
43 // NewLazyContentProvider returns a LazyContentProvider initialized with
44 // function f. The resulting LazyContentProvider calls f in order to
45 // retrieve a ContentProvider
46 func NewLazyContentProvider(f func() (OutputFormatContentProvider, error)) *LazyContentProvider {
47 lcp := LazyContentProvider{
48 init: lazy.New(),
49 cp: NopPage,
50 }
51 lcp.init.Add(func() (any, error) {
52 cp, err := f()
53 if err != nil {
54 return nil, err
55 }
56 lcp.cp = cp
57 return nil, nil
58 })
59 return &lcp
60 }
61
62 func (lcp *LazyContentProvider) Reset() {
63 lcp.init.Reset()
64 }
65
66 func (lcp *LazyContentProvider) Content() (any, error) {
67 lcp.init.Do()
68 return lcp.cp.Content()
69 }
70
71 func (lcp *LazyContentProvider) Plain() string {
72 lcp.init.Do()
73 return lcp.cp.Plain()
74 }
75
76 func (lcp *LazyContentProvider) PlainWords() []string {
77 lcp.init.Do()
78 return lcp.cp.PlainWords()
79 }
80
81 func (lcp *LazyContentProvider) Summary() template.HTML {
82 lcp.init.Do()
83 return lcp.cp.Summary()
84 }
85
86 func (lcp *LazyContentProvider) Truncated() bool {
87 lcp.init.Do()
88 return lcp.cp.Truncated()
89 }
90
91 func (lcp *LazyContentProvider) FuzzyWordCount() int {
92 lcp.init.Do()
93 return lcp.cp.FuzzyWordCount()
94 }
95
96 func (lcp *LazyContentProvider) WordCount() int {
97 lcp.init.Do()
98 return lcp.cp.WordCount()
99 }
100
101 func (lcp *LazyContentProvider) ReadingTime() int {
102 lcp.init.Do()
103 return lcp.cp.ReadingTime()
104 }
105
106 func (lcp *LazyContentProvider) Len() int {
107 lcp.init.Do()
108 return lcp.cp.Len()
109 }
110
111 func (lcp *LazyContentProvider) Render(layout ...string) (template.HTML, error) {
112 lcp.init.Do()
113 return lcp.cp.Render(layout...)
114 }
115
116 func (lcp *LazyContentProvider) RenderString(args ...any) (template.HTML, error) {
117 lcp.init.Do()
118 return lcp.cp.RenderString(args...)
119 }
120
121 func (lcp *LazyContentProvider) TableOfContents() template.HTML {
122 lcp.init.Do()
123 return lcp.cp.TableOfContents()
124 }