Specific entry in a structure field

Hey there.

Sorry if this is obvious but im not PHP expert and reasonably new to Kirby.

I am using a structure field to hold information for 20 items. I need to be able to add these to some inline javascript on the page. I cannot use a for each loop as per the examples - i need to tell kirby to get a specific field from a specific entry in the structure field. How do i do this please?

Blueprint looks like this:

 winerymap:
    label: Contact Address
    type: structure
    entry: >
      {{winerylogo}}<br />
      {{wineryname}}<br />
      {{winerydesc}}<br />
      {{winerylink}}<br />
    fields:
      winerylogo:
        label: Winery Logo
        type: image
      wineryname:
        label: Winery name
        type:  text
      winerydesc:
        label: Winery Description
        type:  text
      wineryname:
        label: Winery name
        type:  url

So i need to get kirby to pull the fourth item in the structured field, for example, and then output the winerydesc field for that fourth entry. I hope that makes sense. How do i do this please?

Thank you.

Not tested but this could work:

$item = $page->winerymap()->toStructure()->nth(4);
echo $item->winerydesc();
1 Like

Thanks, I tried something similar and my attempt and your suggestion results in:

Fatal error: Call to a member function winerydesc() on boolean

:frowning:

Any other ideas?

Try this:

// n is your item number
$n = 4;
$wineries = $page->winerymap()->yaml();
echo $wineries[$n]['winerydesc'];

Awesome!

Thanks, that did the trick and I’m grateful but out of curiosity, is there a way to do it using toStructure() since this gives much greater flexibility to do other stuff since its a full blown collection?

I tested my code in my install and had no problem with it. The important thing is that the item you are calling must exist, if it doesn’t, you get the error message that you got.

Nevertheless, while toStructure() has several advantages, it also has some drawbacks, as e.g. shuffling does currently not work.

I think it may have been my fault. I just discovered PHP numbers things from 0 rather then 1. I was trying to pull the second entry by setting the nth to 2 which should have been set to 1 to get the second. Sorry!

I was like “I have no clue why this code is not working” but didn’t think to try it myself! Duh! Good job :wink:

It might make sense to count the number of items first and then apply a number only if the number of items is equal or greater than the total number of items.

Thanks for the idea :slight_smile:

Another way would be to get the item by value, e.g.:

$item = $winerymap->toStructure()->findBy('wineryname', 'something');

Same thing as with the nth() approach: You always need to check if the item is valid and provide a fallback in case it couldn’t be found.

@lukasbestle: What happens if the value is not unique? Will findBy() always stop at the first item it finds?

Yep. It’s like filterBy()->first(), but without the overhead.

2 Likes

all provided solutions are great, but what overhead of findBy() are you thinking of here I wonder?

sorry for bumping

Not overhead of findBy() but of filterBy(). So use findBy() if you only want to get a single item.