使用 JSON 的 Hugo Shortcode 抛出 "bad character U+0022 error"

Hugo Shortcode that uses JSON throws "bad character U+0022 error"

我正在尝试使用两个参数创建一个短代码,一个 CSS class 和一个推文 ID。我的起点是这个示例 https://gohugo.io/content-management/shortcodes/#tweet,它显示了如何使用默认的 Hugo Twitter 短代码

{{< tweet 877500564405444608 >}}

但是我想在post.md中这样使用它:

{{< tweet-single class="alignright" id="877500564405444608" >}}

生成 html:

<div class="tweet-in-post alignright">
<twitter-widget class=....
</div>

但在 tweet-single.html

中使用它
<!-- tweet-single -->

<div class="tweet-in-post {{ .Get "class" }}">

{{ (getJSON "https://api.twitter.com/1.1/statuses/oembed.json?dnt=1&hide_thread=1&id={{ .Get "id" }}") }}

</div>

给我错误 bad character U+0022 ‘"’

这些文档 https://gohugo.io/templates/data-templates/#call-the-functions-with-a-url 展示了如何在 Hugo 中调用 JSON 函数,但我不知道如何使用这些示例来让我的简码起作用。

自定义内置短代码的最佳方法是从其代码开始。

您提供的 link 显示了 如何使用 推文短代码,但没有显示其代码实际是什么样子。需要深入研究 Hugo 源代码才能真正找到内置简码的样子。

您可以在这里找到它们:https://github.com/gohugoio/hugo/tree/master/tpl/tplimpl/embedded/templates/shortcodes

截至当前提交 (67f9204),Twitter 短代码如下所示:

{{- $pc := .Page.Site.Config.Privacy.Twitter -}}
{{- if not $pc.Disable -}}
{{- if $pc.Simple -}}
{{ template "_internal/shortcodes/twitter_simple.html" . }}
{{- else -}}
{{- $url := printf "https://api.twitter.com/1/statuses/oembed.json?id=%v&dnt=%t" (index .Params 0) $pc.EnableDNT -}}
{{- $json := getJSON $url -}}
{{ $json.html | safeHTML }}
{{- end -}}
{{- end -}}

这就是你的起点。

但是这个例子特别棘手,因为这个短代码使用了推特 api 设置的样式,并且很难 fiddle 使用它。

This post 可以帮到你。

这里的另一个困难是,如果你查看推特短代码,你会发现推文 ID 不是由 {{ .Get "ID" }}(一个命名参数)调用的,而是由 (index .Params 0)(一个位置参数)。并且 Hugo 不允许您混合使用命名参数和位置参数。

所以您不能像您尝试的那样使用 {{ .Get "class" }} 之类的东西。相反,您需要使用位置参数,例如 {{ .Get xx }}xx 作为您的参数在短代码调用中的位置。

这是一个可能的解决方案:

{{- $pc := .Page.Site.Config.Privacy.Twitter -}}
{{- if not $pc.Disable -}}
{{- if $pc.Simple -}}
{{ template "_internal/shortcodes/twitter_simple.html" . }}
{{- else -}}
<blockquote class="twitter-tweet tw-align-{{ .Get 0 }}" data-lang="en">
  {{- $url := printf "https://api.twitter.com/1/statuses/oembed.json?id=%v&dnt=%t" (index .Params 1) $pc.EnableDNT -}}
  {{- $json := getJSON $url -}}
  {{ $json.html | safeHTML }}
</blockquote>
{{- end -}}
{{- end -}}

如您所见,我根据上面提到的 post 的回答添加了一些 <blockquote> 自定义设置,并且我正在使用 {{ .Get 0 }} 作为职位。这意味着我现在必须将推文 ID 的参数位置调整为 1.

如果您将此短代码命名为 tweet-single.html,您可以使用以下方式调用它:

{{< twitter-single right 877500564405444608>}}

将推文显示在右侧。

要使推文居中,应该是:

{{< twitter-single center 877500564405444608>}}

请注意 rightcenter 不要使用引号,因为它们是位置参数。


替代方法:

如果由于某种原因这种方法对您不起作用,则完全不同的方法是重新创建推文的整个格式(不使用推特 api 所做的)。

如果您使用 twitter_simple.html 而不是 twitter.html,这就是 Hugo 所做的。

如果您查看 twitter_simple.html,您会发现他们省略了样式脚本,而是为 .twitter-tweet class:

重新创建了一些更简单的格式
{{- $pc := .Page.Site.Config.Privacy.Twitter -}}
{{- $sc := .Page.Site.Config.Services.Twitter -}}
{{- if not $pc.Disable -}}
{{- $id := .Get 0 -}}
{{- $json := getJSON "https://api.twitter.com/1/statuses/oembed.json?id=" $id "&omit_script=true" -}}
{{- if not $sc.DisableInlineCSS -}}
{{ template "__h_simple_twitter_css" $ }}
{{- end -}}
{{ $json.html | safeHTML }}
{{- end -}}

{{ define "__h_simple_twitter_css" }}
{{ if not (.Page.Scratch.Get "__h_simple_twitter_css") }}
{{/* Only include once */}}
{{  .Page.Scratch.Set "__h_simple_twitter_css" true }}
<style type="text/css">
  .twitter-tweet {
  font: 14px/1.45 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;
  border-left: 4px solid #2b7bb9;
  padding-left: 1.5em;
  color: #555;
}
  .twitter-tweet a {
  color: #2b7bb9;
  text-decoration: none;
}
  blockquote.twitter-tweet a:hover,
  blockquote.twitter-tweet a:focus {
  text-decoration: underline;
}
</style>
{{ end }}
{{ end }}

您可以尝试使用此代码,直到获得适合您的自定义。