github.com/graemephi/kahugo@v0.62.3-0.20211121071557-d78c0423784d/hugolib/page__output.go (about) 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 hugolib 15 16 import ( 17 "github.com/gohugoio/hugo/markup/converter" 18 "github.com/gohugoio/hugo/output" 19 "github.com/gohugoio/hugo/resources/page" 20 "github.com/gohugoio/hugo/resources/resource" 21 ) 22 23 func newPageOutput( 24 ps *pageState, 25 pp pagePaths, 26 f output.Format, 27 render bool) *pageOutput { 28 var targetPathsProvider targetPathsHolder 29 var linksProvider resource.ResourceLinksProvider 30 31 ft, found := pp.targetPaths[f.Name] 32 if !found { 33 // Link to the main output format 34 ft = pp.targetPaths[pp.firstOutputFormat.Format.Name] 35 } 36 targetPathsProvider = ft 37 linksProvider = ft 38 39 var paginatorProvider page.PaginatorProvider = page.NopPage 40 var pag *pagePaginator 41 42 if render && ps.IsNode() { 43 pag = newPagePaginator(ps) 44 paginatorProvider = pag 45 } 46 47 providers := struct { 48 page.PaginatorProvider 49 resource.ResourceLinksProvider 50 targetPather 51 }{ 52 paginatorProvider, 53 linksProvider, 54 targetPathsProvider, 55 } 56 57 po := &pageOutput{ 58 f: f, 59 pagePerOutputProviders: providers, 60 ContentProvider: page.NopPage, 61 TableOfContentsProvider: page.NopPage, 62 render: render, 63 paginator: pag, 64 } 65 66 return po 67 } 68 69 // We create a pageOutput for every output format combination, even if this 70 // particular page isn't configured to be rendered to that format. 71 type pageOutput struct { 72 // Set if this page isn't configured to be rendered to this format. 73 render bool 74 75 f output.Format 76 77 // Only set if render is set. 78 // Note that this will be lazily initialized, so only used if actually 79 // used in template(s). 80 paginator *pagePaginator 81 82 // These interface provides the functionality that is specific for this 83 // output format. 84 pagePerOutputProviders 85 page.ContentProvider 86 page.TableOfContentsProvider 87 88 // May be nil. 89 cp *pageContentOutput 90 } 91 92 func (o *pageOutput) initRenderHooks() error { 93 if o.cp == nil { 94 return nil 95 } 96 97 var initErr error 98 99 o.cp.renderHooks.init.Do(func() { 100 ps := o.cp.p 101 102 c := ps.getContentConverter() 103 if c == nil || !c.Supports(converter.FeatureRenderHooks) { 104 return 105 } 106 107 h, err := ps.createRenderHooks(o.f) 108 if err != nil { 109 initErr = err 110 return 111 } 112 o.cp.renderHooks.hooks = h 113 114 if !o.cp.renderHooksHaveVariants || h.IsZero() { 115 // Check if there is a different render hooks template 116 // for any of the other page output formats. 117 // If not, we can reuse this. 118 for _, po := range ps.pageOutputs { 119 if po.f.Name != o.f.Name { 120 h2, err := ps.createRenderHooks(po.f) 121 if err != nil { 122 initErr = err 123 return 124 } 125 126 if h2.IsZero() { 127 continue 128 } 129 130 if o.cp.renderHooks.hooks.IsZero() { 131 o.cp.renderHooks.hooks = h2 132 } 133 134 o.cp.renderHooksHaveVariants = !h2.Eq(o.cp.renderHooks.hooks) 135 136 if o.cp.renderHooksHaveVariants { 137 break 138 } 139 140 } 141 } 142 } 143 }) 144 145 return initErr 146 } 147 148 func (p *pageOutput) initContentProvider(cp *pageContentOutput) { 149 if cp == nil { 150 return 151 } 152 p.ContentProvider = cp 153 p.TableOfContentsProvider = cp 154 p.cp = cp 155 } 156 157 func (p *pageOutput) enablePlaceholders() { 158 if p.cp != nil { 159 p.cp.enablePlaceholders() 160 } 161 }