Function to check if a file exists

My use case is that I want to have a shortcode to create a <picture> element, but I want to only insert code for files that already exist (the rules for when I use webp or avif are not so easy to express in a static generator and I prefer to handle them separately).

get_file_metadata kind of works as a proxy, but avif support is flaky and I actually don’t care about the metadata, so only checking for the file would be more efficient.

1 Like

Interesting, it shouldn’t be too hard to add but I’m just wondering how many people need that though.

Probably it is a very obscure use-case. Sadly, AVIF support is broken in the image crate that zola uses to read the metadata, but I’ll try look into collaborating with that.

I’ve found the need for such a function a couple of times while adding/improving multilanguage support on my theme.

The last case was figuring out whether a page had translations to add hreflang tags to the header of the page.

I solved it by using load_data with required=false first. Not pretty, but it worked:

{# Check if the translated page or section exists #}
{%- set translation_exists = load_data(path=translated_filename, required=false) -%}

{# Get the page or section details #}
{%- if translation_exists -%}
    {%- if page.relative_path -%}
        {%- set translated_page = get_page(path=translated_filename, metadata_only=true) -%}
    {%- else -%}
        {%- set translated_page = get_section(path=translated_filename, metadata_only=true) -%}
    {%- endif -%}
{%- endif -%}

It would be nice, however, to have the optional required argument to get_section, get_page, and/or to get a function to check if a file exists.

I have a use case: I’m trying to set up a default header image for pages (that ends up in my open_graph previews). If the page or section has an image with the same path but .png|.jpg (components + some string concat is the best I’ve found for now. File search with the ability to either ignore extensions or give multiple options would be even better) get_url it, otherwise use the site default. Really I’d probably set page > section > config as fallbacks.

A basic error catching filter/ability to tell get_url to do warning only on this specific call only might be a broader category of thing that could be useful and would also cover this. I’ll probably do the load_data hack for now, but it’ll definitely make my template/shortcode a bit messier and do unnecessary processing.

ETA:
I guess I’ll make a macro to abstract that at least. Hmm, for images the get_image_metadata also accepts a required parameter, so maybe I grab that for making it not entirely an otherwise useless check. I guess if get_url had that param it’s make the whole issue mostly moot?

Kenzi

Here’s my current image version. I couldn’t get defined or anything else to make the ifs not choke on the get_image_metadata calls if I inline them.

{%- macro img_exists(path, default='') -%}
   {%- set png = get_image_metadata(path=path ~ '.png', allow_missing=true) -%}
   {%- set jpg = get_image_metadata(path=path ~ '.jpg', allow_missing=true) -%}
   {%- if png -%}
      {%- set path = path ~ '.png' -%}
   {%- elif jpg -%}
      {%- set path = path ~ '.jpg' -%}
   {%- else -%}
      {%- set path = default -%}
   {%- endif -%}
   {{-path-}}
{%- endmacro img_exists -%}