Remove image from filter |first

Hello.

How to set a first image from page.media.images with any twig filter or other way, if it is different from other one defined in page.header.avatar?

Hypothetical example:

{% set image = page.media[page.header.primaryImage] ?: page.media.images|first(somefilter) %}

If the first image is equal to page.header.avatar, it should set another image.

@pmoreno, one solution might be to use a filter filter

{% set image = page.media.images[page.header.primaryImage] ?: page.media.images|filter((v, k) => k != page.header.avatar)|first %}

@b.da, I’m testing your solution with this code:

{% set avatar = page.media[page.header.avatarimage] %}
{% set images = page.media.images%}
{% set image = page.media[page.header.primaryImage] ?: images|filter(v => v != avatar)|first %}

On pages with the main image declared there is no problem, but on others any image is displayed.

I think I’m missing something.

Reference help:
https://github.com/twigphp/Twig/blob/3.x/doc/filters/filter.rst

@pmoreno, did you try first
|filter((v, k) => k != page.header.avatarimage)|first
i’ve tested on the Quark theme and it seems to work as it should

what do you mean by that?

HI @b.da.

I describe the current configuration (with Future2021 theme):
Example page: /blog/post-five/item.md

In md file I have three images (example):

media_order: '01.jpg,02.jpg, avatar.jpg'
avatarImage: avatar.jpg

primaryImage is not defined.

Expected solution: The page should show 01 or 02 image, excluding avatar image.

With {% set image = page.media[page.header.primaryImage] ?: page.media.images|filter((v, k) => k != page.header.avatarImage)|first %}
in pages with primaryImage, this is displayed, in pages without primaryImage, any image is displayed. (I’ve attached some screenshots)

Post Five without image:

Post One with primaryImage defined:

ok, i’ve tested on a fresh installation of Futura 2021 + latest grav, and change one line (image set), to your last example: {% set image = page.media[page.header.primaryImage] ?: page.media.images|filter((v, k) => k != page.header.avatarImage)|first %}
and everything works fine, so yep

1 Like

Okay. I already know what’s going on. If I upload .jpg or .png images everything works fine with your code, but if I upload .svg images it doesn’t.

However, I can load .svg images in page.header.primaryImage (with pagemediaselect blueprint)

At the moment, I don’t know how to correct this.
Thanks, so much for your help.

@pmoreno, i’ll tell you more, the original code won’t work with svg files either, because page.media.images array doesn’t contains svg files.

@b.da, following this Github thread, in which @rhuk, explains how to get SVG from page.media, I have made some code modifications that allow to get both images (jpg, png, etc) and SVG files. I think it’s not a well optimized code, but it works.
I have used a double ternary operator for it.

{% set avatarImage = page.media[page.header.avatarImage].url|e %}
{% set avatar = page.header.avatarImage %}
{% set primaryImage = page.media[page.header.primaryImage] %}
{% set image_media = page.media.images|filter((v, k) => k != avatar)|first %}
{% set image_file = page.media.files|filter((v, k) => k != avatar)|first %}
{% set image = primaryImage ?: (image_media ?: image_file) %}

I don’t know if anyone in this forum can think of a way to optimize this code or do it in another way.

@pmoreno, ok lets play to the end :rofl:

first, if i may say a few remarks:
  1. your code has broken logic:

    • if primaryImage isn’t defined your image var will be set to the first el in page.media.images (not the first img or svg)
    • page.media.files array could contains .pdf .docx etc.
  2. so why are you asking questions here :person_shrugging:

  3. It would save some time, if you specified the need for svg support, feels like you came up with new requirements on the go.

anyway, one of the possible solution in one line )

{% set image = page.media[page.header.primaryImage] ?: page.media.all|filter((v, k) => k != page.header.avatarImage and (v.type == 'image' or v.type == 'vector'))|first %}
1 Like

Hi @b.da, first of all I want to thank you for your help. The final code works great and is what I wanted.

Second, I want to apologize for not asking the right questions. :sweat_smile:

It is true that in this post I have asked about the use of SVG as one more requirement, but I thought that when performing a search in the images of a page, it would show all the image files. I’ve already seen that SVGs are not treated as images, which is why I took advantage of the current query to solve the problem with SVGs.

Thanks again. :+1:

1 Like