]> git.maquefel.me Git - brevno-suite/hugo/commitdiff
Fix .Fragments when called cross sites on uninitialized output format
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Sun, 5 Mar 2023 09:32:00 +0000 (10:32 +0100)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Sun, 5 Mar 2023 11:51:57 +0000 (12:51 +0100)
Fixes #10794

hugolib/page.go
hugolib/page__fragments_test.go [new file with mode: 0644]
hugolib/page__output.go
hugolib/page__per_output.go
hugolib/shortcode_page.go
resources/page/page.go
resources/page/page_lazy_contentprovider.go

index aa107c63eb8ed063529988f758e433bfcd88c455..a80b28a3e255ce7e0ff08bbeeaa0c9d8f334e1c1 100644 (file)
@@ -17,7 +17,6 @@ import (
        "bytes"
        "context"
        "fmt"
-       "html/template"
        "path"
        "path/filepath"
        "sort"
@@ -151,19 +150,6 @@ func (p *pageState) GetIdentity() identity.Identity {
        return identity.NewPathIdentity(files.ComponentFolderContent, filepath.FromSlash(p.Pathc()))
 }
 
-func (p *pageState) Fragments(ctx context.Context) *tableofcontents.Fragments {
-       p.s.initInit(ctx, p.cp.initToC, p)
-       if p.pageOutput.cp.tableOfContents == nil {
-               return tableofcontents.Empty
-       }
-       return p.pageOutput.cp.tableOfContents
-}
-
-func (p *pageState) TableOfContents(ctx context.Context) template.HTML {
-       p.s.initInit(ctx, p.cp.initToC, p)
-       return p.pageOutput.cp.tableOfContentsHTML
-}
-
 func (p *pageState) HeadingsFiltered(context.Context) tableofcontents.Headings {
        return nil
 }
@@ -957,6 +943,7 @@ func (p *pageState) shiftToOutputFormat(isRenderingSite bool, idx int) error {
                        p.pageOutput.contentRenderer = lcp
                        p.pageOutput.ContentProvider = lcp
                        p.pageOutput.PageRenderProvider = lcp
+                       p.pageOutput.TableOfContentsProvider = lcp
                }
        }
 
diff --git a/hugolib/page__fragments_test.go b/hugolib/page__fragments_test.go
new file mode 100644 (file)
index 0000000..4b17378
--- /dev/null
@@ -0,0 +1,69 @@
+// 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 hugolib
+
+import "testing"
+
+// #10794
+func TestFragmentsAndToCCrossSiteAccess(t *testing.T) {
+       files := `
+-- hugo.toml --
+baseURL = "https://example.com"
+disableKinds = ["taxonomy", "term", "home"]
+defaultContentLanguage = "en"
+defaultContentLanguageInSubdir = true
+[languages]
+[languages.en]
+weight = 1
+[languages.fr]
+weight = 2
+-- content/p1.en.md --
+---
+title: "P1"
+outputs: ["HTML", "JSON"]
+---
+
+## Heading 1 EN
+
+-- content/p1.fr.md --
+---
+title: "P1"
+outputs: ["HTML", "JSON"]
+---
+
+## Heading 1 FR
+-- layouts/_default/single.html --
+HTML
+-- layouts/_default/single.json --
+{{ $secondSite := index .Sites 1 }}
+{{ $p1 := $secondSite.GetPage "p1" }}
+ToC: {{ $p1.TableOfContents }}
+Fragments : {{ $p1.Fragments.Identifiers }}
+
+
+
+       
+`
+
+       b := NewIntegrationTestBuilder(
+               IntegrationTestConfig{
+                       TxtarString: files,
+                       T:           t,
+               },
+       ).Build()
+
+       b.AssertFileContent("public/en/p1/index.html", "HTML")
+       b.AssertFileContent("public/en/p1/index.json", "ToC: <nav id=\"TableOfContents\">\n  <ul>\n    <li><a href=\"#heading-1-fr\">Heading 1 FR</a></li>\n  </ul>\n</nav>\nFragments : [heading-1-fr]")
+
+}
index ae2fdb7786680ec360cc9881e742a980d1b6c539..25ce26b7a4f2dbabec75e08698bc63a7844d251f 100644 (file)
@@ -54,12 +54,13 @@ func newPageOutput(
        }
 
        po := &pageOutput{
-               f:                      f,
-               pagePerOutputProviders: providers,
-               ContentProvider:        page.NopPage,
-               PageRenderProvider:     page.NopPage,
-               render:                 render,
-               paginator:              pag,
+               f:                       f,
+               pagePerOutputProviders:  providers,
+               ContentProvider:         page.NopPage,
+               PageRenderProvider:      page.NopPage,
+               TableOfContentsProvider: page.NopPage,
+               render:                  render,
+               paginator:               pag,
        }
 
        return po
@@ -84,6 +85,7 @@ type pageOutput struct {
        pagePerOutputProviders
        page.ContentProvider
        page.PageRenderProvider
+       page.TableOfContentsProvider
 
        // May be nil.
        cp *pageContentOutput
@@ -96,6 +98,7 @@ func (p *pageOutput) initContentProvider(cp *pageContentOutput) {
        p.contentRenderer = cp
        p.ContentProvider = cp
        p.PageRenderProvider = cp
+       p.TableOfContentsProvider = cp
        p.cp = cp
 
 }
index be65ad9e723d994e87aa48d2002af7739641cf70..3e61a45133ac87b28a1b4dfd16c6a2ed4df7e71d 100644 (file)
@@ -342,6 +342,19 @@ func (p *pageContentOutput) Reset() {
        p.renderHooks = &renderHooks{}
 }
 
+func (p *pageContentOutput) Fragments(ctx context.Context) *tableofcontents.Fragments {
+       p.p.s.initInit(ctx, p.initToC, p.p)
+       if p.tableOfContents == nil {
+               return tableofcontents.Empty
+       }
+       return p.tableOfContents
+}
+
+func (p *pageContentOutput) TableOfContents(ctx context.Context) template.HTML {
+       p.p.s.initInit(ctx, p.initToC, p.p)
+       return p.tableOfContentsHTML
+}
+
 func (p *pageContentOutput) Content(ctx context.Context) (any, error) {
        p.p.s.initInit(ctx, p.initMain, p.p)
        return p.content, nil
@@ -380,11 +393,6 @@ func (p *pageContentOutput) Summary(ctx context.Context) template.HTML {
        return p.summary
 }
 
-func (p *pageContentOutput) TableOfContents(ctx context.Context) template.HTML {
-       p.p.s.initInit(ctx, p.initMain, p.p)
-       return p.tableOfContentsHTML
-}
-
 func (p *pageContentOutput) Truncated(ctx context.Context) bool {
        if p.p.truncated {
                return true
index 3bc061bc08416092172d90319eb30d5dc6a90328..20fa22d2fe6f03d5ee03661bca9db7e6af1b126b 100644 (file)
@@ -63,6 +63,7 @@ var zeroShortcode = prerenderedShortcode{}
 // the best we can do.
 type pageForShortcode struct {
        page.PageWithoutContent
+       page.TableOfContentsProvider
        page.ContentProvider
 
        // We need to replace it after we have rendered it, so provide a
@@ -74,10 +75,11 @@ type pageForShortcode struct {
 
 func newPageForShortcode(p *pageState) page.Page {
        return &pageForShortcode{
-               PageWithoutContent: p,
-               ContentProvider:    page.NopPage,
-               toc:                template.HTML(tocShortcodePlaceholder),
-               p:                  p,
+               PageWithoutContent:      p,
+               TableOfContentsProvider: p,
+               ContentProvider:         page.NopPage,
+               toc:                     template.HTML(tocShortcodePlaceholder),
+               p:                       p,
        }
 }
 
@@ -105,7 +107,7 @@ func newPageForRenderHook(p *pageState) page.Page {
        return &pageForRenderHooks{
                PageWithoutContent:      p,
                ContentProvider:         page.NopPage,
-               TableOfContentsProvider: page.NopPage,
+               TableOfContentsProvider: p,
        }
 }
 
index 8f89142b3c5e4b0e175eca85db61f3896c08edf8..6f6f1d10003523bcd2d468c567350fa386068a66 100644 (file)
@@ -334,9 +334,6 @@ type PageWithoutContent interface {
        // Used in change/dependency tracking.
        identity.Provider
 
-       // Fragments returns the fragments for this page.
-       Fragments(context.Context) *tableofcontents.Fragments
-
        // Headings 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.
@@ -407,6 +404,9 @@ type SitesProvider interface {
 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.
index 400b9e4f0751ebf988b78bed89d4b77c4cfcadd6..2d647e90c171661b1f9494060b58e85a59ea39e5 100644 (file)
@@ -19,6 +19,7 @@ import (
 
        "github.com/gohugoio/hugo/lazy"
        "github.com/gohugoio/hugo/markup/converter"
+       "github.com/gohugoio/hugo/markup/tableofcontents"
 )
 
 // OutputFormatContentProvider represents the method set that is "outputFormat aware" and that we
@@ -73,6 +74,17 @@ func (lcp *LazyContentProvider) Reset() {
        lcp.init.Reset()
 }
 
+func (lcp *LazyContentProvider) TableOfContents(ctx context.Context) template.HTML {
+       lcp.init.Do(ctx)
+       return lcp.cp.TableOfContents(ctx)
+
+}
+
+func (lcp *LazyContentProvider) Fragments(ctx context.Context) *tableofcontents.Fragments {
+       lcp.init.Do(ctx)
+       return lcp.cp.Fragments(ctx)
+}
+
 func (lcp *LazyContentProvider) Content(ctx context.Context) (any, error) {
        lcp.init.Do(ctx)
        return lcp.cp.Content(ctx)