This PR fixes the immediate bug (failing to load images when custom contentDir and/or siteDir paths are set), but does so in a way that's somewhat brittle. As it stands, we need to acquire a Hugo setting from within a template, which isn't generally advisable, but I haven't been able to find any other path to fixing this. I am 100% open to other ways to solve the issue.
Background
render-image.html uses a Hugo render hook to replace Hugo's default image rendering with a number of things, but the most relevant thing here is that it will load the image from the appropriate directory based on whether Page Bundles are being used.
If Page Bundles are set to true (either in the site params or in a post's front matter) then all images are loaded relative to the current post's directory within the site's contentDir. If Page Bundles are set to false, then all images are loaded relative to the site's staticDir. The latter is how things operated prior to #206, so this was meant as a way to prevent existing sites from breaking.
Right now, we need to know the value of a site's contentDir and staticDir in order to serve images with the correct path. (I believe this is also true when either directory is loaded using Hugo Modules.) The reason accessing site configuration variables is brittle is because the config file can be in a number of locations, with a number of file extensions. Settings can be changed at run-time using CLI flags. But without checking these settings, I don't know how we would know the correct path to an image in all of the following contexts:
within a post (e.g. via a Markdown render hook)
through a partial template (e.g. a featured image)
through a list template (e.g. a thumbnail on a post excerpt)
all of the above both with and without page bundles being used
So here is what this PR attempts to do:
Checks two common locations (including the one used by Hugo Clarity in exampleSite) for the config file, using toml, yaml and json formats.
Checks to see if contentDir and/or staticDir are set, and if so uses the values provided to load images.
If a value is not set for either of those, provides the default content and static paths that Hugo uses.
Again, this is brittle, but I can't figure out any other way to do this. Open to suggestions.
A few things I cleaned up while I was doing the above:
Paths are now joined correctly (eliminates possible double-slash concatenation).
Some fixes for external images that were overlooked in #267 are included here, e.g. using an external image as a thumbnail now works.
The same partial is used for both thumbnails and featured images, reducing duplication. Previously the only difference was some markup, which we can render conditionally, and classes, which we can pass to the partial from the parent.
render-image.html (the Markdown image render hook) and image.html (the partial) are identical files except for the first line. As far as I know there isn't a way to use the same file as both a render hook and a partial despite the code being the same, but if there is then duplication could be reduced even more.
Things that are unresolved:
If the config is placed somewhere else, this won't pick it up.
If contentDir or staticDir are changed at runtime, the wrong paths will be generated. I just don't know any way around that.
How to test this PR
Copy exampleSite, change the static directory to something else, then set staticDir in config.toml to that new directory name. Generate the site and go to http://localhost:1313/post/markdown-syntax/ to make sure the local image still loads. Go to http://localhost:1313 and make sure the thumbnail still loads.
Update the markdown-syntax.md post and add a featured image.
Test all of the preceding (Markdown image, thumbnail image, featured image) with an external image as well.
To test a custom contentDir, you'll have to change that directory, set usePageBundles to true in params.toml, then regenerate the site.
Checklist
Ensure you have checked off the following before submitting your PR.
This PR...
Summary
This PR fixes the immediate bug (failing to load images when custom
contentDir
and/orsiteDir
paths are set), but does so in a way that's somewhat brittle. As it stands, we need to acquire a Hugo setting from within a template, which isn't generally advisable, but I haven't been able to find any other path to fixing this. I am 100% open to other ways to solve the issue.Background
render-image.html
uses a Hugo render hook to replace Hugo's default image rendering with a number of things, but the most relevant thing here is that it will load the image from the appropriate directory based on whether Page Bundles are being used.If Page Bundles are set to
true
(either in the site params or in a post's front matter) then all images are loaded relative to the current post's directory within the site'scontentDir
. If Page Bundles are set tofalse
, then all images are loaded relative to the site'sstaticDir
. The latter is how things operated prior to #206, so this was meant as a way to prevent existing sites from breaking.contentDir
andstaticDir
can be specified in Hugo's general configuration settings. Note these are not the same as site variables (including site params) or page variables; in effect the configuration settings are a level above these. They are not designed to be accessible from templates. Nonetheless, there is a way.Right now, we need to know the value of a site's
contentDir
andstaticDir
in order to serve images with the correct path. (I believe this is also true when either directory is loaded using Hugo Modules.) The reason accessing site configuration variables is brittle is because theconfig
file can be in a number of locations, with a number of file extensions. Settings can be changed at run-time using CLI flags. But without checking these settings, I don't know how we would know the correct path to an image in all of the following contexts:So here is what this PR attempts to do:
exampleSite
) for theconfig
file, usingtoml
,yaml
andjson
formats.contentDir
and/orstaticDir
are set, and if so uses the values provided to load images.content
andstatic
paths that Hugo uses.Again, this is brittle, but I can't figure out any other way to do this. Open to suggestions.
A few things I cleaned up while I was doing the above:
render-image.html
(the Markdown image render hook) andimage.html
(the partial) are identical files except for the first line. As far as I know there isn't a way to use the same file as both a render hook and a partial despite the code being the same, but if there is then duplication could be reduced even more.Things that are unresolved:
config
is placed somewhere else, this won't pick it up.contentDir
orstaticDir
are changed at runtime, the wrong paths will be generated. I just don't know any way around that.How to test this PR
exampleSite
, change thestatic
directory to something else, then setstaticDir
inconfig.toml
to that new directory name. Generate the site and go to http://localhost:1313/post/markdown-syntax/ to make sure the local image still loads. Go to http://localhost:1313 and make sure the thumbnail still loads.markdown-syntax.md
post and add a featured image.contentDir
, you'll have to change that directory, setusePageBundles
totrue
inparams.toml
, then regenerate the site.Checklist
Ensure you have checked off the following before submitting your PR.