content_render_hooks_test.go - hugo - [fork] hugo port for 9front
(HTM) git clone https://git.drkhsh.at/hugo.git
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) Submodules
(DIR) README
(DIR) LICENSE
---
content_render_hooks_test.go (11436B)
---
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 "strings"
19 "testing"
20
21 qt "github.com/frankban/quicktest"
22 )
23
24 func TestRenderHooksRSS(t *testing.T) {
25 files := `
26 -- hugo.toml --
27 baseURL = "https://example.org"
28 disableKinds = ["taxonomy", "term"]
29 -- layouts/index.html --
30 {{ $p := site.GetPage "p1.md" }}
31 {{ $p2 := site.GetPage "p2.md" }}
32 P1: {{ $p.Content }}
33 P2: {{ $p2.Content }}
34 -- layouts/index.xml --
35 {{ $p2 := site.GetPage "p2.md" }}
36 {{ $p3 := site.GetPage "p3.md" }}
37 P2: {{ $p2.Content }}
38 P3: {{ $p3.Content }}
39 -- layouts/_default/_markup/render-link.html --
40 html-link: {{ .Destination | safeURL }}|
41 -- layouts/_default/_markup/render-link.rss.xml --
42 xml-link: {{ .Destination | safeURL }}|
43 -- layouts/_default/_markup/render-heading.html --
44 html-heading: {{ .Text }}|
45 -- layouts/_default/_markup/render-heading.rss.xml --
46 xml-heading: {{ .Text }}|
47 -- content/p1.md --
48 ---
49 title: "p1"
50 ---
51 P1. [I'm an inline-style link](https://www.gohugo.io)
52
53 # Heading in p1
54
55 -- content/p2.md --
56 ---
57 title: "p2"
58 ---
59 P2. [I'm an inline-style link](https://www.bep.is)
60
61 # Heading in p2
62
63 -- content/p3.md --
64 ---
65 title: "p3"
66 outputs: ["rss"]
67 ---
68 P3. [I'm an inline-style link](https://www.example.org)
69 `
70 b := Test(t, files)
71
72 b.AssertFileContent("public/index.html", `
73 P1: <p>P1. html-link: https://www.gohugo.io|</p>
74 html-heading: Heading in p1|
75 html-heading: Heading in p2|
76 `)
77 b.AssertFileContent("public/index.xml", `
78 P2: <p>P2. xml-link: https://www.bep.is|</p>
79 P3: <p>P3. xml-link: https://www.example.org|</p>
80 xml-heading: Heading in p2|
81 `)
82 }
83
84 // Issue 13242.
85 func TestRenderHooksRSSOnly(t *testing.T) {
86 files := `
87 -- hugo.toml --
88 baseURL = "https://example.org"
89 disableKinds = ["taxonomy", "term"]
90 -- layouts/index.html --
91 {{ $p := site.GetPage "p1.md" }}
92 {{ $p2 := site.GetPage "p2.md" }}
93 P1: {{ $p.Content }}
94 P2: {{ $p2.Content }}
95 -- layouts/index.xml --
96 {{ $p2 := site.GetPage "p2.md" }}
97 {{ $p3 := site.GetPage "p3.md" }}
98 P2: {{ $p2.Content }}
99 P3: {{ $p3.Content }}
100 -- layouts/_default/_markup/render-link.rss.xml --
101 xml-link: {{ .Destination | safeURL }}|
102 -- layouts/_default/_markup/render-heading.rss.xml --
103 xml-heading: {{ .Text }}|
104 -- content/p1.md --
105 ---
106 title: "p1"
107 ---
108 P1. [I'm an inline-style link](https://www.gohugo.io)
109
110 # Heading in p1
111
112 -- content/p2.md --
113 ---
114 title: "p2"
115 ---
116 P2. [I'm an inline-style link](https://www.bep.is)
117
118 # Heading in p2
119
120 -- content/p3.md --
121 ---
122 title: "p3"
123 outputs: ["rss"]
124 ---
125 P3. [I'm an inline-style link](https://www.example.org)
126 `
127 b := Test(t, files)
128
129 b.AssertFileContent("public/index.html", `
130 P1: <p>P1. <a href="https://www.gohugo.io">I’m an inline-style link</a></p>
131 <h1 id="heading-in-p1">Heading in p1</h1>
132 <h1 id="heading-in-p2">Heading in p2</h1>
133 `)
134
135 b.AssertFileContent("public/index.xml", `
136 P2: <p>P2. xml-link: https://www.bep.is|</p>
137 P3: <p>P3. xml-link: https://www.example.org|</p>
138 xml-heading: Heading in p2|
139 `)
140 }
141
142 // https://github.com/gohugoio/hugo/issues/6629
143 func TestRenderLinkWithMarkupInText(t *testing.T) {
144 b := newTestSitesBuilder(t)
145 b.WithConfigFile("toml", `
146
147 baseURL="https://example.org"
148
149 [markup]
150 [markup.goldmark]
151 [markup.goldmark.renderer]
152 unsafe = true
153
154 `)
155
156 b.WithTemplates("index.html", `
157 {{ $p := site.GetPage "p1.md" }}
158 P1: {{ $p.Content }}
159
160 `,
161 "_default/_markup/render-link.html", `html-link: {{ .Destination | safeURL }}|Text: {{ .Text }}|Plain: {{ .PlainText | safeHTML }}`,
162 "_default/_markup/render-image.html", `html-image: {{ .Destination | safeURL }}|Text: {{ .Text }}|Plain: {{ .PlainText | safeHTML }}`,
163 )
164
165 b.WithContent("p1.md", `---
166 title: "p1"
167 ---
168
169 START: [**should be bold**](https://gohugo.io)END
170
171 Some regular **markup**.
172
173 Image:
174
175 END
176
177 `)
178
179 b.Build(BuildCfg{})
180
181 b.AssertFileContent("public/index.html", `
182 P1: <p>START: html-link: https://gohugo.io|Text: <strong>should be bold</strong>|Plain: should be boldEND</p>
183 <p>Some regular <strong>markup</strong>.</p>
184 <p>html-image: image.jpg|Text: Hello<br> Goodbye|Plain: Hello GoodbyeEND</p>
185 `)
186 }
187
188 func TestRenderHookContentFragmentsOnSelf(t *testing.T) {
189 files := `
190 -- hugo.toml --
191 baseURL = "https://example.org"
192 disableKinds = ["taxonomy", "term", "RSS", "sitemap", "robotsTXT"]
193 -- content/p1.md --
194 ---
195 title: "p1"
196 ---
197
198 ## A {#z}
199 ## B
200 ## C
201
202 -- content/p2.md --
203 ---
204 title: "p2"
205 ---
206
207 ## D
208 ## E
209 ## F
210
211 -- layouts/_default/_markup/render-heading.html --
212 Heading: {{ .Text }}|
213 {{ with .Page }}
214 Self Fragments: {{ .Fragments.Identifiers }}|
215 {{ end }}
216 {{ with (site.GetPage "p1.md") }}
217 P1 Fragments: {{ .Fragments.Identifiers }}|
218 {{ end }}
219 -- layouts/_default/single.html --
220 {{ .Content}}
221 `
222
223 b := Test(t, files)
224
225 b.AssertFileContent("public/p1/index.html", `
226 Self Fragments: [b c z]
227 P1 Fragments: [b c z]
228 `)
229 b.AssertFileContent("public/p2/index.html", `
230 Self Fragments: [d e f]
231 P1 Fragments: [b c z]
232 `)
233 }
234
235 func TestDefaultRenderHooksMultilingual(t *testing.T) {
236 files := `
237 -- hugo.toml --
238 baseURL = "https://example.org"
239 disableKinds = ["taxonomy", "term", "RSS", "sitemap", "robotsTXT"]
240 defaultContentLanguage = "nn"
241 defaultContentLanguageInSubdir = true
242 [markup]
243 [markup.goldmark]
244 duplicateResourceFiles = false
245 [markup.goldmark.renderhooks]
246 [markup.goldmark.renderhooks.link]
247 #enableDefault = false
248 [markup.goldmark.renderhooks.image]
249 #enableDefault = false
250 [languages]
251 [languages.en]
252 weight = 1
253 [languages.nn]
254 weight = 2
255 -- content/p1/index.md --
256 ---
257 title: "p1"
258 ---
259 [P2](p2)
260 
261 -- content/p2/index.md --
262 ---
263 title: "p2"
264 ---
265 [P1](p1)
266 
267 -- content/p1/index.en.md --
268 ---
269 title: "p1 en"
270 ---
271 [P2](p2)
272 
273 -- content/p2/index.en.md --
274 ---
275 title: "p2 en"
276 ---
277 [P1](p1)
278 
279
280 -- content/p1/pixel.nn.png --
281 iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==
282 -- content/p2/pixel.png --
283 iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==
284 -- layouts/_default/single.html --
285 {{ .Title }}|{{ .Content }}|$
286
287 `
288
289 t.Run("Default multilingual", func(t *testing.T) {
290 b := Test(t, files)
291
292 b.AssertFileContent("public/nn/p1/index.html",
293 "p1|<p><a href=\"/nn/p2/\">P2</a\n></p>", "<img src=\"/nn/p1/pixel.nn.png\" alt=\"Pixel\">")
294 b.AssertFileContent("public/en/p1/index.html",
295 "p1 en|<p><a href=\"/en/p2/\">P2</a\n></p>", "<img src=\"/nn/p1/pixel.nn.png\" alt=\"Pixel\">")
296 })
297
298 t.Run("Disabled", func(t *testing.T) {
299 b := Test(t, strings.ReplaceAll(files, "#enableDefault = false", "enableDefault = false"))
300
301 b.AssertFileContent("public/nn/p1/index.html",
302 "p1|<p><a href=\"p2\">P2</a>", "<img src=\"pixel.png\" alt=\"Pixel\">")
303 })
304 }
305
306 func TestRenderHooksDefaultEscape(t *testing.T) {
307 files := `
308 -- hugo.toml --
309 [markup.goldmark.extensions.typographer]
310 disable = true
311 [markup.goldmark.renderHooks.image]
312 enableDefault = ENABLE
313 [markup.goldmark.renderHooks.link]
314 enableDefault = ENABLE
315 [markup.goldmark.parser]
316 wrapStandAloneImageWithinParagraph = false
317 [markup.goldmark.parser.attribute]
318 block = true
319 title = true
320
321 -- content/_index.md --
322 ---
323 title: "Home"
324 ---
325 Link: [text-"<>&](/destination-"<> 'title-"<>&')
326
327 Image: 
328 {class="><script>alert()</script>" id="baz"}
329
330 -- layouts/index.html --
331 {{ .Content }}
332 `
333
334 for _, enabled := range []bool{true, false} {
335 enabled := enabled
336 t.Run(fmt.Sprint(enabled), func(t *testing.T) {
337 t.Parallel()
338 b := Test(t, strings.ReplaceAll(files, "ENABLE", fmt.Sprint(enabled)))
339
340 // The escaping is slightly different between the two.
341 if enabled {
342 b.AssertFileContent("public/index.html",
343 "Link: <a href=\"/destination-%22%3C%3E\" title=\"title-"<>&\">text-"<>&</a>",
344 "img src=\"/destination-%22%3C%3E\" alt=\"alt-"<>&\" title=\"title-"<>&\">",
345 "><script>",
346 )
347 } else {
348 b.AssertFileContent("public/index.html",
349 "Link: <a href=\"/destination-%22%3C%3E\" title=\"title-"<>&\">text-"<>&</a>",
350 "Image: <img src=\"/destination-%22%3C%3E\" alt=\"alt-"<>&\" title=\"title-"<>&\">",
351 )
352 }
353 })
354 }
355 }
356
357 // Issue 13410.
358 func TestRenderHooksMultilineTitlePlainText(t *testing.T) {
359 t.Parallel()
360
361 files := `
362 -- hugo.toml --
363 -- content/p1.md --
364 ---
365 title: "p1"
366 ---
367
368 First line.
369 Second line.
370 ----------------
371 -- layouts/_default/_markup/render-heading.html --
372 Plain text: {{ .PlainText }}|Text: {{ .Text }}|
373 -- layouts/_default/single.html --
374 Content: {{ .Content}}|
375 }
376 `
377 b := Test(t, files)
378
379 b.AssertFileContent("public/p1/index.html",
380 "Content: Plain text: First line.\nSecond line.|",
381 "|Text: First line.\nSecond line.||\n",
382 )
383 }
384
385 func TestContentOutputReuseRenderHooksAndShortcodesHTMLOnly(t *testing.T) {
386 files := `
387 -- hugo.toml --
388 -- layouts/index.html --
389 HTML: {{ .Title }}|{{ .Content }}|
390 -- layouts/index.xml --
391 XML: {{ .Title }}|{{ .Content }}|
392 -- layouts/_markup/render-heading.html --
393 Render heading.
394 -- layouts/shortcodes/myshortcode.html --
395 My shortcode.
396 -- content/_index.md --
397 ---
398 title: "Home"
399 ---
400 ## Heading
401
402 {{< myshortcode >}}
403 `
404 b := Test(t, files)
405
406 s := b.H.Sites[0]
407 b.Assert(s.home.pageOutputTemplateVariationsState.Load(), qt.Equals, uint32(1))
408 b.AssertFileContent("public/index.html", "HTML: Home|Render heading.\nMy shortcode.\n|")
409 b.AssertFileContent("public/index.xml", "XML: Home|Render heading.\nMy shortcode.\n|")
410 }
411
412 func TestContentOutputNoReuseRenderHooksInBothHTMLAnXML(t *testing.T) {
413 files := `
414 -- hugo.toml --
415 disableKinds = ["taxonomy", "term"]
416 -- layouts/index.html --
417 HTML: {{ .Title }}|{{ .Content }}|
418 -- layouts/index.xml --
419 XML: {{ .Title }}|{{ .Content }}|
420 -- layouts/_markup/render-heading.html --
421 Render heading.
422 -- layouts/_markup/render-heading.xml --
423 Render heading XML.
424 -- content/_index.md --
425 ---
426 title: "Home"
427 ---
428 ## Heading
429
430
431 `
432 b := Test(t, files)
433
434 s := b.H.Sites[0]
435 b.Assert(s.home.pageOutputTemplateVariationsState.Load() > 1, qt.IsTrue)
436 b.AssertFileContentExact("public/index.xml", "XML: Home|Render heading XML.|")
437 b.AssertFileContentExact("public/index.html", "HTML: Home|Render heading.|")
438 }
439
440 func TestContentOutputNoReuseShortcodesInBothHTMLAnXML(t *testing.T) {
441 files := `
442 -- hugo.toml --
443 disableKinds = ["taxonomy", "term"]
444 -- layouts/index.html --
445 HTML: {{ .Title }}|{{ .Content }}|
446 -- layouts/index.xml --
447 XML: {{ .Title }}|{{ .Content }}|
448 -- layouts/_markup/render-heading.html --
449 Render heading.
450
451 -- layouts/shortcodes/myshortcode.html --
452 My shortcode HTML.
453 -- layouts/shortcodes/myshortcode.xml --
454 My shortcode XML.
455 -- content/_index.md --
456 ---
457 title: "Home"
458 ---
459 ## Heading
460
461 {{< myshortcode >}}
462
463
464 `
465 b := Test(t, files)
466
467 b.AssertFileContentExact("public/index.xml", "My shortcode XML.")
468 b.AssertFileContentExact("public/index.html", "My shortcode HTML.")
469 s := b.H.Sites[0]
470 b.Assert(s.home.pageOutputTemplateVariationsState.Load() > 1, qt.IsTrue)
471 }