zola
zola copied to clipboard
Don't use absolute URL's as resize_image's output
Bug Report
Environment
Zola version: 0.12
Expected Behavior
resize_image
would output URLs that work wherever the site happens to be deployed at.
Current Behavior
resize_image
outputs URLs that have the base_url
hardcoded in, making it impossible to deploy into a preview/staging environment that has a different domain name, without the images breaking.
Step to reproduce
- Have a simple build that has
<img src="{{ resize_image(path="some_image.jpg", width=600, height=600, op='fill') | safe }}">
in some file in contents. - Deploy it to a different environment than what
base_url
would suggest. - Images break.
Some possible ways to resolve this backwards-compatibly:
- Have the current behaviour as the default, and have an additional parameter that changes the setting.
- Introduce another function that behaves differently.
- Have a opt-in setting in
config.toml
.
I'm running into this limitation myself. I'd love it if resize_image
returned a struct (or whatever the Rust equivalent is) containing a variety of information, including things like:
- Width
- Height
- Image type/mimetype
- Size
- Maybe hash/checksum, if it seems useful...
For instance, if the width/height were returned properly, then we wouldn't need to do any kind of song and dance with get_image_metadata
like #1099 just to generate an <img>
tag with proper width
and height
attributes.
Yep it would be a nice improvement. I don't know if it's going to make it to 0.14 though - already a lot of changes in there going on for i18n
Completely fair, I can work around the above limitations for now, as long as this is on the horizon for future work.
Thanks for your hard work on Zola!
There's been a few change to resize_image
in 0.14 so the original issue should be fixed, see the return output of https://www.getzola.org/documentation/content/image-processing/
Has this issue really been addressed by the changes in 0.14? As far as I can tell, the returned object contains two relevant fields: url
, which is the full absolute URL (same behavior as before), and static_path
, which is the filesystem path relative to the website directory (i.e. starts with static/
).
I think what would be needed to address this issue is a field with an absolute URL without explicit domain name or protocol, so /processed_images/...
. Am I misunderstanding something or should this issue be re-opened?
Note to anyone looking for a workaround: Tera has the trim_start_matches
filter. This seems to work: {{ image.static_path | trim_start_matches(pat="static") }}
It could be added or the workaround with the Tera filters documented
In an attempt to not make this a +1-style comment..
I agree that this is a feature that should be supported without workarounds. I also don't think we need to break backwards compatibility to allow for this use case.
just to establish some terms here:
- URL: https://en.wikipedia.org/wiki/URL
- URL path: the path component of a URL
- file path: a file path that does not need to comply to the URL specification.
url
as made evident by its name is a URL. this does not need to change. it is the public URL to the image resource.
static_path
should just be a file path on the filesystem. this also does not need to change. it is the file path to the image resource under static/
.
I think what we can add here is an additional attribute public_path
which is the path component of a valid url
.
the name doesn't need to be public_path
. it can also be something like url_path
to make its provenance more obvious.
I've crudely implemented the above: https://github.com/syphoxy/zola/commit/50f68efc13d61b84c653d784c82db1b8ccf05871
looking for feedback.
I think you can just apply the Tera workaround above in the codebase directly using https://doc.rust-lang.org/std/primitive.str.html#method.trim_start_matches with the base_url as a pattern?
that really strikes me as a hack as opposed to properly managing URLs and paths. it would also inextricably link the static asset location with the public asset location forever.
the more I think about this the more I realize that maybe the original suggestion, a global flag in config.toml
, makes more sense.
just to clarify my use case:
my original use case was that I wanted to load the static site generated from disk but realizing it used URLs instead of relative paths, I reached for something like darkhttpd for a quick solution. that works but lots of things broke because it was using my FQDN and not localhost:8080 (or similar).
not great (my idea): a change like this where I can instruct resize_image to give me a full path, instead of a URL, does fix this but it also implies that a change like this would infect every aspect of Zola that generates a URL in the future. do we now provide url
and url_path
for everything? it would also imply that my templates inform how my site can be deployed.
if we viewed it as 2 scenarios:
- I want to deploy to
https://base.url/
- I want to deploy to a local filesystem and view it in the browser
for case 1 you can always set the --base-url
parameter at build time and have any arbitrary domain accomodated without changing any code. this would solve most people's concerns in this thread albeit trading the problem for space (you would need to generate N copies of a site for N base URLs) and you'd need to have a builder to achieve it.
for case 2 there's really nothing to be done right now except hardcode it in your templates.