Skip to content

Commit

Permalink
Make figure SC insert absolute links in the src attribute
Browse files Browse the repository at this point in the history
- Fixes #4562
  - So now the figure shortcode inserted images work fine on list pages and on
    sites with baseURL containing subdir too.
- Support figure SC src attribute with protocol or two leading slashes
- Update the figure shortcode + src attr tests to use BaseURL
- Add tests for all of the above.

Other:

- White-space change syncup between figure SC and tests
- Consistency edits: {{.}} -> {{ . }}, {{else}} -> {{ else }}, and similar
  • Loading branch information
kaushalmodi committed May 30, 2018
1 parent ceaff7c commit 384b350
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 48 deletions.
8 changes: 4 additions & 4 deletions hugolib/embedded_shortcodes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,22 +123,22 @@ func TestShortcodeFigure(t *testing.T) {
}{
{
`{{< figure src="/img/hugo-logo.png" >}}`,
"(?s)\n<figure>.*?<img src=\"/img/hugo-logo.png\" />.*?</figure>\n",
"(?s)\n<figure>.*?<img src=\"/img/hugo-logo.png\"/>.*?</figure>\n",
},
{
// set alt
`{{< figure src="/img/hugo-logo.png" alt="Hugo logo" >}}`,
"(?s)\n<figure>.*?<img src=\"/img/hugo-logo.png\" alt=\"Hugo logo\" />.*?</figure>\n",
"(?s)\n<figure>.*?<img src=\"/img/hugo-logo.png\" alt=\"Hugo logo\"/>.*?</figure>\n",
},
// set title
{
`{{< figure src="/img/hugo-logo.png" title="Hugo logo" >}}`,
"(?s)\n<figure>.*?<img src=\"/img/hugo-logo.png\" />.*?<figcaption>.*?<h4>Hugo logo</h4>.*?</figcaption>.*?</figure>\n",
"(?s)\n<figure>.*?<img src=\"/img/hugo-logo.png\"/>.*?<figcaption>.*?<h4>Hugo logo</h4>.*?</figcaption>.*?</figure>\n",
},
// set attr and attrlink
{
`{{< figure src="/img/hugo-logo.png" attr="Hugo logo" attrlink="/img/hugo-logo.png" >}}`,
"(?s)\n<figure>.*?<img src=\"/img/hugo-logo.png\" />.*?<figcaption>.*?<p>.*?<a href=\"/img/hugo-logo.png\">.*?Hugo logo.*?</a>.*?</p>.*?</figcaption>.*?</figure>\n",
"(?s)\n<figure>.*?<img src=\"/img/hugo-logo.png\"/>.*?<figcaption>.*?<p>.*?<a href=\"/img/hugo-logo.png\">.*?Hugo logo.*?</a>.*?</p>.*?</figcaption>.*?</figure>\n",
},
} {

Expand Down
2 changes: 1 addition & 1 deletion hugolib/page_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -794,7 +794,7 @@ func TestPageWithShortCodeInSummary(t *testing.T) {
assertFunc := func(t *testing.T, ext string, pages Pages) {
p := pages[0]
checkPageTitle(t, p, "Simple")
checkPageContent(t, p, normalizeExpected(ext, "<p>Summary Next Line. \n<figure>\n \n <img src=\"/not/real\" />\n \n \n</figure>\n.\nMore text here.</p>\n\n<p>Some more text</p>\n"))
checkPageContent(t, p, normalizeExpected(ext, "<p>Summary Next Line. \n<figure>\n \n <img src=\"/not/real\"/>\n \n \n</figure>\n.\nMore text here.</p>\n\n<p>Some more text</p>\n"))
checkPageSummary(t, p, "Summary Next Line. . More text here. Some more text")
checkPageType(t, p, "page")
}
Expand Down
72 changes: 59 additions & 13 deletions hugolib/shortcode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (

"github.com/gohugoio/hugo/deps"
"github.com/gohugoio/hugo/helpers"
"github.com/gohugoio/hugo/hugofs"
"github.com/gohugoio/hugo/tpl"
"github.com/stretchr/testify/require"
)
Expand All @@ -56,13 +57,18 @@ func pageFromString(in, filename string, withTemplate ...func(templ tpl.Template
return s.NewPageFrom(strings.NewReader(in), filename)
}

func CheckShortCodeMatch(t *testing.T, input, expected string, withTemplate func(templ tpl.TemplateHandler) error) {
CheckShortCodeMatchAndError(t, input, expected, withTemplate, false)
func CheckShortCodeMatchWithBaseURL(t *testing.T, baseURL string, input, expected string, withTemplate func(templ tpl.TemplateHandler) error) {
cfg, fs := newTestCfg()
cfg.Set("baseURL", baseURL)
CheckShortCodeMatchAndError(t, input, expected, cfg, fs, withTemplate, false)
}

func CheckShortCodeMatchAndError(t *testing.T, input, expected string, withTemplate func(templ tpl.TemplateHandler) error, expectError bool) {

func CheckShortCodeMatch(t *testing.T, input, expected string, withTemplate func(templ tpl.TemplateHandler) error) {
cfg, fs := newTestCfg()
CheckShortCodeMatchAndError(t, input, expected, cfg, fs, withTemplate, false)
}

func CheckShortCodeMatchAndError(t *testing.T, input, expected string, cfg *viper.Viper, fs *hugofs.Fs, withTemplate func(templ tpl.TemplateHandler) error, expectError bool) {

// Need some front matter, see https://github.com/gohugoio/hugo/issues/2337
contentFile := `---
Expand Down Expand Up @@ -246,8 +252,8 @@ This is **plain** text.

func TestEmbeddedSC(t *testing.T) {
t.Parallel()
CheckShortCodeMatch(t, `{{% figure src="/found/here" class="bananas orange" %}}`, "\n<figure class=\"bananas orange\">\n \n <img src=\"/found/here\" />\n \n \n</figure>\n", nil)
CheckShortCodeMatch(t, `{{% figure src="/found/here" class="bananas orange" caption="This is a caption" %}}`, "\n<figure class=\"bananas orange\">\n \n <img src=\"/found/here\" alt=\"This is a caption\" />\n \n \n <figcaption>\n <p>\n This is a caption\n \n \n \n </p> \n </figcaption>\n \n</figure>\n", nil)
CheckShortCodeMatch(t, `{{% figure src="/found/here" class="bananas orange" %}}`, "\n<figure class=\"bananas orange\">\n \n <img src=\"/found/here\"/> </figure>\n", nil)
CheckShortCodeMatch(t, `{{% figure src="/found/here" class="bananas orange" caption="This is a caption" %}}`, "\n<figure class=\"bananas orange\">\n \n <img src=\"/found/here\" alt=\"This is a caption\"/> <figcaption>\n \n <p>\n This is a caption\n \n \n </p>\n \n </figcaption></figure>\n", nil)
}

func TestNestedSC(t *testing.T) {
Expand Down Expand Up @@ -293,37 +299,77 @@ func TestParentShortcode(t *testing.T) {

func TestFigureOnlySrc(t *testing.T) {
t.Parallel()
CheckShortCodeMatch(t, `{{< figure src="/found/here" >}}`, "\n<figure>\n \n <img src=\"/found/here\" />\n \n \n</figure>\n", nil)
CheckShortCodeMatch(t, `{{< figure src="/found/here" >}}`, "\n<figure>\n \n <img src=\"/found/here\"/> </figure>\n", nil)
}

func TestFigureImgWidth(t *testing.T) {
t.Parallel()
CheckShortCodeMatch(t, `{{% figure src="/found/here" class="bananas orange" alt="apple" width="100px" %}}`, "\n<figure class=\"bananas orange\">\n \n <img src=\"/found/here\" alt=\"apple\" width=\"100px\" />\n \n \n</figure>\n", nil)
CheckShortCodeMatch(t, `{{% figure src="/found/here" class="bananas orange" alt="apple" width="100px" %}}`, "\n<figure class=\"bananas orange\">\n \n <img src=\"/found/here\" alt=\"apple\" width=\"100px\"/> </figure>\n", nil)
}

func TestFigureImgHeight(t *testing.T) {
t.Parallel()
CheckShortCodeMatch(t, `{{% figure src="/found/here" class="bananas orange" alt="apple" height="100px" %}}`, "\n<figure class=\"bananas orange\">\n \n <img src=\"/found/here\" alt=\"apple\" height=\"100px\" />\n \n \n</figure>\n", nil)
CheckShortCodeMatch(t, `{{% figure src="/found/here" class="bananas orange" alt="apple" height="100px" %}}`, "\n<figure class=\"bananas orange\">\n \n <img src=\"/found/here\" alt=\"apple\" height=\"100px\"/> </figure>\n", nil)
}

func TestFigureImgWidthAndHeight(t *testing.T) {
t.Parallel()
CheckShortCodeMatch(t, `{{% figure src="/found/here" class="bananas orange" alt="apple" width="50" height="100" %}}`, "\n<figure class=\"bananas orange\">\n \n <img src=\"/found/here\" alt=\"apple\" width=\"50\" height=\"100\" />\n \n \n</figure>\n", nil)
CheckShortCodeMatch(t, `{{% figure src="/found/here" class="bananas orange" alt="apple" width="50" height="100" %}}`, "\n<figure class=\"bananas orange\">\n \n <img src=\"/found/here\" alt=\"apple\" width=\"50\" height=\"100\"/> </figure>\n", nil)
}

func TestFigureLinkNoTarget(t *testing.T) {
t.Parallel()
CheckShortCodeMatch(t, `{{< figure src="/found/here" link="/jump/here/on/clicking" >}}`, "\n<figure>\n <a href=\"/jump/here/on/clicking\">\n <img src=\"/found/here\" />\n </a>\n \n</figure>\n", nil)
CheckShortCodeMatch(t, `{{< figure src="/found/here" link="/jump/here/on/clicking" >}}`, "\n<figure>\n <a href=\"/jump/here/on/clicking\">\n <img src=\"/found/here\"/> </a></figure>\n", nil)
}

func TestFigureLinkWithTarget(t *testing.T) {
t.Parallel()
CheckShortCodeMatch(t, `{{< figure src="/found/here" link="/jump/here/on/clicking" target="_self" >}}`, "\n<figure>\n <a href=\"/jump/here/on/clicking\" target=\"_self\">\n <img src=\"/found/here\" />\n </a>\n \n</figure>\n", nil)
CheckShortCodeMatch(t, `{{< figure src="/found/here" link="/jump/here/on/clicking" target="_self" >}}`, "\n<figure>\n <a href=\"/jump/here/on/clicking\" target=\"_self\">\n <img src=\"/found/here\"/> </a></figure>\n", nil)
}

func TestFigureLinkWithTargetAndRel(t *testing.T) {
t.Parallel()
CheckShortCodeMatch(t, `{{< figure src="/found/here" link="/jump/here/on/clicking" target="_blank" rel="noopener" >}}`, "\n<figure>\n <a href=\"/jump/here/on/clicking\" target=\"_blank\" rel=\"noopener\">\n <img src=\"/found/here\" />\n </a>\n \n</figure>\n", nil)
CheckShortCodeMatch(t, `{{< figure src="/found/here" link="/jump/here/on/clicking" target="_blank" rel="noopener" >}}`, "\n<figure>\n <a href=\"/jump/here/on/clicking\" target=\"_blank\" rel=\"noopener\">\n <img src=\"/found/here\"/> </a></figure>\n", nil)
}

func TestFigureWithRelativeSrcBaseURLNoSubdir(t *testing.T) {
t.Parallel()
CheckShortCodeMatchWithBaseURL(t, "https://example.com/", `{{< figure src="image.png" >}}`, "\n<figure>\n \n <img src=\"https://example.com/simple/image.png\"/> </figure>\n", nil)
}

func TestFigureWithRelativeSrcBaseURLWithSubdir(t *testing.T) {
t.Parallel()
CheckShortCodeMatchWithBaseURL(t, "https://example.com/subdir/", `{{< figure src="image.png" >}}`, "\n<figure>\n \n <img src=\"https://example.com/subdir/simple/image.png\"/> </figure>\n", nil)
}

func TestFigureWithAbsoluteSrc1BaseURLNoSubdir(t *testing.T) {
t.Parallel()
CheckShortCodeMatchWithBaseURL(t, "https://example.com/", `{{< figure src="/image.png" >}}`, "\n<figure>\n \n <img src=\"https://example.com/image.png\"/> </figure>\n", nil)
}

func TestFigureWithAbsoluteSrc1BaseURLWithSubdir(t *testing.T) {
t.Parallel()
CheckShortCodeMatchWithBaseURL(t, "https://example.com/subdir/", `{{< figure src="/image.png" >}}`, "\n<figure>\n \n <img src=\"https://example.com/subdir/image.png\"/> </figure>\n", nil)
}

func TestFigureWithAbsoluteSrc2BaseURLNoSubdir(t *testing.T) {
t.Parallel()
CheckShortCodeMatchWithBaseURL(t, "https://example.com/", `{{< figure src="//example.com/image.png" >}}`, "\n<figure>\n \n \n <img src=\"//example.com/image.png\"/> </figure>\n", nil)
}

func TestFigureWithAbsoluteSrc2BaseURLWithSubdir(t *testing.T) {
t.Parallel()
CheckShortCodeMatchWithBaseURL(t, "https://example.com/subdir/", `{{< figure src="//example.com/image.png" >}}`, "\n<figure>\n \n \n <img src=\"//example.com/image.png\"/> </figure>\n", nil)
}

func TestFigureWithAbsoluteSrc3BaseURLNoSubdir(t *testing.T) {
t.Parallel()
CheckShortCodeMatchWithBaseURL(t, "https://example.com/", `{{< figure src="https://foo.bar/image.png" >}}`, "\n<figure>\n \n \n <img src=\"https://foo.bar/image.png\"/> </figure>\n", nil)
}

func TestFigureWithAbsoluteSrc3BaseURLWithSubdir(t *testing.T) {
t.Parallel()
CheckShortCodeMatchWithBaseURL(t, "http://example.com/subdir/", `{{< figure src="http://foo.bar/image.png" >}}`, "\n<figure>\n \n \n <img src=\"http://foo.bar/image.png\"/> </figure>\n", nil)
}

const testScPlaceholderRegexp = "HAHAHUGOSHORTCODE-\\d+HBHB"
Expand Down
49 changes: 34 additions & 15 deletions tpl/tplimpl/embedded/templates.autogen.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,23 +305,42 @@ if (!doNotTrack) {
{{- end -}}
`},
{`shortcodes/figure.html`, `<!-- image -->
<figure{{ with .Get "class" }} class="{{.}}"{{ end }}>
{{ $image := .Get "src" }}
<figure{{ with .Get "class" }} class="{{ . }}"{{ end }}>
{{ if .Get "link"}}<a href="{{ .Get "link" }}"{{ with .Get "target" }} target="{{ . }}"{{ end }}{{ with .Get "rel" }} rel="{{ . }}"{{ end }}>{{ end }}
<img src="{{ .Get "src" }}" {{ if or (.Get "alt") (.Get "caption") }}alt="{{ with .Get "alt"}}{{.}}{{else}}{{ .Get "caption" }}{{ end }}" {{ end }}{{ with .Get "width" }}width="{{.}}" {{ end }}{{ with .Get "height" }}height="{{.}}" {{ end }}/>
{{ if .Get "link"}}</a>{{ end }}
{{ if or (or (.Get "title") (.Get "caption")) (.Get "attr")}}
<figcaption>{{ if isset .Params "title" }}
<h4>{{ .Get "title" }}</h4>{{ end }}
{{ if or (.Get "caption") (.Get "attr")}}<p>
{{ .Get "caption" }}
{{ with .Get "attrlink"}}<a href="{{.}}"> {{ end }}
{{ .Get "attr" }}
{{ if .Get "attrlink"}}</a> {{ end }}
</p> {{ end }}
</figcaption>
{{ end }}
{{ if (findRE "(^|:)//" $image) -}} <!-- If image link is a URL with protocol or two leading slashes, use just that unmodified. -->
<img src="{{ $image }}"
{{- else if (findRE "^/" $image) -}} <!-- If image link has one leading slash -->
{{- /* Cannot use absURL below because it doesn't work as expected if baseURL has a subdir. */ -}}
{{- $baseurl_no_trailing_slash := $.Site.BaseURL | replaceRE "/$" "" -}}
<img src="{{ (printf "%s%s" $baseurl_no_trailing_slash $image) }}"
{{- else -}}
{{- /* Below variable will always have a trailing slash, even with uglyURLs enabled. */ -}}
{{- $permalink_pretty := $.Page.Permalink | replaceRE "\\.html$" "/" -}}
<img src="{{ (printf "%s%s" $permalink_pretty $image) }}"
{{- end -}}
{{- with (or (.Get "alt") (.Get "caption")) -}}
{{- printf " alt=\"%s\"" . | safeHTMLAttr -}}
{{- end -}}
{{- with .Get "width" }} width="{{ . }}"{{ end -}}
{{- with .Get "height" }} height="{{ . }}"{{ end -}}/> <!-- Closing img tag -->
{{- if .Get "link" }}</a>{{ end -}}
{{- if or (or (.Get "title") (.Get "caption")) (.Get "attr") -}}
<figcaption>
{{ if isset .Params "title" }}
<h4>{{ .Get "title" }}</h4>
{{ end }}
{{ if or (.Get "caption") (.Get "attr") }}<p>
{{ .Get "caption" }}
{{ with .Get "attrlink" }}<a href="{{ . }}"> {{ end }}
{{ .Get "attr" }}
{{ if .Get "attrlink" }}</a>{{ end }}</p>
{{ end }}
</figcaption>
{{- end -}}
</figure>
<!-- image -->`},
<!-- image -->
`},
{`shortcodes/gist.html`, `<script src="//gist.github.com/{{ index .Params 0 }}/{{ index .Params 1 }}.js{{if len .Params | eq 3 }}?file={{ index .Params 2 }}{{end}}"></script>`},
{`shortcodes/highlight.html`, `{{ if len .Params | eq 2 }}{{ highlight (trim .Inner "\n\r") (.Get 0) (.Get 1) }}{{ else }}{{ highlight (trim .Inner "\n\r") (.Get 0) "" }}{{ end }}`},
{`shortcodes/instagram.html`, `{{- $pc := .Page.Site.Config.Privacy.Instagram -}}
Expand Down
48 changes: 33 additions & 15 deletions tpl/tplimpl/embedded/templates/shortcodes/figure.html
Original file line number Diff line number Diff line change
@@ -1,18 +1,36 @@
<!-- image -->
<figure{{ with .Get "class" }} class="{{.}}"{{ end }}>
{{ $image := .Get "src" }}
<figure{{ with .Get "class" }} class="{{ . }}"{{ end }}>
{{ if .Get "link"}}<a href="{{ .Get "link" }}"{{ with .Get "target" }} target="{{ . }}"{{ end }}{{ with .Get "rel" }} rel="{{ . }}"{{ end }}>{{ end }}
<img src="{{ .Get "src" }}" {{ if or (.Get "alt") (.Get "caption") }}alt="{{ with .Get "alt"}}{{.}}{{else}}{{ .Get "caption" }}{{ end }}" {{ end }}{{ with .Get "width" }}width="{{.}}" {{ end }}{{ with .Get "height" }}height="{{.}}" {{ end }}/>
{{ if .Get "link"}}</a>{{ end }}
{{ if or (or (.Get "title") (.Get "caption")) (.Get "attr")}}
<figcaption>{{ if isset .Params "title" }}
<h4>{{ .Get "title" }}</h4>{{ end }}
{{ if or (.Get "caption") (.Get "attr")}}<p>
{{ .Get "caption" }}
{{ with .Get "attrlink"}}<a href="{{.}}"> {{ end }}
{{ .Get "attr" }}
{{ if .Get "attrlink"}}</a> {{ end }}
</p> {{ end }}
</figcaption>
{{ end }}
{{ if (findRE "(^|:)//" $image) -}} <!-- If image link is a URL with protocol or two leading slashes, use just that unmodified. -->
<img src="{{ $image }}"
{{- else if (findRE "^/" $image) -}} <!-- If image link has one leading slash -->
{{- /* Cannot use absURL below because it doesn't work as expected if baseURL has a subdir. */ -}}
{{- $baseurl_no_trailing_slash := $.Site.BaseURL | replaceRE "/$" "" -}}
<img src="{{ (printf "%s%s" $baseurl_no_trailing_slash $image) }}"
{{- else -}}
{{- /* Below variable will always have a trailing slash, even with uglyURLs enabled. */ -}}
{{- $permalink_pretty := $.Page.Permalink | replaceRE "\\.html$" "/" -}}
<img src="{{ (printf "%s%s" $permalink_pretty $image) }}"
{{- end -}}
{{- with (or (.Get "alt") (.Get "caption")) -}}
{{- printf " alt=\"%s\"" . | safeHTMLAttr -}}
{{- end -}}
{{- with .Get "width" }} width="{{ . }}"{{ end -}}
{{- with .Get "height" }} height="{{ . }}"{{ end -}}/> <!-- Closing img tag -->
{{- if .Get "link" }}</a>{{ end -}}
{{- if or (or (.Get "title") (.Get "caption")) (.Get "attr") -}}
<figcaption>
{{ if isset .Params "title" }}
<h4>{{ .Get "title" }}</h4>
{{ end }}
{{ if or (.Get "caption") (.Get "attr") }}<p>
{{ .Get "caption" }}
{{ with .Get "attrlink" }}<a href="{{ . }}"> {{ end }}
{{ .Get "attr" }}
{{ if .Get "attrlink" }}</a>{{ end }}</p>
{{ end }}
</figcaption>
{{- end -}}
</figure>
<!-- image -->
<!-- image -->

0 comments on commit 384b350

Please sign in to comment.