Hugo

Links for images, videos, audio in internal templates twitter_cards and opengraph

Hello,

I was trying to use the internal twitter_cards.html template and it didn’t work for me for 2 reasons:

  1. I am using the images front-matter to set the twitter:image meta data.

    The page was a bundle, so the full path of the page was something like content/posts/my-post/index.md, and I decided to keep the images in the bundle directory (though, not using the Resources method to fetch those for the meta data, as I don’t need image processing).

    So the path of an image from site root was /posts/my-post/images/some-image.png.

    It was convenient to have the images front-matter (TOML) set as below:

    images = ["images/some-image.png"]
    

    … instead of typing the full path from site root.

    The problem is that in the internal twitter_cards and opengraph templates use something like below:

    {{ with .Params.images }}
        <meta name="twitter:image" content="{{ index . 0 | absURL }}"/>
    {{ end }}
    

    So, with the above front-matter, the above Go template expands to:

    <meta name="twitter:image" content="https://example.com/images/some-image.png"/>
    

    This expansion is wrong!
    The correct image link would be: "https://example.com/posts/my-post/images/some-image.png".

  2. Another problem is that I cannot simply use relURL instead of absURL in the above template. Twitter cards require the twitter:image tag to have the absolute URL. I have tried using the relative URL, didn’t work.


Workaround

At the moment, the only way to make the twitter cards works (if not using Resources, but instead the images front-matter) is to put the absolute link manually in that front-matter.

So one would need to do something like:

images = ["/posts/my-post/images/some-image.png"]

… inside the front-matter of a /posts/my-post/index.md file.

More than the problem of lot of typing, that link has to be manually fixed if a custom slug is used for the post, or if the post if moved to any other section for some reason.

Fix

Instead I have tried and tested this fix to work (below is the gist of the fix):

{{ $permalink := .Permalink }}
{{ with .Params.images }}
    {{ $image := (index . 0) }}
    {{ $image_link_absolute := (findRE "^/" $image) }}
    {{ if $image_link_absolute }}
        <meta name="twitter:image" content="{{ $image | absURL }}"/>
    {{ else }}
        <meta name="twitter:image" content="{{ (printf "%s%s" $permalink $image) }}"/>
    {{ end }}
{{ end }}

What above does:

  • If the image path in images in the front-matter begins with / (e.g. /images/foo.png), the user is intending to specify the absolute path (would make sense if the path is to an image in the static/ directory). In that case, the current method of absURL is used.
  • But if the image path does not begin with / (e.g. images/foo.png), the user wants the Page’s .Permalink to be auto-prefixed to that path.

Does this work?

Yes! I have tested and deployed this technique already on my blog.

Now, with:

images = ["images/seconds-to-human-time.png"]

the twitter image meta tag looks like:

<meta name="twitter:image" content="https://scripter.co/convert-seconds-to-human-time/images/seconds-to-human-time.png">

Here are the fixed internal templates saved as partials:


So what’s next?

  • Is this fix (the above linked modified versions of the 2 internal templates) acceptable in the internal templates? Should I open a PR for this?
  • Or should a different logic be used to decide when to auto-prefix the Permalink?
  • If not, then well, may be someone else also finds those modified templates useful.

@bep Bumping this thread for your input.

I’m also trying to setup OpenGraph and Twitter Cards using Hugo internal templates. This is my content structure:

.
├── _index.md
├── about.md
└── posts
    ├── post1
    │   ├── index.md
    │   └── image.jpg
    ├── post2.md
    └── post3.md

Although internal templates are undocumented, so far I’ve found that I need to define “images” in a frontmatter.

Question: how to reference an image from page bundle in a frontmatter (I do not want to specify its full url)? My attempt to reference it via Resources doesn’t work:

---
title: Post 1
description: This is the post number 1
images: ["{{ (.Resources.GetMatch "image.jpg").RelPermalink }}"]
---

Functions like that would work only in an Archetype. Also I think that you would need to eliminate the angle brackets and the quotes for the above to work.

P.S. Cool approach by the way. :+1:

You can do this too:

{{- with .Params.images -}}
  <meta property='og:image' content='{{ ( replaceRE "^\\./" $.RelPermalink . ) | absURL }}'>
{{- end -}}