hugo

Fork of github.com/gohugoio/hugo with reverse pagination support

git clone git://git.shimmy1996.com/hugo.git

content_render_hooks_test.go (13420B)

    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 requiredF 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 	"fmt"
   18 	"testing"
   19 
   20 	qt "github.com/frankban/quicktest"
   21 )
   22 
   23 func TestRenderHookEditNestedPartial(t *testing.T) {
   24 	config := `
   25 baseURL="https://example.org"
   26 workingDir="/mywork"
   27 `
   28 	b := newTestSitesBuilder(t).WithWorkingDir("/mywork").WithConfigFile("toml", config).Running()
   29 
   30 	b.WithTemplates("_default/single.html", "{{ .Content }}")
   31 	b.WithTemplates("partials/mypartial1.html", `PARTIAL1 {{ partial "mypartial2.html" }}`)
   32 	b.WithTemplates("partials/mypartial2.html", `PARTIAL2`)
   33 	b.WithTemplates("_default/_markup/render-link.html", `Link {{ .Text | safeHTML }}|{{ partial "mypartial1.html" . }}END`)
   34 
   35 	b.WithContent("p1.md", `---
   36 title: P1
   37 ---
   38 
   39 [First Link](https://www.google.com "Google's Homepage")
   40 
   41 `)
   42 	b.Build(BuildCfg{})
   43 
   44 	b.AssertFileContent("public/p1/index.html", `Link First Link|PARTIAL1 PARTIAL2END`)
   45 
   46 	b.EditFiles("layouts/partials/mypartial1.html", `PARTIAL1_EDITED {{ partial "mypartial2.html" }}`)
   47 
   48 	b.Build(BuildCfg{})
   49 
   50 	b.AssertFileContent("public/p1/index.html", `Link First Link|PARTIAL1_EDITED PARTIAL2END`)
   51 
   52 	b.EditFiles("layouts/partials/mypartial2.html", `PARTIAL2_EDITED`)
   53 
   54 	b.Build(BuildCfg{})
   55 
   56 	b.AssertFileContent("public/p1/index.html", `Link First Link|PARTIAL1_EDITED PARTIAL2_EDITEDEND`)
   57 }
   58 
   59 func TestRenderHooks(t *testing.T) {
   60 	config := `
   61 baseURL="https://example.org"
   62 workingDir="/mywork"
   63 
   64 [markup]
   65 [markup.goldmark]
   66 [markup.goldmark.parser]
   67 autoHeadingID = true
   68 autoHeadingIDType = "github"
   69 [markup.goldmark.parser.attribute]
   70 block = true
   71 title = true
   72 
   73 `
   74 	b := newTestSitesBuilder(t).WithWorkingDir("/mywork").WithConfigFile("toml", config).Running()
   75 	b.WithTemplatesAdded("_default/single.html", `{{ .Content }}`)
   76 	b.WithTemplatesAdded("shortcodes/myshortcode1.html", `{{ partial "mypartial1" }}`)
   77 	b.WithTemplatesAdded("shortcodes/myshortcode2.html", `{{ partial "mypartial2" }}`)
   78 	b.WithTemplatesAdded("shortcodes/myshortcode3.html", `SHORT3|`)
   79 	b.WithTemplatesAdded("shortcodes/myshortcode4.html", `
   80 <div class="foo">
   81 {{ .Inner | markdownify }}
   82 </div>
   83 `)
   84 	b.WithTemplatesAdded("shortcodes/myshortcode5.html", `
   85 Inner Inline: {{ .Inner | .Page.RenderString }}
   86 Inner Block: {{ .Inner | .Page.RenderString (dict "display" "block" ) }}
   87 `)
   88 
   89 	b.WithTemplatesAdded("shortcodes/myshortcode6.html", `.Render: {{ .Page.Render "myrender" }}`)
   90 	b.WithTemplatesAdded("partials/mypartial1.html", `PARTIAL1`)
   91 	b.WithTemplatesAdded("partials/mypartial2.html", `PARTIAL2  {{ partial "mypartial3.html" }}`)
   92 	b.WithTemplatesAdded("partials/mypartial3.html", `PARTIAL3`)
   93 	b.WithTemplatesAdded("partials/mypartial4.html", `PARTIAL4`)
   94 	b.WithTemplatesAdded("customview/myrender.html", `myrender: {{ .Title }}|P4: {{ partial "mypartial4" }}`)
   95 	b.WithTemplatesAdded("_default/_markup/render-link.html", `{{ with .Page }}{{ .Title }}{{ end }}|{{ .Destination | safeURL }}|Title: {{ .Title | safeHTML }}|Text: {{ .Text | safeHTML }}|END`)
   96 	b.WithTemplatesAdded("docs/_markup/render-link.html", `Link docs section: {{ .Text | safeHTML }}|END`)
   97 	b.WithTemplatesAdded("_default/_markup/render-image.html", `IMAGE: {{ .Page.Title }}||{{ .Destination | safeURL }}|Title: {{ .Title | safeHTML }}|Text: {{ .Text | safeHTML }}|END`)
   98 	b.WithTemplatesAdded("_default/_markup/render-heading.html", `HEADING: {{ .Page.Title }}||Level: {{ .Level }}|Anchor: {{ .Anchor | safeURL }}|Text: {{ .Text | safeHTML }}|Attributes: {{ .Attributes }}|END`)
   99 	b.WithTemplatesAdded("docs/_markup/render-heading.html", `Docs Level: {{ .Level }}|END`)
  100 
  101 	b.WithContent("customview/p1.md", `---
  102 title: Custom View
  103 ---
  104 
  105 {{< myshortcode6 >}}
  106 
  107 	`, "blog/p1.md", `---
  108 title: Cool Page
  109 ---
  110 
  111 [First Link](https://www.google.com "Google's Homepage")
  112 <https://foo.bar/>
  113 https://bar.baz/
  114 <fake@example.com>
  115 <mailto:fake2@example.com>
  116 
  117 {{< myshortcode3 >}}
  118 
  119 [Second Link](https://www.google.com "Google's Homepage")
  120 
  121 Image:
  122 
  123 ![Drag Racing](/images/Dragster.jpg "image title")
  124 
  125 Attributes:
  126 
  127 ## Some Heading {.text-serif #a-heading title="Hovered"} 
  128 
  129 
  130 `, "blog/p2.md", `---
  131 title: Cool Page2
  132 layout: mylayout
  133 ---
  134 
  135 {{< myshortcode1 >}}
  136 
  137 [Some Text](https://www.google.com "Google's Homepage")
  138 
  139 ,[No Whitespace Please](https://gohugo.io),
  140 
  141 
  142 
  143 `, "blog/p3.md", `---
  144 title: Cool Page3
  145 ---
  146 
  147 {{< myshortcode2 >}}
  148 
  149 
  150 `, "docs/docs1.md", `---
  151 title: Docs 1
  152 ---
  153 
  154 
  155 [Docs 1](https://www.google.com "Google's Homepage")
  156 
  157 
  158 `, "blog/p4.md", `---
  159 title: Cool Page With Image
  160 ---
  161 
  162 Image:
  163 
  164 ![Drag Racing](/images/Dragster.jpg "image title")
  165 
  166 
  167 `, "blog/p5.md", `---
  168 title: Cool Page With Markdownify
  169 ---
  170 
  171 {{< myshortcode4 >}}
  172 Inner Link: [Inner Link](https://www.google.com "Google's Homepage")
  173 {{< /myshortcode4 >}}
  174 
  175 `, "blog/p6.md", `---
  176 title: With RenderString
  177 ---
  178 
  179 {{< myshortcode5 >}}Inner Link: [Inner Link](https://www.gohugo.io "Hugo's Homepage"){{< /myshortcode5 >}}
  180 
  181 `, "blog/p7.md", `---
  182 title: With Headings
  183 ---
  184 
  185 # Heading Level 1
  186 some text
  187 
  188 ## Heading Level 2
  189 
  190 ### Heading Level 3
  191 `,
  192 		"docs/p8.md", `---
  193 title: Doc With Heading
  194 ---
  195 
  196 # Docs lvl 1
  197 
  198 `,
  199 	)
  200 
  201 	for i := 1; i <= 30; i++ {
  202 		// Add some content with no shortcodes or links, i.e no templates needed.
  203 		b.WithContent(fmt.Sprintf("blog/notempl%d.md", i), `---
  204 title: No Template
  205 ---
  206 
  207 ## Content
  208 `)
  209 	}
  210 	counters := &testCounters{}
  211 	b.Build(BuildCfg{testCounters: counters})
  212 	b.Assert(int(counters.contentRenderCounter), qt.Equals, 45)
  213 
  214 	b.AssertFileContent("public/blog/p1/index.html", `
  215 Cool Page|https://www.google.com|Title: Google's Homepage|Text: First Link|END
  216 Cool Page|https://foo.bar/|Title: |Text: https://foo.bar/|END
  217 Cool Page|https://bar.baz/|Title: |Text: https://bar.baz/|END
  218 Cool Page|mailto:fake@example.com|Title: |Text: fake@example.com|END
  219 Cool Page|mailto:fake2@example.com|Title: |Text: mailto:fake2@example.com|END
  220 Text: Second
  221 SHORT3|
  222 <p>IMAGE: Cool Page||/images/Dragster.jpg|Title: image title|Text: Drag Racing|END</p>
  223 `)
  224 
  225 	b.AssertFileContent("public/customview/p1/index.html", `.Render: myrender: Custom View|P4: PARTIAL4`)
  226 	b.AssertFileContent("public/blog/p2/index.html",
  227 		`PARTIAL
  228 ,Cool Page2|https://gohugo.io|Title: |Text: No Whitespace Please|END,`,
  229 	)
  230 	b.AssertFileContent("public/blog/p3/index.html", `PARTIAL3`)
  231 	// We may add type template support later, keep this for then. b.AssertFileContent("public/docs/docs1/index.html", `Link docs section: Docs 1|END`)
  232 	b.AssertFileContent("public/blog/p4/index.html", `<p>IMAGE: Cool Page With Image||/images/Dragster.jpg|Title: image title|Text: Drag Racing|END</p>`)
  233 	// markdownify
  234 	b.AssertFileContent("public/blog/p5/index.html", "Inner Link: |https://www.google.com|Title: Google's Homepage|Text: Inner Link|END")
  235 
  236 	b.AssertFileContent("public/blog/p6/index.html",
  237 		"Inner Inline: Inner Link: With RenderString|https://www.gohugo.io|Title: Hugo's Homepage|Text: Inner Link|END",
  238 		"Inner Block: <p>Inner Link: With RenderString|https://www.gohugo.io|Title: Hugo's Homepage|Text: Inner Link|END</p>",
  239 	)
  240 
  241 	b.EditFiles(
  242 		"layouts/_default/_markup/render-link.html", `EDITED: {{ .Destination | safeURL }}|`,
  243 		"layouts/_default/_markup/render-image.html", `IMAGE EDITED: {{ .Destination | safeURL }}|`,
  244 		"layouts/docs/_markup/render-link.html", `DOCS EDITED: {{ .Destination | safeURL }}|`,
  245 		"layouts/partials/mypartial1.html", `PARTIAL1_EDITED`,
  246 		"layouts/partials/mypartial3.html", `PARTIAL3_EDITED`,
  247 		"layouts/partials/mypartial4.html", `PARTIAL4_EDITED`,
  248 		"layouts/shortcodes/myshortcode3.html", `SHORT3_EDITED|`,
  249 	)
  250 
  251 	counters = &testCounters{}
  252 	b.Build(BuildCfg{testCounters: counters})
  253 	// Make sure that only content using the changed templates are re-rendered.
  254 	b.Assert(int(counters.contentRenderCounter), qt.Equals, 7)
  255 
  256 	b.AssertFileContent("public/customview/p1/index.html", `.Render: myrender: Custom View|P4: PARTIAL4_EDITED`)
  257 	b.AssertFileContent("public/blog/p1/index.html", `<p>EDITED: https://www.google.com|</p>`, "SHORT3_EDITED|")
  258 	b.AssertFileContent("public/blog/p2/index.html", `PARTIAL1_EDITED`)
  259 	b.AssertFileContent("public/blog/p3/index.html", `PARTIAL3_EDITED`)
  260 	// We may add type template support later, keep this for then. b.AssertFileContent("public/docs/docs1/index.html", `DOCS EDITED: https://www.google.com|</p>`)
  261 	b.AssertFileContent("public/blog/p4/index.html", `IMAGE EDITED: /images/Dragster.jpg|`)
  262 	b.AssertFileContent("public/blog/p6/index.html", "<p>Inner Link: EDITED: https://www.gohugo.io|</p>")
  263 	b.AssertFileContent("public/blog/p7/index.html", "HEADING: With Headings||Level: 1|Anchor: heading-level-1|Text: Heading Level 1|Attributes: map[id:heading-level-1]|END<p>some text</p>\nHEADING: With Headings||Level: 2|Anchor: heading-level-2|Text: Heading Level 2|Attributes: map[id:heading-level-2]|ENDHEADING: With Headings||Level: 3|Anchor: heading-level-3|Text: Heading Level 3|Attributes: map[id:heading-level-3]|END")
  264 
  265 	// https://github.com/gohugoio/hugo/issues/7349
  266 	b.AssertFileContent("public/docs/p8/index.html", "Docs Level: 1")
  267 }
  268 
  269 func TestRenderHooksDeleteTemplate(t *testing.T) {
  270 	config := `
  271 baseURL="https://example.org"
  272 workingDir="/mywork"
  273 `
  274 	b := newTestSitesBuilder(t).WithWorkingDir("/mywork").WithConfigFile("toml", config).Running()
  275 	b.WithTemplatesAdded("_default/single.html", `{{ .Content }}`)
  276 	b.WithTemplatesAdded("_default/_markup/render-link.html", `html-render-link`)
  277 
  278 	b.WithContent("p1.md", `---
  279 title: P1
  280 ---
  281 [First Link](https://www.google.com "Google's Homepage")
  282 
  283 `)
  284 	b.Build(BuildCfg{})
  285 
  286 	b.AssertFileContent("public/p1/index.html", `<p>html-render-link</p>`)
  287 
  288 	b.RemoveFiles(
  289 		"layouts/_default/_markup/render-link.html",
  290 	)
  291 
  292 	b.Build(BuildCfg{})
  293 	b.AssertFileContent("public/p1/index.html", `<p><a href="https://www.google.com" title="Google's Homepage">First Link</a></p>`)
  294 }
  295 
  296 func TestRenderHookAddTemplate(t *testing.T) {
  297 	config := `
  298 baseURL="https://example.org"
  299 workingDir="/mywork"
  300 `
  301 	b := newTestSitesBuilder(t).WithWorkingDir("/mywork").WithConfigFile("toml", config).Running()
  302 	b.WithTemplatesAdded("_default/single.html", `{{ .Content }}`)
  303 
  304 	b.WithContent("p1.md", `---
  305 title: P1
  306 ---
  307 [First Link](https://www.google.com "Google's Homepage")
  308 
  309 `)
  310 	b.Build(BuildCfg{})
  311 
  312 	b.AssertFileContent("public/p1/index.html", `<p><a href="https://www.google.com" title="Google's Homepage">First Link</a></p>`)
  313 
  314 	b.EditFiles("layouts/_default/_markup/render-link.html", `html-render-link`)
  315 
  316 	b.Build(BuildCfg{})
  317 
  318 	b.AssertFileContent("public/p1/index.html", `<p>html-render-link</p>`)
  319 }
  320 
  321 func TestRenderHooksRSS(t *testing.T) {
  322 	b := newTestSitesBuilder(t)
  323 
  324 	b.WithTemplates("index.html", `
  325 {{ $p := site.GetPage "p1.md" }}
  326 {{ $p2 := site.GetPage "p2.md" }}
  327 
  328 P1: {{ $p.Content }}
  329 P2: {{ $p2.Content }}
  330 	
  331 	`, "index.xml", `
  332 
  333 {{ $p2 := site.GetPage "p2.md" }}
  334 {{ $p3 := site.GetPage "p3.md" }}
  335 
  336 P2: {{ $p2.Content }}
  337 P3: {{ $p3.Content }}
  338 
  339 	
  340 	`,
  341 		"_default/_markup/render-link.html", `html-link: {{ .Destination | safeURL }}|`,
  342 		"_default/_markup/render-link.rss.xml", `xml-link: {{ .Destination | safeURL }}|`,
  343 		"_default/_markup/render-heading.html", `html-heading: {{ .Text }}|`,
  344 		"_default/_markup/render-heading.rss.xml", `xml-heading: {{ .Text }}|`,
  345 	)
  346 
  347 	b.WithContent("p1.md", `---
  348 title: "p1"
  349 ---
  350 P1. [I'm an inline-style link](https://www.gohugo.io)
  351 
  352 # Heading in p1
  353 
  354 `, "p2.md", `---
  355 title: "p2"
  356 ---
  357 P1. [I'm an inline-style link](https://www.bep.is)
  358 
  359 # Heading in p2
  360 
  361 `,
  362 		"p3.md", `---
  363 title: "p2"
  364 outputs: ["rss"]
  365 ---
  366 P3. [I'm an inline-style link](https://www.example.org)
  367 
  368 `,
  369 	)
  370 
  371 	b.Build(BuildCfg{})
  372 
  373 	b.AssertFileContent("public/index.html", `
  374 P1: <p>P1. html-link: https://www.gohugo.io|</p>
  375 html-heading: Heading in p1|
  376 html-heading: Heading in p2|
  377 `)
  378 	b.AssertFileContent("public/index.xml", `
  379 P2: <p>P1. xml-link: https://www.bep.is|</p>
  380 P3: <p>P3. xml-link: https://www.example.org|</p>
  381 xml-heading: Heading in p2|
  382 `)
  383 }
  384 
  385 // https://github.com/gohugoio/hugo/issues/6629
  386 func TestRenderLinkWithMarkupInText(t *testing.T) {
  387 	b := newTestSitesBuilder(t)
  388 	b.WithConfigFile("toml", `
  389 
  390 baseURL="https://example.org"
  391 
  392 [markup]
  393   [markup.goldmark]
  394     [markup.goldmark.renderer]
  395       unsafe = true
  396     
  397 `)
  398 
  399 	b.WithTemplates("index.html", `
  400 {{ $p := site.GetPage "p1.md" }}
  401 P1: {{ $p.Content }}
  402 
  403 	`,
  404 		"_default/_markup/render-link.html", `html-link: {{ .Destination | safeURL }}|Text: {{ .Text | safeHTML }}|Plain: {{ .PlainText | safeHTML }}`,
  405 		"_default/_markup/render-image.html", `html-image: {{ .Destination | safeURL }}|Text: {{ .Text | safeHTML }}|Plain: {{ .PlainText | safeHTML }}`,
  406 	)
  407 
  408 	b.WithContent("p1.md", `---
  409 title: "p1"
  410 ---
  411 
  412 START: [**should be bold**](https://gohugo.io)END
  413 
  414 Some regular **markup**.
  415 
  416 Image:
  417 
  418 ![Hello<br> Goodbye](image.jpg)END
  419 
  420 `)
  421 
  422 	b.Build(BuildCfg{})
  423 
  424 	b.AssertFileContent("public/index.html", `
  425   P1: <p>START: html-link: https://gohugo.io|Text: <strong>should be bold</strong>|Plain: should be boldEND</p>
  426 <p>Some regular <strong>markup</strong>.</p>
  427 <p>html-image: image.jpg|Text: Hello<br> Goodbye|Plain: Hello GoodbyeEND</p>
  428 `)
  429 }