HUGO

Image EXIF Data Shortcode: Nil Pointer evaluating resource.Resource.RelPermalink

Hugo Version:

Hugo Static Site Generator v0.74.3-DA0437B4/extended darwin/amd64 BuildDate: 2020-07-23T16:28:32Z

Hello,

I’m trying to display an image with accompanying EXIF data as a shortcode.

Using this guide as a reference, (actually, straight copy-pasted), I still cannot get it to work properly.

execute of template failed: template: shortcodes/exif.html:6:29: executing "shortcodes/exif.html" at <$originalImage.RelPermalink>: nil pointer evaluating resource.Resource.RelPermalink

Here’s the full shortcode:

{{- $imageName := .Get "src" -}}
{{- $originalImage := (.Page.Resources.ByType "image").GetMatch (printf "**%s**" (.Get "src")) -}}
{{- $noExif := .Get "noExif" -}}

<p>
    <a href="{{$originalImage.RelPermalink}}">
        <img src="{{$originalImage.RelPermalink}}" alt="{{ .Get "alt" }}"/>
    </a>
    {{ if (and $originalImage.Exif (ne $noExif "true")) }}
        <div class="exifTags">
            Taken

            {{ with $originalImage.Exif }}
                {{ if and .Tags.GPSLatitude .Tags.GPSLongitude }}
                    {{ $latSign := 1 }}
                    {{ if eq .Tags.LatRef "S" }}
                        {{ $latSign = -1 }}
                    {{ end }}
                    {{ $lonSign := 1 }}
                    {{ if eq .Tags.LonRef "W" }}
                        {{ $lonSign = -1 }}
                    {{ end }}
                    {{ $lat := mul $latSign (add (index .Tags.GPSLatitude 0) (add (div (index .Tags.GPSLatitude 1) 60) (div (index .Tags.GPSLatitude 2) 3600))) }}
                    {{ $lon := mul $lonSign (add (index .Tags.GPSLongitude 0) (add (div (index .Tags.GPSLongitude 1) 60) (div (index .Tags.GPSLongitude 2) 3600))) }}
                    <div class="exifElement">
                        <a href="http://www.openstreetmap.org/?mlat={{ $lat }}&mlon={{ $lon }}&zoom=16&layers=M">
                            <i class="fa fa-map-marked"></i>
                            here
                        </a>
                    </div>
                {{ end }}

                {{ if .Tags.Make }}
                    with a(n)
                    <div class="exifElement">	
                        <i class="fa fa-tag"></i>
                        {{ .Tags.Make }}
                    </div>
                {{ end }}

                {{ if .Tags.Model }}
                    <div class="exifElement">
                        <i class="fa fa-camera"></i>
                        {{ .Tags.Model }}
                    </div>
                {{ end }}

                {{ if .Tags.FocalLength }}
                    using a focal length of
                    <div class="exifElement">
                        <i class="fa fa-expand-alt"></i>
                        {{ .Tags.FocalLength }} mm
                    </div>
                {{ end }}

                {{ if (or .Tags.ExposureTime .Tags.FNumber .Tags.ISOSpeedRatings) }}
                at
                {{ end }}

                {{ if .Tags.ExposureTime }}
                    <div class="exifElement">
                        <i class="fa fa-clock"></i>
                        {{ .Tags.ExposureTime }}
                    </div>
                {{ end }}

                {{ if .Tags.FNumber }}
                    <div class="exifElement">
                        <i class="fa fa-bullseye"></i>
                        f/{{ .Tags.FNumber }}
                    </div>
                {{ end }}

                {{ if .Tags.ISOSpeedRatings }}
                    <div class="exifElement">
                        ISO{{ .Tags.ISOSpeedRatings }}
                    </div>
                {{ end }}

            {{ end }}
        </div>
    {{ end }}
</p>

And here’s how I’m calling it:

{{< exif src="photos/monkey.jpeg" alt="" >}}

I have my desired monkey photo located at “assets/photos/monkey.jpeg”

Any thoughts?

Following HUGO’s own Exif processing guide, I’m still receiving the Nil Pointer error.

Update: I got this particular shortcode to work only after keeping the jpeg in the same folder as the _index.md page the shortcode is called from.

Ideally, I’d like to be able to keep the picture in the static or assets folder, but I can’t seem to figure it out.

Resources can be categorized as either “global resources” or “page resources”.

Global resources are:

  • Located in the assets directory
  • Accessed with resources.Get and resources.GetMatch

Page resources are:

  • Located within a page bundle
  • Accessed with .Resources.Match, .Resources.GetMatch, and .Resources.ByType

In your shortcode you are trying to access a global resource using a method intended for page resources.

Change this:

{{- $originalImage := (.Page.Resources.ByType "image").GetMatch (printf "**%s**" (.Get "src")) -}}

To this:

{{- $originalImage := resources.Get (.Get "src") -}}
2 Likes

This is exactly what I needed! Thank you so much, your efforts are extremely appreciated!

Curiously, I’m getting this error when deploying via Netlify:

Error: Error building site: "/opt/build/repo/content/monkey/_index.md:11:1": failed to render shortcode "exif": failed to process shortcode: "/opt/build/repo/themes/rh-theme/layouts/shortcodes/exif.html:11:33": execute of template failed: template: shortcodes/exif.html:11:33: executing "shortcodes/exif.html" at <$originalImage.Exif>: can't evaluate field Exif in type resource.Resource

It works perfectly on localhost though!

Are you processing the same images in both environments?

What version of Hugo is running on Netlify? EXIF support was added in v0.58.

1 Like

I have no environment set— in my netlify.toml I have HUGO_VERSION = "0.82.1" set.

Perhaps I should contact Netlify support in this case?

What I meant was, when you tested locally were you testing with the same images?

1 Like

Yes, while testing locally I was using “monkey.jpeg” as the first example, which is what caused the build error on Netlify.

I just swapped out “monkey.jpeg” for “flowers.jpg”, and while it tested fine on localhost, it gave me the same error while building with Netlify.

I’m out of ideas at the moment, but I would like to see your netlify.toml file.

I truly appreciate the help you’ve given so far, it’s been extremely helpful. Regardless of this kerfuffle, you’ve completely solved my Hugo issue. Here’s my netlify.toml as requested:

[build]
command = "hugo --gc --minify"
publish = "public"
HUGO_VERSION = "0.82.1"

[functions]
  directory = "functions"

[[headers]]
    for = "/*"
    [headers.values]
        X-Frame-Options = "deny"
        X-XSS-Protection = "1; mode=block"
        X-Content-Type-Options = "nosniff"
        Referrer-Policy = "no-referrer"
        Strict-Transport-Security = '''
            max-age=31536000;
            includeSubDomains
        '''

        Permissions-Policy = '''
            accelerometer=none,
            ambient-light-sensor=none,
            autoplay=none,
            camera=none,
            encrypted-media=none,
            fullscreen=none,
            geolocation=none,
            gyroscope=none,
            magnetometer=none,
            microphone=none,
            midi=none,
            payment=none,
            picture-in-picture=none,
            speaker=none,
            usb=none,
            vibrate=none,
            vr=none
        '''

[[plugins]]
  package = "netlify-plugin-submit-sitemap"

	[plugins.inputs]

	# The base url of your site (optional, default = main URL set in Netlify)
	baseUrl = "https://roryhinkel.com"

	# Path to the sitemap URL (optional, default = /sitemap.xml)
	sitemapPath = "/sitemap.xml"

	# Enabled providers to submit sitemap to (optional, default = 'google', 'bing', 'yandex'). Possible providers are currently only 'google', 'bing', 'yandex'.
	providers = [
		"google",
		"bing",
	]

See https://docs.netlify.com/configure-builds/common-configurations/hugo/.

I think it should be:

[build]
command = "hugo --gc --minify"
publish = "public"

[build.environment]
HUGO_VERSION = "0.82.1"
1 Like

You, my friend, are a genius. This solved it completely. I truly appreciate your help! Thank you!! :innocent:

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.