Compare commits

...

13 Commits

Author SHA1 Message Date
Bjørn Erik Pedersen 445eb9e6c3 Use Apache License without modification
Closes #12415
2024-04-23 09:15:10 +02:00
Bjørn Erik Pedersen 509ab08c1b markup/goldmark: Fix data race in the hugocontext wrapper
The window for this to happen is very small, but it has been reported by Go's race detector (-race flag) in a tests once.
2024-04-22 19:10:15 +02:00
Bjørn Erik Pedersen 2d75f539e1 Delete .hugo_build.lock
Added to Git by accident.
2024-04-22 16:57:48 +02:00
Bjørn Erik Pedersen 15a4b9b337 tpl: Escape .Title in built-in image and link render hooks
Co-authored-by: Joe Mooring <joe@mooring.com>
2024-04-22 16:54:24 +02:00
Joe Mooring 10a8448eee tpl/tplimpl: Improve embedded templates
- Do not call the YouTube oEmbed API
- Do not include the Hugo version in RSS feeds

Closes #12396
2024-04-22 15:57:37 +02:00
Eric Anderson 722c486a34 SECURITY.md: Update link to security model
The security model was moved in https://github.com/gohugoio/hugoDocs/pull/2495
2024-04-22 13:04:53 +02:00
Bjørn Erik Pedersen f40f50ead0 modules: Fix potential infinite loop in module collection
Fixes #12407
2024-04-22 11:34:11 +02:00
hugoreleaser 4e483f5d4a releaser: Bump versions for release of 0.125.2
[ci skip]
2024-04-20 15:29:44 +00:00
Bjørn Erik Pedersen 06d248910c Only add root sections to the section pages menu
Fixes #12399
2024-04-20 17:23:33 +02:00
Bjørn Erik Pedersen 004b694390 Fix partial rebuilds for SCSS fetched with GetMatch and similar
Fixes #12395
2024-04-20 15:09:12 +02:00
Joe Mooring da6112fc65 commands: Add gen chromastyles --lineNumbersTableStyle flag
For symmetry, also rename --linesStyle to --lineNumbersInlineStyle.

Closes #12393
2024-04-20 12:25:28 +02:00
Bjørn Erik Pedersen faf9fedc3d resources/images: Fix TestColorLuminance on s390x 2024-04-19 11:21:50 +02:00
Joe Mooring 11aa893198 commands: Provide examples for chromastyles flags
Closes #12387
2024-04-18 12:16:36 -07:00
24 changed files with 248 additions and 80 deletions
+1 -1
View File
@@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2022 The Hugo Authors.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
+1 -1
View File
@@ -4,4 +4,4 @@
Please report (suspected) security vulnerabilities to **[bjorn.erik.pedersen@gmail.com](mailto:bjorn.erik.pedersen@gmail.com)**. You will receive a response from us within 48 hours. If we can confirm the issue, we will release a patch as soon as possible depending on the complexity of the issue but historically within days.
Also see [Hugo's Security Model](https://gohugo.io/about/security-model/).
Also see [Hugo's Security Model](https://gohugo.io/about/security/).
+13 -3
View File
@@ -140,16 +140,25 @@ func (c *Cache) DrainEvictedIdentities() []identity.Identity {
}
// ClearMatching clears all partition for which the predicate returns true.
func (c *Cache) ClearMatching(predicate func(k, v any) bool) {
func (c *Cache) ClearMatching(predicatePartition func(k string, p PartitionManager) bool, predicateValue func(k, v any) bool) {
if predicatePartition == nil {
predicatePartition = func(k string, p PartitionManager) bool { return true }
}
if predicateValue == nil {
panic("nil predicateValue")
}
g := rungroup.Run[PartitionManager](context.Background(), rungroup.Config[PartitionManager]{
NumWorkers: len(c.partitions),
Handle: func(ctx context.Context, partition PartitionManager) error {
partition.clearMatching(predicate)
partition.clearMatching(predicateValue)
return nil
},
})
for _, p := range c.partitions {
for k, p := range c.partitions {
if !predicatePartition(k, p) {
continue
}
g.Enqueue(p)
}
@@ -356,6 +365,7 @@ func GetOrCreatePartition[K comparable, V any](c *Cache, name string, opts Optio
trace: c.opts.Log.Logger().WithLevel(logg.LevelTrace).WithField("partition", name),
opts: opts,
}
c.partitions[name] = partition
return partition
+1 -1
View File
@@ -156,7 +156,7 @@ func TestClear(t *testing.T) {
cache = newTestCache(t)
cache.ClearMatching(func(k, v any) bool {
cache.ClearMatching(nil, func(k, v any) bool {
return k.(string) == "clearOnRebuild"
})
+29 -21
View File
@@ -128,6 +128,7 @@ type rootCommand struct {
verbose bool
debug bool
quiet bool
devMode bool // Hidden flag.
renderToMemory bool
@@ -423,29 +424,33 @@ func (r *rootCommand) PreRun(cd, runner *simplecobra.Commandeer) error {
func (r *rootCommand) createLogger(running bool) (loggers.Logger, error) {
level := logg.LevelWarn
if r.logLevel != "" {
switch strings.ToLower(r.logLevel) {
case "debug":
level = logg.LevelDebug
case "info":
level = logg.LevelInfo
case "warn", "warning":
level = logg.LevelWarn
case "error":
level = logg.LevelError
default:
return nil, fmt.Errorf("invalid log level: %q, must be one of debug, warn, info or error", r.logLevel)
}
if r.devMode {
level = logg.LevelTrace
} else {
if r.verbose {
hugo.Deprecate("--verbose", "use --logLevel info", "v0.114.0")
hugo.Deprecate("--verbose", "use --logLevel info", "v0.114.0")
level = logg.LevelInfo
}
if r.logLevel != "" {
switch strings.ToLower(r.logLevel) {
case "debug":
level = logg.LevelDebug
case "info":
level = logg.LevelInfo
case "warn", "warning":
level = logg.LevelWarn
case "error":
level = logg.LevelError
default:
return nil, fmt.Errorf("invalid log level: %q, must be one of debug, warn, info or error", r.logLevel)
}
} else {
if r.verbose {
hugo.Deprecate("--verbose", "use --logLevel info", "v0.114.0")
hugo.Deprecate("--verbose", "use --logLevel info", "v0.114.0")
level = logg.LevelInfo
}
if r.debug {
hugo.Deprecate("--debug", "use --logLevel debug", "v0.114.0")
level = logg.LevelDebug
if r.debug {
hugo.Deprecate("--debug", "use --logLevel debug", "v0.114.0")
level = logg.LevelDebug
}
}
}
@@ -505,10 +510,13 @@ Complete documentation is available at https://gohugo.io/.`
cmd.PersistentFlags().BoolVarP(&r.verbose, "verbose", "v", false, "verbose output")
cmd.PersistentFlags().BoolVarP(&r.debug, "debug", "", false, "debug output")
cmd.PersistentFlags().BoolVarP(&r.devMode, "devMode", "", false, "only used for internal testing, flag hidden.")
cmd.PersistentFlags().StringVar(&r.logLevel, "logLevel", "", "log level (debug|info|warn|error)")
_ = cmd.RegisterFlagCompletionFunc("logLevel", cobra.FixedCompletions([]string{"debug", "info", "warn", "error"}, cobra.ShellCompDirectiveNoFileComp))
cmd.Flags().BoolVarP(&r.buildWatch, "watch", "w", false, "watch filesystem for changes and recreate as needed")
cmd.PersistentFlags().MarkHidden("devMode")
// Configure local flags
applyLocalFlagsBuild(cmd, r)
+14 -8
View File
@@ -45,9 +45,10 @@ func newGenCommand() *genCommand {
genmandir string
// Chroma flags.
style string
highlightStyle string
linesStyle string
style string
highlightStyle string
lineNumbersInlineStyle string
lineNumbersTableStyle string
)
newChromaStyles := func() simplecobra.Commander {
@@ -63,8 +64,11 @@ See https://xyproto.github.io/splash/docs/all.html for a preview of the availabl
if highlightStyle != "" {
builder.Add(chroma.LineHighlight, highlightStyle)
}
if linesStyle != "" {
builder.Add(chroma.LineNumbers, linesStyle)
if lineNumbersInlineStyle != "" {
builder.Add(chroma.LineNumbers, lineNumbersInlineStyle)
}
if lineNumbersTableStyle != "" {
builder.Add(chroma.LineNumbersTable, lineNumbersTableStyle)
}
style, err := builder.Build()
if err != nil {
@@ -78,10 +82,12 @@ See https://xyproto.github.io/splash/docs/all.html for a preview of the availabl
cmd.ValidArgsFunction = cobra.NoFileCompletions
cmd.PersistentFlags().StringVar(&style, "style", "friendly", "highlighter style (see https://xyproto.github.io/splash/docs/)")
_ = cmd.RegisterFlagCompletionFunc("style", cobra.NoFileCompletions)
cmd.PersistentFlags().StringVar(&highlightStyle, "highlightStyle", "", "style used for highlighting lines (see https://github.com/alecthomas/chroma)")
cmd.PersistentFlags().StringVar(&highlightStyle, "highlightStyle", "", `foreground and background colors for highlighted lines, e.g. --highlightStyle "#fff000 bg:#000fff"`)
_ = cmd.RegisterFlagCompletionFunc("highlightStyle", cobra.NoFileCompletions)
cmd.PersistentFlags().StringVar(&linesStyle, "linesStyle", "", "style used for line numbers (see https://github.com/alecthomas/chroma)")
_ = cmd.RegisterFlagCompletionFunc("linesStyle", cobra.NoFileCompletions)
cmd.PersistentFlags().StringVar(&lineNumbersInlineStyle, "lineNumbersInlineStyle", "", `foreground and background colors for inline line numbers, e.g. --lineNumbersInlineStyle "#fff000 bg:#000fff"`)
_ = cmd.RegisterFlagCompletionFunc("lineNumbersInlineStyle", cobra.NoFileCompletions)
cmd.PersistentFlags().StringVar(&lineNumbersTableStyle, "lineNumbersTableStyle", "", `foreground and background colors for table line numbers, e.g. --lineNumbersTableStyle "#fff000 bg:#000fff"`)
_ = cmd.RegisterFlagCompletionFunc("lineNumbersTableStyle", cobra.NoFileCompletions)
},
}
}
+3 -3
View File
@@ -17,7 +17,7 @@ package hugo
// This should be the only one.
var CurrentVersion = Version{
Major: 0,
Minor: 126,
PatchLevel: 0,
Suffix: "-DEV",
Minor: 125,
PatchLevel: 2,
Suffix: "",
}
@@ -20,10 +20,11 @@ hugo gen chromastyles [flags] [args]
### Options
```
-h, --help help for chromastyles
--highlightStyle string style used for highlighting lines (see https://github.com/alecthomas/chroma)
--linesStyle string style used for line numbers (see https://github.com/alecthomas/chroma)
--style string highlighter style (see https://xyproto.github.io/splash/docs/) (default "friendly")
-h, --help help for chromastyles
--highlightStyle string foreground and background colors for highlighted lines, e.g. --highlightStyle "#fff000 bg:#000fff"
--lineNumbersInlineStyle string foreground and background colors for inline line numbers, e.g. --lineNumbersInlineStyle "#fff000 bg:#000fff"
--lineNumbersTableStyle string foreground and background colors for table line numbers, e.g. --lineNumbersTableStyle "#fff000 bg:#000fff"
--style string highlighter style (see https://xyproto.github.io/splash/docs/) (default "friendly")
```
### Options inherited from parent commands
+6
View File
@@ -16,6 +16,7 @@ package hqt
import (
"errors"
"fmt"
"math"
"reflect"
"strings"
@@ -38,6 +39,11 @@ var IsSameType qt.Checker = &typeChecker{
argNames: []string{"got", "want"},
}
// IsSameFloat64 asserts that two float64 values are equal within a small delta.
var IsSameFloat64 = qt.CmpEquals(cmp.Comparer(func(a, b float64) bool {
return math.Abs(a-b) < 0.0001
}))
type argNames []string
func (a argNames) ArgNames() []string {
+1 -1
View File
@@ -1084,7 +1084,7 @@ func (h *HugoSites) resolveAndClearStateForIdentities(
return b
}
h.MemCache.ClearMatching(shouldDelete)
h.MemCache.ClearMatching(nil, shouldDelete)
return ll, nil
}); err != nil {
+50
View File
@@ -14,6 +14,7 @@
package hugolib
import (
"fmt"
"strings"
"testing"
)
@@ -241,3 +242,52 @@ iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAA
"p1|<p><a href=\"p2\">P2</a>", "<img src=\"pixel.png\" alt=\"Pixel\">")
})
}
func TestRenderHooksDefaultEscape(t *testing.T) {
files := `
-- hugo.toml --
[markup.goldmark.renderHooks]
[markup.goldmark.renderHooks.image]
enableDefault = ENABLE
[markup.goldmark.renderHooks.link]
enableDefault = ENABLE
[markup.goldmark.parser]
wrapStandAloneImageWithinParagraph = false
[markup.goldmark.parser.attribute]
block = true
title = true
-- content/_index.md --
---
title: "Home"
---
Link: [text-"<>&](/destination-"<> 'title-"<>&')
Image: ![alt-"<>&](/destination-"<> 'title-"<>&')
{class="><script>alert()</script>" id="baz"}
-- layouts/index.html --
{{ .Content }}
`
for _, enabled := range []bool{true, false} {
enabled := enabled
t.Run(fmt.Sprint(enabled), func(t *testing.T) {
t.Parallel()
b := Test(t, strings.ReplaceAll(files, "ENABLE", fmt.Sprint(enabled)))
// The escaping is slightly different between the two.
if enabled {
b.AssertFileContent("public/index.html",
"Link: <a href=\"/destination-%22%3C%3E\" title=\"title-&#34;&lt;&gt;&amp;\">text-&quot;&lt;&gt;&amp;</a>",
"img alt=\"alt-&quot;&lt;&gt;&amp;\" src=\"/destination-%22%3C%3E\" title=\"title-&#34;&lt;&gt;&amp;\">",
"&gt;&lt;script&gt;",
)
} else {
b.AssertFileContent("public/index.html",
"Link: <a href=\"/destination-%22%3C%3E\" title=\"title-&quot;&lt;&gt;&amp;\">text-&quot;&lt;&gt;&amp;</a>",
"Image: <img src=\"/destination-%22%3C%3E\" alt=\"alt-&quot;&lt;&gt;&amp;\" title=\"title-&quot;&lt;&gt;&amp;\">",
)
}
})
}
}
+39 -7
View File
@@ -23,6 +23,7 @@ import (
"path"
"path/filepath"
"strings"
"sync"
"time"
"github.com/bep/logg"
@@ -46,6 +47,7 @@ import (
"github.com/gohugoio/hugo/resources/page"
"github.com/gohugoio/hugo/resources/page/siteidentities"
"github.com/gohugoio/hugo/resources/postpub"
"github.com/gohugoio/hugo/resources/resource"
"github.com/spf13/afero"
@@ -758,15 +760,45 @@ func (h *HugoSites) processPartial(ctx context.Context, l logg.LevelLogger, conf
}
}
case files.ComponentFolderAssets:
logger.Println("Asset changed", pathInfo.Path())
p := pathInfo.Path()
logger.Println("Asset changed", p)
var matches []any
var mu sync.Mutex
h.MemCache.ClearMatching(
func(k string, pm dynacache.PartitionManager) bool {
// Avoid going through everything.
return strings.HasPrefix(k, "/res")
},
func(k, v any) bool {
if strings.Contains(k.(string), p) {
mu.Lock()
defer mu.Unlock()
switch vv := v.(type) {
case resource.Resources:
// GetMatch/Match.
for _, r := range vv {
matches = append(matches, r)
}
return true
default:
matches = append(matches, vv)
return true
}
}
return false
})
var hasID bool
r, _ := h.ResourceSpec.ResourceCache.Get(context.Background(), dynacache.CleanKey(pathInfo.Base()))
identity.WalkIdentitiesShallow(r, func(level int, rid identity.Identity) bool {
hasID = true
changes = append(changes, rid)
return false
})
for _, r := range matches {
identity.WalkIdentitiesShallow(r, func(level int, rid identity.Identity) bool {
hasID = true
changes = append(changes, rid)
return false
})
}
if !hasID {
changes = append(changes, pathInfo)
}
+34
View File
@@ -676,3 +676,37 @@ menu: main
b.AssertFileContent("public/fr/index.html", `<a href="/fr/p1/">p1</a>`)
b.AssertLogNotContains("WARN")
}
func TestSectionPagesIssue12399(t *testing.T) {
t.Parallel()
files := `
-- hugo.toml --
disableKinds = ['rss','sitemap','taxonomy','term']
capitalizeListTitles = false
pluralizeListTitles = false
sectionPagesMenu = 'main'
-- content/p1.md --
---
title: p1
---
-- content/s1/p2.md --
---
title: p2
menus: main
---
-- content/s1/p3.md --
---
title: p3
---
-- layouts/_default/list.html --
{{ range site.Menus.main }}<a href="{{ .URL }}">{{ .Name }}</a>{{ end }}
-- layouts/_default/single.html --
{{ .Title }}
`
b := Test(t, files)
b.AssertFileExists("public/index.html", true)
b.AssertFileContent("public/index.html", `<a href="/s1/p2/">p2</a><a href="/s1/">s1</a>`)
}
+1 -1
View File
@@ -175,7 +175,7 @@ func (pco *pageContentOutput) RenderShortcodes(ctx context.Context) (template.HT
// This content will be parsed and rendered by Goldmark.
// Wrap it in a special Hugo markup to assign the correct Page from
// the stack.
c = hugocontext.Wrap(c, pco.po.p.pid)
return template.HTML(hugocontext.Wrap(c, pco.po.p.pid)), nil
}
return helpers.BytesToHTML(c), nil
+1 -1
View File
@@ -659,7 +659,7 @@ func (s *Site) assembleMenus() error {
if sectionPagesMenu != "" {
if err := s.pageMap.forEachPage(pagePredicates.ShouldListGlobal, func(p *pageState) (bool, error) {
if p.IsHome() || !p.m.shouldBeCheckedForMenuDefinitions() {
if p.Kind() != kinds.KindSection || !p.m.shouldBeCheckedForMenuDefinitions() {
return false, nil
}
+2 -2
View File
@@ -34,7 +34,7 @@ func New() goldmark.Extender {
// Wrap wraps the given byte slice in a Hugo context that used to determine the correct Page
// in .RenderShortcodes.
func Wrap(b []byte, pid uint64) []byte {
func Wrap(b []byte, pid uint64) string {
buf := bufferpool.GetBuffer()
defer bufferpool.PutBuffer(buf)
buf.Write(prefix)
@@ -45,7 +45,7 @@ func Wrap(b []byte, pid uint64) []byte {
buf.Write(b)
buf.Write(prefix)
buf.Write(closingDelimAndNewline)
return buf.Bytes()
return buf.String()
}
var kindHugoContext = ast.NewNodeKind("HugoContext")
@@ -24,7 +24,7 @@ func TestWrap(t *testing.T) {
b := []byte("test")
c.Assert(string(Wrap(b, 42)), qt.Equals, "{{__hugo_ctx pid=42}}\ntest{{__hugo_ctx/}}\n")
c.Assert(Wrap(b, 42), qt.Equals, "{{__hugo_ctx pid=42}}\ntest{{__hugo_ctx/}}\n")
}
func BenchmarkWrap(b *testing.B) {
+4 -1
View File
@@ -261,7 +261,10 @@ func (c *collector) add(owner *moduleAdapter, moduleImport Import) (*moduleAdapt
// This will select the latest release-version (not beta etc.).
versionQuery = "upgrade"
}
if err := c.Get(fmt.Sprintf("%s@%s", modulePath, versionQuery)); err != nil {
// Note that we cannot use c.Get for this, as that may
// trigger a new module collection and potentially create a infinite loop.
if err := c.get(fmt.Sprintf("%s@%s", modulePath, versionQuery)); err != nil {
return nil, err
}
if err := c.loadModules(); err != nil {
+5 -4
View File
@@ -18,6 +18,7 @@ import (
"testing"
qt "github.com/frankban/quicktest"
"github.com/gohugoio/hugo/htesting/hqt"
)
func TestHexStringToColor(t *testing.T) {
@@ -119,8 +120,8 @@ func TestReplaceColorInPalette(t *testing.T) {
func TestColorLuminance(t *testing.T) {
c := qt.New(t)
c.Assert(hexStringToColor("#000000").Luminance(), qt.Equals, 0.0)
c.Assert(hexStringToColor("#768a9a").Luminance(), qt.Equals, 0.24361603589088263)
c.Assert(hexStringToColor("#d5bc9f").Luminance(), qt.Equals, 0.5261577672685374)
c.Assert(hexStringToColor("#ffffff").Luminance(), qt.Equals, 1.0)
c.Assert(hexStringToColor("#000000").Luminance(), hqt.IsSameFloat64, 0.0)
c.Assert(hexStringToColor("#768a9a").Luminance(), hqt.IsSameFloat64, 0.24361603589088263)
c.Assert(hexStringToColor("#d5bc9f").Luminance(), hqt.IsSameFloat64, 0.5261577672685374)
c.Assert(hexStringToColor("#ffffff").Luminance(), hqt.IsSameFloat64, 1.0)
}
@@ -327,3 +327,34 @@ Styles: {{ $r.RelPermalink }}
b.AssertFileContent("public/index.html", "Styles: /scss/main.css")
}
func TestRebuildAssetGetMatch(t *testing.T) {
t.Parallel()
if !scss.Supports() {
t.Skip()
}
files := `
-- assets/scss/main.scss --
b {
color: red;
}
-- layouts/index.html --
{{ $r := resources.GetMatch "scss/main.scss" | toCSS }}
T1: {{ $r.Content }}
`
b := hugolib.NewIntegrationTestBuilder(
hugolib.IntegrationTestConfig{
T: t,
TxtarString: files,
NeedsOsFS: true,
Running: true,
}).Build()
b.AssertFileContent("public/index.html", `color: red`)
b.EditFiles("assets/scss/main.scss", `b { color: blue; }`).Build()
b.AssertFileContent("public/index.html", `color: blue`)
}
@@ -5,7 +5,7 @@
{{- $src = .RelPermalink -}}
{{- end -}}
{{- end -}}
{{- $attributes := merge .Attributes (dict "alt" .Text "src" $src "title" .Title) -}}
{{- $attributes := merge .Attributes (dict "alt" .Text "src" $src "title" (.Title | transform.HTMLEscape)) -}}
<img
{{- range $k, $v := $attributes -}}
{{- if $v -}}
@@ -17,7 +17,7 @@
{{- end -}}
{{- end -}}
{{- end -}}
{{- $attributes := dict "href" $href "title" .Title -}}
{{- $attributes := dict "href" $href "title" (.Title | transform.HTMLEscape) -}}
<a
{{- range $k, $v := $attributes -}}
{{- if $v -}}
@@ -48,7 +48,7 @@
<title>{{ if eq .Title .Site.Title }}{{ .Site.Title }}{{ else }}{{ with .Title }}{{ . }} on {{ end }}{{ .Site.Title }}{{ end }}</title>
<link>{{ .Permalink }}</link>
<description>Recent content {{ if ne .Title .Site.Title }}{{ with .Title }}in {{ . }} {{ end }}{{ end }}on {{ .Site.Title }}</description>
<generator>Hugo {{ hugo.Version }}</generator>
<generator>Hugo</generator>
<language>{{ site.Language.LanguageCode }}</language>{{ with $authorEmail }}
<managingEditor>{{.}}{{ with $authorName }} ({{ . }}){{ end }}</managingEditor>{{ end }}{{ with $authorEmail }}
<webMaster>{{ . }}{{ with $authorName }} ({{ . }}){{ end }}</webMaster>{{ end }}{{ with .Site.Copyright }}
@@ -8,10 +8,10 @@ Renders an embedded YouTube video.
@param {int} [end] The time, measured in seconds from the start of the video, when the player should stop playing the video.
@param {string} [id] The video id. Optional if the id is provided as first positional argument.
@param {string} [loading=eager] The loading attribute of the iframe element.
@param {bool} [loop=false] Whether to indefinitely repeat the video.
@param {bool} [loop=false] Whether to indefinitely repeat the video. Ignores the start and end arguments after the first play.
@param {bool} [mute=false] Whether to mute the video. Always true when autoplay is true.
@param {int} [start] The time, measured in seconds from the start of the video, when the player should start playing the video.
@param {string} [title] The title attribute of the iframe element. Defaults to the title returned by YouTube oEmbed API.
@param {string} [title] The title attribute of the iframe element. Defaults to "YouTube video".
@returns {template.HTML}
@@ -26,20 +26,6 @@ Renders an embedded YouTube video.
{{- if not $pc.Disable }}
{{- with $id := or (.Get "id") (.Get 0) }}
{{- /* Get data from the YouTube oEmbed API. */}}
{{- $q := querify "url" (printf "https://www.youtube.com/watch?v=%s" $id) "format" "json" }}
{{- $url := printf "https://www.youtube.com/oembed?%s" $q }}
{{- $data := dict }}
{{- with resources.GetRemote $url }}
{{- with .Err }}
{{- erroridf $remoteErrID "The %q shortcode was unable to get remote resource %q. %s. See %s" $.Name $url . $.Position }}
{{- else }}
{{- $data = .Content | transform.Unmarshal }}
{{- end }}
{{- else }}
{{- erroridf $remoteErrID "The %q shortcode was unable to get remote resource %q. See %s" $.Name $url $.Position }}
{{- end }}
{{/* Set defaults. */}}
{{- $allowFullScreen := "allowfullscreen" }}
{{- $autoplay := 0 }}
@@ -50,7 +36,7 @@ Renders an embedded YouTube video.
{{- $loop := 0 }}
{{- $mute := 0 }}
{{- $start := 0 }}
{{- $title := $data.title }}
{{- $title := "YouTube video" }}
{{- /* Get arguments. */}}
{{- if in (slice "false" false 0) ($.Get "allowFullScreen") }}