zola icon indicating copy to clipboard operation
zola copied to clipboard

Can't get directory path to collocated assets when using YYYY-MM-DD_ page prefix

Open zdenek-crha opened this issue 4 years ago • 16 comments

Bug Report

Environment

Zola version: 0.8.0 Features used:

  • shortcode
  • collocated assets for page
  • YYYY-MM-DD_ prefix for page
  • resize_image() function

Setup

Directory structure like this:

content/section/2000-01-01_page/index.md
content/section/2000-01-01_page/image1.jpg
content/section/2000-01-01_page/image2.jpg

Attempt to create shortcode that would convert this (in index.md):

{{ render_image(path="image1.jpg", width=100, height=200) }}

Into this:

<div class="image">
<a href="/section/page/image1.jpg"><img src="static/processed_images/foo.jpg"></a>
</div>

Expected Behavior

I've expected that when I pass relative asset name to shortcode, I can use page from Tera context to compute both:

  • path to image source to pass into resize_image()
  • path to deployed image to pass into link

Current Behavior

The page.path points to path used in public directory (section/page/ - ie without prefix). It can't be used to construct path for asset source location needed by resize_image().

The page.relative_path points section/2000-01-01_page/index.md file in correct - directory. But points to file not directory and can't be used for computing source path for render_image()

Note: May be it could be use by sequence of split, remove last element, join, ... operations, but I would not consider that very user friendly, especially for beginners :-)

Proposed solution

I can see two solutions:

  1. Add page.relative_dir that would point to post directory (similar to page.relative_path)
  2. Add dirname, basename, file_path filters to Tera to allow dissection and concatenation of paths

Personally, I find the second approach more desirable as it would benefit to Tera too and would be usable in wider range of applications, instead of fixing just one corner-case

Workaround

I've resorted into passing directory and file into shortcode separately:

{{ render_image(dir="section/2000-01-01_page", "file="image1.jpg", width=100, height=200) }}

And shortcode:

<div>
    {% set uri  = page.permalink ~ "/" ~ file %}
    {% set path = dir ~ "/" ~ file %}
    <a href="{{ uri }}"><img src="{{ resize_image(path=path, ....) }}" /></a>
</div>

I don't like it much, because it forces me to hard-code page location in repository into index.md, which imho, negates some of the benefits of asset collocation - it will be harder to move pages around without extensive editing and breaking stuff.

zdenek-crha avatar Aug 27 '19 13:08 zdenek-crha

I've played with zola bit more yesterday and attempted to use gallery rendering snippet. The <a href={{ get_url(asset) }}>...</a> generates invalid links when assets are coming from page with YYYY-MM-DD date prefix.

I'm not sure it should be in this issue or if it warrants separate issue though.

zdenek-crha avatar Aug 28 '19 05:08 zdenek-crha

Thanks for the bug reports! I'll have a look asap, unless someone beats me to it

Keats avatar Aug 28 '19 07:08 Keats

I'm converting old middleman site into zola and I love it so far. There are some rough edges and I will report more bugs once I have bit more time.

I'm very new to Rust and not confident I can help with fixes, but reporting bugs I can do :-)

zdenek-crha avatar Aug 28 '19 07:08 zdenek-crha

I'm converting old middleman site into zola and I love it so far. There are some rough edges and I will report more bugs once I have bit more time.

Thanks! Is your site open-source by any chance? Or just a stripped down version with just the page/shortcodes needed for those issues so it's quicker to fix.

Keats avatar Aug 28 '19 15:08 Keats

I'm afraid it is not open-source site. But I will create minimal reproduction site to attach to the issue. Hopefully I will some time to do that tomorrow.

zdenek-crha avatar Aug 28 '19 18:08 zdenek-crha

Here is a site for issue reproduction. Writing that up together, I realized that I've actually run into 2 separate issues:

  • get_url() does not work for page assets
  • it is not possible to get path to page directory in content directory tree

Both are (hopefully) explained in the test site itself. If there are any questions or need for clarification, let me know and I will do my best.

issue_reproduction_site.zip

zdenek-crha avatar Aug 28 '19 20:08 zdenek-crha

get_url() does not work for page assets

That's expected, it only works for internal links & static assets. I don't see how to make it work for page assets short of adding another parameter.

Thanks for the reproduction!

Keats avatar Aug 29 '19 14:08 Keats

Thanks again for the very detailed reproduction! Both issue stems from the fact that page.assets are the paths from the filesystem rather than the output site as they need to refer to the filesystem for the resize_image function. I didn't think of putting links to the assets outside of the markdown so that's why there's nothing builtin. I'll think about that a bit, but it isn't a bug.

Keats avatar Aug 29 '19 20:08 Keats

Note: May be it could be use by sequence of split, remove last element, join, ... operations, but I would not consider that very user friendly, especially for beginners :-)

That's what I ended up doing:

{% if page %}
  {% set relative_path = page.relative_path | split(pat="/") -%}
{% else %}
  {% set relative_path = "./" ~ section.relative_path | split(pat="/") -%}
{% endif %}
{% set relative_path = relative_path | slice(end=relative_path | length - 1) | join(sep="/") -%}
{% set relative_path = relative_path ~ "/" ~ src -%}
{% set src = resize_image(path=relative_path, width=resize_w, quality=resize_q, op="fit_width") -%}

It works, but is certainly not an elegant solution.

TjeuKayim avatar Oct 04 '19 18:10 TjeuKayim

@Keats if I understand right you're positive it's not feasible to upgrade get_url() to support collocated assets as well?

If that's the case, would it maybe make sense to make the assets array contain tuples/structs with a disk path as one element and the URL corresponding to that path in the other element?

vojtechkral avatar Jul 02 '20 07:07 vojtechkral

It would be feasible, it just needs to breaking changes. It's case where we have to think it through, part of #977

Keats avatar Jul 02 '20 07:07 Keats

I think it's fixed in 0.14? You can re-open the issue if it isn't.

Keats avatar Jul 19 '21 19:07 Keats

@Keats Doesn't look like its fixed in 0.14.1; get_url still has the datestamp in the URL it generates.

ColonelThirtyTwo avatar Sep 21 '21 21:09 ColonelThirtyTwo

This bug is still present in v0.15.2 :(

timharek avatar Dec 25 '21 22:12 timharek

Can someone make a PR for that? At least a failing test.

Keats avatar Dec 26 '21 22:12 Keats

In 0.15.3 get_url still doesn't work for assets when a page has a custom slug. Please fix it.

biodranik avatar Feb 06 '22 23:02 biodranik

Ran into this today, the cleanest possible workaround I find:

{% set path = page.relative_path | split(pat="/") | slice(end=-1) | join(sep="/") %}
{% set thumbnail = resize_image(path=path ~ "/" ~ src, width=size, op="fit_width", format="jpg") %}

bitinn avatar Jan 20 '23 04:01 bitinn

Zola next version gets a colocated_path pointing to the folder on disk when a page is colocated, no need to split/slice anymore.

Keats avatar Feb 11 '23 23:02 Keats

I'm not sure why this issue is closed, as it does not appear to have a solution:

  • get_url still does not return the actual output URL of colocated files, the @ prefix results in an error
  • colocated_path is only available for pages and not sections, so it is an incomplete workaround as it cannot be used universally with a simple string replacement

In my case, I'm trying to use the assets array to embed a few images via templates or shortcodes, but I can't refer to the original/source file in the output HTML. For my current project, I don't need dates in file names (it's actually not a blog so none of the content is dated), but I do prefer to use underscores over hyphens in my source directory structure, though I can put up with the inconvenience in the meantime.

I don't think get_url really needs to be changed for my use-case, I would be happy with the following:

  • an analogue to the existing assets array with the unprefixed file names (this also makes it easier to do pattern matching on file names only)
  • making colocated_path available for sections

That said, letting the existing @ prefix resolve output paths correctly with get_url would still be useful.

9ary avatar Sep 01 '23 15:09 9ary