hugo

Unnamed repository; edit this file 'description' to name the repository.

git clone git://git.shimmy1996.com/hugo.git
commit 9b5debe4b820132759cfdf7bff7fe9c1ad0a6bb1
parent 12530519d8fb4513c9c18a6494099b7dff8e4fd4
Author: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Date:   Mon,  7 Jun 2021 12:45:00 +0200

Upgrade Instagram shortcode

Fixes #7879

Diffstat:
M.github/workflows/test.yml | 1+
Mconfig/services/servicesConfig.go | 5+++++
Mhugolib/embedded_shortcodes_test.go | 12+++++++++---
Mresources/page/page_generate/generate_page_wrappers.go | 6+++---
Mtpl/tplimpl/embedded/templates.autogen.go | 113+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
Mtpl/tplimpl/embedded/templates/shortcodes/instagram.html | 24++++++++++++++++--------
Mtpl/tplimpl/embedded/templates/shortcodes/instagram_simple.html | 89++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
7 files changed, 158 insertions(+), 92 deletions(-)
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
@@ -75,6 +75,7 @@ jobs:
         HUGO_BUILD_TAGS: extended
         HUGO_TIMEOUT: 31000
         HUGO_IGNOREERRORS: error-remote-getjson
+        HUGO_SERVICES_INSTAGRAM_ACCESSTOKEN: ${{ secrets.HUGO_SERVICES_INSTAGRAM_ACCESSTOKEN }}
       run: |
         mage -v hugo
         ./hugo -s docs/
diff --git a/config/services/servicesConfig.go b/config/services/servicesConfig.go
@@ -53,6 +53,11 @@ type Instagram struct {
 	// This means that if you use Bootstrap 4 or want to provide your own CSS, you want
 	// to disable the inline CSS provided by Hugo.
 	DisableInlineCSS bool
+
+	// App or Client Access Token.
+	// If you are using a Client Access Token, remember that you must combine it with your App ID
+	// using a pipe symbol (<APPID>|<CLIENTTOKEN>) otherwise the request will fail.
+	AccessToken string
 }
 
 // Twitter holds the functional configuration settings related to the Twitter shortcodes.
diff --git a/hugolib/embedded_shortcodes_test.go b/hugolib/embedded_shortcodes_test.go
@@ -372,12 +372,16 @@ func TestShortcodeInstagram(t *testing.T) {
 	} {
 		// overload getJSON to return mock API response from Instagram
 		instagramFuncMap := template.FuncMap{
-			"getJSON": func(urlParts ...string) interface{} {
+			"getJSON": func(args ...interface{}) interface{} {
+				headers := args[len(args)-1].(map[string]interface{})
+				auth := headers["Authorization"]
+				if auth != "Bearer dummytoken" {
+					return fmt.Errorf("invalid access token: %q", auth)
+				}
 				var v interface{}
 				err := json.Unmarshal([]byte(this.resp), &v)
 				if err != nil {
-					t.Fatalf("[%d] unexpected error in json.Unmarshal: %s", i, err)
-					return err
+					return fmt.Errorf("[%d] unexpected error in json.Unmarshal: %s", i, err)
 				}
 				return v
 			},
@@ -388,6 +392,8 @@ func TestShortcodeInstagram(t *testing.T) {
 			th      = newTestHelper(cfg, fs, t)
 		)
 
+		cfg.Set("services.instagram.accessToken", "dummytoken")
+
 		writeSource(t, fs, filepath.Join("content", "simple.md"), fmt.Sprintf(`---
 title: Shorty
 ---
diff --git a/resources/page/page_generate/generate_page_wrappers.go b/resources/page/page_generate/generate_page_wrappers.go
@@ -235,7 +235,7 @@ func generateFileIsZeroWrappers(c *codegen.Inspector) error {
 
 	}
 
-	pkgImports := append(methods.Imports(), "github.com/gohugoio/hugo/helpers", "github.com/gohugoio/hugo/source")
+	pkgImports := append(methods.Imports(), "github.com/gohugoio/hugo/common/loggers", "github.com/gohugoio/hugo/source")
 
 	fmt.Fprintf(f, `%s
 
@@ -245,10 +245,10 @@ package page
 
 // ZeroFile represents a zero value of source.File with warnings if invoked.
 type zeroFile struct {
-	log *helpers.DistinctLogger
+	log loggers.Logger
 }
 
-func NewZeroFile(log *helpers.DistinctLogger) source.File {
+func NewZeroFile(log loggers.Logger) source.File {
 	return zeroFile{log: log}
 }
 
diff --git a/tpl/tplimpl/embedded/templates.autogen.go b/tpl/tplimpl/embedded/templates.autogen.go
@@ -387,63 +387,90 @@ if (!doNotTrack) {
 	{`shortcodes/gist.html`, `<script type="application/javascript" src="https://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 -}}
+	{`shortcodes/instagram.html`, `{{- $pc := site.Config.Privacy.Instagram -}}
 {{- if not $pc.Disable -}}
-{{- if $pc.Simple -}}
-{{ template "_internal/shortcodes/instagram_simple.html" . }}
-{{- else -}}
-{{ $id := .Get 0 }}
-{{ $hideCaption := cond (eq (.Get 1) "hidecaption") "1" "0" }}
-{{ with getJSON "https://api.instagram.com/oembed/?url=https://instagram.com/p/" $id "/&hidecaption=" $hideCaption  }}{{ .html | safeHTML }}{{ end }}
-{{- end -}}
+  {{ $accessToken := site.Config.Services.Instagram.AccessToken }}
+  {{- if not $accessToken -}}
+    {{- erroridf "err-missing-instagram-accesstoken" "instagram shortcode: Missing config value for services.instagram.accessToken. This can be set in config.toml, but it is recommended to configure this via the HUGO_SERVICES_INSTAGRAM_ACCESSTOKEN OS environment variable. If you are using a Client Access Token, remember that you must combine it with your App ID using a pipe symbol (<APPID>|<CLIENTTOKEN>) otherwise the request will fail." -}}
+  {{- else -}}
+    {{- if $pc.Simple -}}
+      {{ template "_internal/shortcodes/instagram_simple.html" . }}
+    {{- else -}}
+      {{ $id := .Get 0 }}
+      {{ $hideCaption := cond (eq (.Get 1) "hidecaption") "1" "0" }}
+      {{ $headers := dict "Authorization" (printf "Bearer %s" $accessToken) }}
+      {{ with getJSON "https://graph.facebook.com/v8.0/instagram_oembed/?url=https://instagram.com/p/" $id "/&hidecaption=" $hideCaption $headers }}
+        {{ .html | safeHTML }}
+      {{ end }}
+    {{- end -}}
+  {{- end -}}
 {{- end -}}`},
 	{`shortcodes/instagram_simple.html`, `{{- $pc := .Page.Site.Config.Privacy.Instagram -}}
 {{- $sc := .Page.Site.Config.Services.Instagram -}}
 {{- if not $pc.Disable -}}
-{{- $id := .Get 0 -}}
-{{- $item := getJSON "https://api.instagram.com/oembed/?url=https://www.instagram.com/p/" $id "/&amp;maxwidth=640&amp;omitscript=true" -}}
-{{- $class1 := "__h_instagram" -}}
-{{- $class2 := "s_instagram_simple" -}}
-{{- $hideCaption := (eq (.Get 1) "hidecaption") -}}
-{{ with $item }}
-{{- $mediaURL := printf "https://instagram.com/p/%s/" $id | safeURL -}}
-{{- if not $sc.DisableInlineCSS -}}
-{{ template "__h_simple_instagram_css" $ }}
-{{- end -}}
-<div class="{{ $class1 }} {{ $class2 }} card" style="max-width: {{ $item.thumbnail_width }}px">
-	<div class="card-header">
-    <a href="{{ $item.author_url | safeURL }}" class="card-link">{{ $item.author_name }}</a>
-  </div>
-	<a href="{{ $mediaURL }}" rel="noopener" target="_blank"><img class="card-img-top img-fluid" src="{{ $item.thumbnail_url }}" width="{{ $item.thumbnail_width }}"  height="{{ $item.thumbnail_height }}" alt="Instagram Image"></a>
-	<div class="card-body">
-		{{ if not $hideCaption }}<p class="card-text"><a href="{{ $item.author_url | safeURL }}" class="card-link">{{ $item.author_name }}</a> {{ $item.title}}</p>{{ end }}
-		<a href="{{ $item.author_url | safeURL }}" class="card-link">View More on Instagram</a>
-	</div>
-</div>
-{{ end }}
+  {{ $accessToken := site.Config.Services.Instagram.AccessToken }}
+  {{- if not $accessToken -}}
+    {{- erroridf "err-missing-instagram-accesstoken" "instagram shortcode: Missing config value for services.instagram.accessToken. This can be set in config.toml, but it is recommended to configure this via the HUGO_SERVICES_INSTAGRAM_ACCESSTOKEN OS environment variable. If you are using a Client Access Token, remember that you must combine it with your App ID using a pipe symbol (<APPID>|<CLIENTTOKEN>) otherwise the request will fail." -}}
+  {{- else -}}
+    {{- $id := .Get 0 -}}
+    {{- $headers := dict "Authorization" (printf "Bearer %s" $accessToken) -}}
+    {{- $item := getJSON "https://graph.facebook.com/v8.0/instagram_oembed/?url=https://instagram.com/p/" $id "/&amp;maxwidth=640&amp;omitscript=true" $headers -}}
+    {{- $class1 := "__h_instagram" -}}
+    {{- $class2 := "s_instagram_simple" -}}
+    {{- $hideCaption := (eq (.Get 1) "hidecaption") -}}
+    {{ with $item }}
+      {{- $mediaURL := printf "https://instagram.com/p/%s/" $id | safeURL -}}
+      {{- if not $sc.DisableInlineCSS -}}
+        {{ template "__h_simple_instagram_css" $ }}
+      {{- end -}}
+      <div class="{{ $class1 }} {{ $class2 }} card" style="max-width: {{ $item.thumbnail_width }}px">
+        <div class="card-header">
+          <a href="{{ $item.author_url | safeURL }}" class="card-link">
+            {{ $item.author_name }}
+          </a>
+        </div>
+        <a href="{{ $mediaURL }}" rel="noopener" target="_blank">
+          <img class="card-img-top img-fluid" src="{{ $item.thumbnail_url }}" width="{{ $item.thumbnail_width }}"  height="{{ $item.thumbnail_height }}" alt="Instagram Image">
+        </a>
+        <div class="card-body">
+          {{ if not $hideCaption }}
+            <p class="card-text">
+              <a href="{{ $item.author_url | safeURL }}" class="card-link">
+                {{ $item.author_name }}
+              </a>
+              {{ $item.title}}
+            </p>
+          {{ end }}
+          <a href="{{ $item.author_url | safeURL }}" class="card-link">
+            View More on Instagram
+          </a>
+        </div>
+      </div>
+    {{ end }}
+  {{- end -}}
 {{- end -}}
 
 {{ define "__h_simple_instagram_css" }}
-{{ if not (.Page.Scratch.Get "__h_simple_instagram_css") }}
-{{/* Only include once */}}
-{{  .Page.Scratch.Set "__h_simple_instagram_css" true }}
-<style type="text/css">
-   .__h_instagram.card {
+  {{ if not (.Page.Scratch.Get "__h_simple_instagram_css") }}
+    {{/* Only include once */}}
+    {{  .Page.Scratch.Set "__h_simple_instagram_css" true }}
+    <style type="text/css">
+      .__h_instagram.card {
       font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;
       font-size: 14px;
       border: 1px solid rgb(219, 219, 219);
       padding: 0;
-	  margin-top: 30px;
-   }
-   .__h_instagram.card .card-header, .__h_instagram.card .card-body {
+      margin-top: 30px;
+      }
+      .__h_instagram.card .card-header, .__h_instagram.card .card-body {
       padding: 10px 10px 10px;
-   }
-   .__h_instagram.card img {
+      }
+      .__h_instagram.card img {
       width: 100%;
-    	height: auto;
-   }
-</style>
-{{ end }}
+      	height: auto;
+      }
+    </style>
+  {{ end }}
 {{ end }}`},
 	{`shortcodes/param.html`, `{{- $name := (.Get 0) -}}
 {{- with $name -}}
diff --git a/tpl/tplimpl/embedded/templates/shortcodes/instagram.html b/tpl/tplimpl/embedded/templates/shortcodes/instagram.html
@@ -1,10 +1,18 @@
-{{- $pc := .Page.Site.Config.Privacy.Instagram -}}
+{{- $pc := site.Config.Privacy.Instagram -}}
 {{- if not $pc.Disable -}}
-{{- if $pc.Simple -}}
-{{ template "_internal/shortcodes/instagram_simple.html" . }}
-{{- else -}}
-{{ $id := .Get 0 }}
-{{ $hideCaption := cond (eq (.Get 1) "hidecaption") "1" "0" }}
-{{ with getJSON "https://api.instagram.com/oembed/?url=https://instagram.com/p/" $id "/&hidecaption=" $hideCaption  }}{{ .html | safeHTML }}{{ end }}
-{{- end -}}
+  {{ $accessToken := site.Config.Services.Instagram.AccessToken }}
+  {{- if not $accessToken -}}
+    {{- erroridf "err-missing-instagram-accesstoken" "instagram shortcode: Missing config value for services.instagram.accessToken. This can be set in config.toml, but it is recommended to configure this via the HUGO_SERVICES_INSTAGRAM_ACCESSTOKEN OS environment variable. If you are using a Client Access Token, remember that you must combine it with your App ID using a pipe symbol (<APPID>|<CLIENTTOKEN>) otherwise the request will fail." -}}
+  {{- else -}}
+    {{- if $pc.Simple -}}
+      {{ template "_internal/shortcodes/instagram_simple.html" . }}
+    {{- else -}}
+      {{ $id := .Get 0 }}
+      {{ $hideCaption := cond (eq (.Get 1) "hidecaption") "1" "0" }}
+      {{ $headers := dict "Authorization" (printf "Bearer %s" $accessToken) }}
+      {{ with getJSON "https://graph.facebook.com/v8.0/instagram_oembed/?url=https://instagram.com/p/" $id "/&hidecaption=" $hideCaption $headers }}
+        {{ .html | safeHTML }}
+      {{ end }}
+    {{- end -}}
+  {{- end -}}
 {{- end -}} 
\ No newline at end of file
diff --git a/tpl/tplimpl/embedded/templates/shortcodes/instagram_simple.html b/tpl/tplimpl/embedded/templates/shortcodes/instagram_simple.html
@@ -1,48 +1,67 @@
 {{- $pc := .Page.Site.Config.Privacy.Instagram -}}
 {{- $sc := .Page.Site.Config.Services.Instagram -}}
 {{- if not $pc.Disable -}}
-{{- $id := .Get 0 -}}
-{{- $item := getJSON "https://api.instagram.com/oembed/?url=https://www.instagram.com/p/" $id "/&amp;maxwidth=640&amp;omitscript=true" -}}
-{{- $class1 := "__h_instagram" -}}
-{{- $class2 := "s_instagram_simple" -}}
-{{- $hideCaption := (eq (.Get 1) "hidecaption") -}}
-{{ with $item }}
-{{- $mediaURL := printf "https://instagram.com/p/%s/" $id | safeURL -}}
-{{- if not $sc.DisableInlineCSS -}}
-{{ template "__h_simple_instagram_css" $ }}
-{{- end -}}
-<div class="{{ $class1 }} {{ $class2 }} card" style="max-width: {{ $item.thumbnail_width }}px">
-	<div class="card-header">
-    <a href="{{ $item.author_url | safeURL }}" class="card-link">{{ $item.author_name }}</a>
-  </div>
-	<a href="{{ $mediaURL }}" rel="noopener" target="_blank"><img class="card-img-top img-fluid" src="{{ $item.thumbnail_url }}" width="{{ $item.thumbnail_width }}"  height="{{ $item.thumbnail_height }}" alt="Instagram Image"></a>
-	<div class="card-body">
-		{{ if not $hideCaption }}<p class="card-text"><a href="{{ $item.author_url | safeURL }}" class="card-link">{{ $item.author_name }}</a> {{ $item.title}}</p>{{ end }}
-		<a href="{{ $item.author_url | safeURL }}" class="card-link">View More on Instagram</a>
-	</div>
-</div>
-{{ end }}
+  {{ $accessToken := site.Config.Services.Instagram.AccessToken }}
+  {{- if not $accessToken -}}
+    {{- erroridf "err-missing-instagram-accesstoken" "instagram shortcode: Missing config value for services.instagram.accessToken. This can be set in config.toml, but it is recommended to configure this via the HUGO_SERVICES_INSTAGRAM_ACCESSTOKEN OS environment variable. If you are using a Client Access Token, remember that you must combine it with your App ID using a pipe symbol (<APPID>|<CLIENTTOKEN>) otherwise the request will fail." -}}
+  {{- else -}}
+    {{- $id := .Get 0 -}}
+    {{- $headers := dict "Authorization" (printf "Bearer %s" $accessToken) -}}
+    {{- $item := getJSON "https://graph.facebook.com/v8.0/instagram_oembed/?url=https://instagram.com/p/" $id "/&amp;maxwidth=640&amp;omitscript=true" $headers -}}
+    {{- $class1 := "__h_instagram" -}}
+    {{- $class2 := "s_instagram_simple" -}}
+    {{- $hideCaption := (eq (.Get 1) "hidecaption") -}}
+    {{ with $item }}
+      {{- $mediaURL := printf "https://instagram.com/p/%s/" $id | safeURL -}}
+      {{- if not $sc.DisableInlineCSS -}}
+        {{ template "__h_simple_instagram_css" $ }}
+      {{- end -}}
+      <div class="{{ $class1 }} {{ $class2 }} card" style="max-width: {{ $item.thumbnail_width }}px">
+        <div class="card-header">
+          <a href="{{ $item.author_url | safeURL }}" class="card-link">
+            {{ $item.author_name }}
+          </a>
+        </div>
+        <a href="{{ $mediaURL }}" rel="noopener" target="_blank">
+          <img class="card-img-top img-fluid" src="{{ $item.thumbnail_url }}" width="{{ $item.thumbnail_width }}"  height="{{ $item.thumbnail_height }}" alt="Instagram Image">
+        </a>
+        <div class="card-body">
+          {{ if not $hideCaption }}
+            <p class="card-text">
+              <a href="{{ $item.author_url | safeURL }}" class="card-link">
+                {{ $item.author_name }}
+              </a>
+              {{ $item.title}}
+            </p>
+          {{ end }}
+          <a href="{{ $item.author_url | safeURL }}" class="card-link">
+            View More on Instagram
+          </a>
+        </div>
+      </div>
+    {{ end }}
+  {{- end -}}
 {{- end -}}
 
 {{ define "__h_simple_instagram_css" }}
-{{ if not (.Page.Scratch.Get "__h_simple_instagram_css") }}
-{{/* Only include once */}}
-{{  .Page.Scratch.Set "__h_simple_instagram_css" true }}
-<style type="text/css">
-   .__h_instagram.card {
+  {{ if not (.Page.Scratch.Get "__h_simple_instagram_css") }}
+    {{/* Only include once */}}
+    {{  .Page.Scratch.Set "__h_simple_instagram_css" true }}
+    <style type="text/css">
+      .__h_instagram.card {
       font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;
       font-size: 14px;
       border: 1px solid rgb(219, 219, 219);
       padding: 0;
-	  margin-top: 30px;
-   }
-   .__h_instagram.card .card-header, .__h_instagram.card .card-body {
+      margin-top: 30px;
+      }
+      .__h_instagram.card .card-header, .__h_instagram.card .card-body {
       padding: 10px 10px 10px;
-   }
-   .__h_instagram.card img {
+      }
+      .__h_instagram.card img {
       width: 100%;
-    	height: auto;
-   }
-</style>
-{{ end }}
+      	height: auto;
+      }
+    </style>
+  {{ end }}
 {{ end }} 
\ No newline at end of file