getkirby / kirby

Kirby's core application folder
https://getkirby.com
Other
1.27k stars 167 forks source link

Kirby Blocks can't use field info as label #3661

Closed dgsiegel closed 3 years ago

dgsiegel commented 3 years ago

Describe the bug

With Kirby Builder I had a field set up like this:

name: Hero Image
label: Hero Image - {{image.0.filename}}

fields:
  image:
    label: Image
    type: files
    image:
      ratio: 3/1
      cover: false
    max: 1

The label was showing the filename of the first image.

With Kirby Blocks I use this field setup:

name: Hero Image
label: 'Foo {{image.0.filename}}'
preview: fields
wysiwyg: true
icon: image

fields:
  image:
    label: Image
    type: files
    image:
      ratio: 3/1
      cover: false
    max: 1

However the label just shows as Foo …

To Reproduce
Steps to reproduce the behavior:

  1. Use the above field definition as a block
  2. Add the block
  3. Look at the label

Expected behavior
I would expect to be able to select all field properties

Screenshots
Screenshot from 2021-09-01 23-37-04

Kirby Version
3.5.7.1

Additional context
Interestingly, using only '{{image}}' as label results in [object Object]

afbora commented 3 years ago

Kirby builder plugin uses Mustache and Mustache has such a feature. But AFAIK in Kirby Vue template parser there is no possibility to access inside the array.

https://github.com/getkirby/kirby/blob/3.6.0-alpha.4/panel/src/helpers/string.js#L80-L102

lukasbestle commented 3 years ago

Our frontend template implementation doesn't support deep templates at all at the moment. It can only access properties on the top level as well as the special case array.count/array.length.

For deep templates we'd need an entirely different implementation like our backend one (which does support array indices but is overall much more complex).

distantnative commented 3 years ago

We were trying to do a more sophisticated implementation in the first case. But lots of edge cases to cover which is why we went for top-level keys and counts only.

lukasbestle commented 3 years ago

@dgsiegel I think the best way to implement the preview with the filename is a custom block preview (Vue component). I know it's not as simple as a query in the block blueprint, but on the other hand it allows you to customize the display even further. Or you can use the built-in image block that's already very visual.

afbora commented 3 years ago

How about using eval() to accessing all levels?

https://jsfiddle.net/byybora/51vh6Lfo/

lukasbestle commented 3 years ago

There's a saying: eval is evil. Even if the query is entirely controlled by the developer of the site, there could be edge cases where attackers can end up running arbitrary code in the frontend. I mean no one stops you from writing a query like image[0].filename;somethingMalicious().

afbora commented 3 years ago

There's a saying: eval is evil

🙈 💯

Now we are trying to reach the result by looping the data values. What if we tried to get the value by splitting the query template by dot notation and running self function as recursion?

lukasbestle commented 3 years ago

That's pretty much what our backend Query implementation does. And it's the way to go if we want that functionality. But the question is if we want that complexity in the frontend (see Nico's comment).

afbora commented 3 years ago

Yes, I meant the same backend Query does. If doing this is complex or risky, we can improve access to the maximum first-level indexes of arrays with regex, just like we did with count and length. Or if there is no easier solution, we can leave it as unsolvable 🤷‍♂️

lukasbestle commented 3 years ago

I don't think it would be risky, it's just complex to implement correctly. We could 1:1 clone the backend code, don't know if that's viable given that the RegEx support in JS slightly differs from the one in PHP.

afbora commented 3 years ago

If you consider backend Str::template() functionality in frontend I can try to convert it to JS. Of course, if Nico thinks positively.

distantnative commented 3 years ago

If we can manage, I see no argument against a more powerful string template JS helper.

afbora commented 3 years ago

First try and seems works great 🎉 Need your expert touch.

https://jsfiddle.net/byybora/vtm0yanL/

* An improvement done few seconds ago.

bastianallgeier commented 3 years ago

@afbora that looks very promising and still is very simple. Nice!

distantnative commented 3 years ago

That looks great indeed!

bastianallgeier commented 3 years ago