DFD Hugo Image Handling Module README

DFD Hugo image handling module

A Hugo module for handling images and image-related functionality for themes (including enabling responsive images).

Status

build-and-verify

GitHub repository

https://github.com/danielfdickinson/image-handling-mod-hugo-dfd

Site with examples

https://image-handling-mod.wildtechgarden.ca

Features

Basic usage of the module

Prerequisites

  1. Hugo version 0.80.0 or higher installed
    • For webp support you must have version 0.83.0 or higher extended version of Hugo
    • For text overlays you must have version 0.90.0 or higher of Hugo
  2. You must have in directory containing a hugo site (e.g. such as created by hugo new site <directory>).
  3. You must have a recent version of Go installed (see section Prerequisite in ‘Use Hugo Modules’ in the Hugo documentation).
  4. The site must be initialized as a Hugo module (see ‘Initialize a New Module’ in the Hugo documentation, or the output of hugo mod init).
  5. Before the site will build correctly, you will also need a theme installed.

Importing the module

  1. The first step to making use of this module is to add it to your site or theme. In your configuration file:

    config.toml

    [module]
    [[module.imports]]
    path = "github.com/danielfdickinson/image-handling-mod-hugo-dfd"
    

    OR config.yaml

    module:
      imports:
        - path: github.com/danielfdickinson/image-handling-mod-hugo-dfd
    
  2. Execute

    hugo mod get github.com/danielfdickinson/image-handling-mod-hugo-dfd
    hugo mod tidy
    

Add the image

  1. Place your image in a page bundle (e.g. screenshot.png) Note 7
  2. OR under assets in your project root Note 8

If you don’t use a page bundle or assets, the image can still be used, but cannot be made responsive Note 9

Add CSS to style the images

For the demo we use a small custom CSS file

Use markdown (render-image render hook makes it responsive)

Example #1

![Screenshot of a web page with an aqua theme](screenshot.png)

Use figure shortcode

Example #2

{{< figure class="responsive-figure" title="Figure 1: Differences between markdown figures and figure shortcode" src="screenshot.png" alt="Screenshot of a web page with an aqua theme" caption="For a figure caption can be different than alt text" >}}

Example #3

{{< figure class="responsive-figure fullwidth" title="Figure 1: Differences between markdown figures and figure shortcode (full width)" src="screenshot.png" alt="Screenshot of a web page with an aqua theme" caption="For a figure caption can be different than alt text" >}}

See ‘wrapped image’ partial, below, for the full set of parameters you can use with the shortcode.

NOTE: The default for the figure shortcode is to ignoreStaticImages. If you want to changes that, add a parameter ignoreStaticImages="false". For example:

{{< figure class="static-figure" title="Figure 1: Differences between markdown figures and figure shortcode" src="/images/screenshot.png" alt="Screenshot of a web page with an aqua theme" caption="For a figure caption can be different than alt text" ignoreStaticImages="false" >}}

Static images cannot be made responsive Note 9

Advanced usage

base64 encoded images

The src parameter can be provided as a base64-encoded image instead of a filename or URI. For example:

![Portion of a class diagram](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA…)

or more usefully:

![Portion of a class diagram][reference-to-image]

Other markdown / text.

[reference-to-image]:data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA…

Image handling partials

Wrapped image

{{ partial "helpers/wrapped-image" (
    dict "width" 1920px
    "height" 1080px
    "thumbnailWidth" "90px"
    "thumbnailHeight" ""
    "alt" "Screenreader text"
    "altRendered" "alt text is HTML, not Markdown or plain (default false)"
    "title" "Title (screenreaders and often tooltips)"
    "image" "Image source (usually relative to page bundle or assets) or srcset (from another partial, below)"
    "page" .Page (Hugo page context; it is unlikely  that you will want this to be other than .Page)
    "class" "Classes (space separated string) to add to the wrapper element, or the img element if there is no image_wrapper"
    "link" "A link in which to wrap the image"
    "linkclass" "Classes (space separated string) to add to a wrapping link (only if 'link' specified)"
    "target" "For link: E.g. ('_blank')"
    "rel" "For link: E.g. ('nofollow')"
    "imageWrapper" "element in which to wrap <img> element"
    "imageClass" "when there is a wrapper, the class to apply to the <img> element"
    "caption" "A <figcaption> if image wrapper is <figure>, <span> if there is no title, or <div> if there is a title (because title will be wrapped in an <h2>)"
    "captionRendered" "caption is HTML, not Markdown or plain (default false)"
    "attr" "More caption text (but can be wrapped by a hyperlink via attrLink), only for a '<figure>'"
    "attrLink" "A hyperlink wrapped around attr, only if 'attr' above"
    "noImageWrapper" (If true you get a bare <img> element; default for render-image render hook)
    "imageSizes" "A slice of widths to use for the srcset"
    "thumbnailSizes" "A slice of width to use for thumbnail srcset"
    "singleSize" "If true, ignore srcset and *sizes; non-responsive img"
    "convertTo" "image format to which to convert (for this call only)"
    "thumbnails" "If true generate thumbnails; if fullsize is also true use a 'picture' element to pick the set of images (thumbnails or full size, based on screen size)
    "fullSize" "If true generate full size images; see thumbnails"
    "sizesAttr" "Overrides img (or source) 'sizes=' attribute"
    "thumbnailSizesAttr" "As with sizesAttr but for thumbnails"
    "minThumbnailViewport" "Minimum size of the viewport that is require to display thumbnails instead of full images"
    "loading" "If set, is the 'loading=' attribute for the 'img'"
    "noVisibleCaption" "If true then when there is a title and/or caption with an imageWrapper do not display the title and/or caption (attributes only)"
    "imageConvertMethod" "Set method for resize/crop of image, from [ Fit \| GrowFit \| Fill \| Resize ]"
    "imageOverlay" "Dict with src, x, and y for image, and x, y position to overlay 'src' on the main image"
    "textOverlay" "Slice of maps (dict) with text, opts (which is a dict, see [Hugo docs](https://gohugo.io/functions/images/#text)) which specifies text to overlay over an image and the options (color, size, etc)"
    )
-}}
Image and Text overlays for shortcodes

For shortcodes you need to add the definition of the map (for imageOverlay) or list of maps (for textOverlay) as a parameter in your frontmatter, and use the shortcode paramters imageOverlayParam and/or textOverlayParam to point to the page frontmatter param.

For example (without the /* or */):

{{< figure alt="Light blue gradient with the work 'Test' in a large yellow font (if Hugo version >= 0.90.0)" src="/light-blue-gradient-social-card.png" textOverlayParam="figureOverlayText" */ class="responsive-figure" >}}

Featured images each have a url and may have

{{ partial "helpers/featured-images" . -}}
{{ partial "helpers/featured-image" . -}}
{{ partial "helpers/featured-image-link" . -}}

.Site or .Page params

For all processable images

Currently:

Param Default Description
imageResponsive true Make images responsive (have srcset and sizes)
imageConvertTo (nil) Convert all images to specified format (must be an a format supported by Hugo; “webp” requires Hugo Extended)
imageImageSizes [“480”, “720”, “1080”, “1280”, “1600”, “2048”] Sizes (widths) of responsive image to generate
singleSize false (when true overrides default imageImagesSizes to “<image-width>x<image-height>”]) Only generate one size of image
imageConvertMethod Resize Set method for resize/crop of image, from [ Fit | GrowFit | Fill | Resize ]

For all image shortcodes

Param Default Description
imageLoading (nil) Default value of the ’loading=’ attribute for all images on the page (or site, for site-level)

For wrapped images

Param Default Description
imageLinkFull (nil) Link in which to wrap image if not provided by shortcode or partial (always applies to markdown images) Note 12
imageAddWrapper (nil) Element in which to wrap image if not provided by shortcode or partial (always applies to markdown images)
imageAddClass (nil) Classes (space separated string) to add to wrapper element or img element if no image wrapper
imageAltAsCaption false Use alt text as caption when using image wrapper (unless caption specified)
imageSizesAttr 80vw For responsive images the default “sizes=” attribute
imageFullSize true generate full sized image
imageThumbnails false Whether or not to generate thumbnail images
imageThumbnailSizes [“180”, “360”, “512”] Default image sizes (widths) to generate when generating thumbnails
imageThumbnailWidth 512 Width of ‘base’ thumbnail
imageThumbnailHeight (based on thumbnail width and aspect ratio) Height of ‘base’ thumbnail
imageThumbnailSizesAttr 20vw For thumbnail images the default “sizes=” attribute
imageMinThumbnailViewport 768px Minimum viewport for which to generate thumbnails

‘alt’ text from one of:

’title’ from one of:

For Markdown images

Param Default Description
imageMarkdownAddWrapper false If true add a wrapper (e.g. figure or div) around Markdown images (either imageMarkdownClass or imageAddClass)
imageMarkdownClass (none) Class to add to Markdown images
imageMarkdownLinkClass (none) Class to add to links wrapped around Markdown images
imageMarkdownOverlayImage (none) Map with src, x, and y for image, and x, y position to overlay ‘src’ on the main image
imageMarkdownOverlayText (none) Slice of maps with text, opts (which is a map, see Hugo docs) which specifies text to overlay over an image and the options (color, size, etc).

Examples

Test image #1

Source #1

https://github.com/danielfdickinson/image-handling-mod-hugo-dfd/blob/main/exampleSite/content/post/testimage1/index.md

CSS #1

Which uses the above CSS and imageConvertTo = "webp" in config.toml

Result #1

Image shows three different styling variations on a screenshot of a website

Test image #2

Source #2

https://github.com/danielfdickinson/image-handling-mod-hugo-dfd/blob/main/exampleSite/content/post/testimage2/index.md

CSS #2

Which uses the above CSS and imageConvertTo = "webp" in config.toml

Result #2

Image shows four different styling variations on a screenshot of a website

Test image #3

Source #3

https://github.com/danielfdickinson/image-handling-mod-hugo-dfd/blob/main/exampleSite/content/post/testimage3/index.md

CSS #3

Which uses the above CSS and imageConvertTo = "webp" in config.toml

Result #3

Image shows four different styling variations on a screenshot of a website

Test thumbnails #1

Source #4

https://github.com/danielfdickinson/image-handling-mod-hugo-dfd/blob/main/exampleSite/content/post/test-thumbnails-1/index.md

CSS #4

Which uses the above CSS and imageConvertTo = "webp" in config.toml

Result #4

Image shows three image thumbnails in a row (with large amounts space between them)

Test thumbnails #2

Source #5

https://github.com/danielfdickinson/image-handling-mod-hugo-dfd/blob/main/exampleSite/content/post/test-thumbnails-2/index.md

CSS #5

Which uses the above CSS and imageConvertTo = "webp" in config.toml

Result #5

Image shows three image thumbnails in a row (with some space between them)

Endnotes

Note 1

Markdown content only

Note 2

Override of default ‘figure’ shortcode from Hugo core

Note 3

E.g. for blog/taxonomy/HTML sitemap/etc listings

Note 4

E.g. to webp

Note 5

Sizes attribute and sizes of images and/or alternate images based on media queries

Note 6

E.g. single image/size; useful if all you want is image conversion or just the wrapper functionality

Note 7

NB You can only use subdirectories with leaf bundles. For branch bundles the image must be in the same directory as the _index.md

Note 8

This allows using subdirectories under assets (e.g. assets/path/to/screenshot.png which would render to /path/to/screenshot.png).

Note 9

E.g. if you place the image under static

Note 10

But doesn’t have to be, and can be optionally wrapped in <figure>, <span>, or <div>.

Note 11

When using Markdown, if you add links to the full image and wrap the image in a (Markdown) link, the wrapping link will be ignored. Fixing that requires using a link-render-hook such as provided by DFDs Hugo link handling module

Contributions welcome

If your issue can’t be found when searching both open and closed issues, please add it!

Please check open issues on danielfdickinson/image-handling-mod-hugo-dfd for enhancements and bugs that you would like resolved, write the fix, and submit a pull request!

As well, documentation improvements are always handy.

Thank you, and I hope you find this repository useful.

Support and general questions

Please use GitHub Discussions for support and general questions.