I know the title is not very good but let me try and explain what I’m trying to do: I have a structure field where I want to define all kinds of topics:
topics:
label: Topics
type: structure
fields:
title:
label: Text
type: text
info:
label: Info
type: writer
Down below I have another structure field where sections are created and in each section I want to be able to use a multiselect field to select the relevant topics:
topics:
label: Topics
type: multiselect
options:
type: query
query: page.topics.toStructure
text: "{{ item.title }}"
value: "{{ item.title }} {{ item.info }}"
So far so good, however on my page I would like to use the title and info field from the topics structure seperately like below so that I can create an accordion or anything similar
<?php foreach($solution->topics()->split(',') as $topic) : ?>
<h2><?= $topic->title() ?></h2>
<p><?= $topic->info()->inline() ?></p>
<?php endforeach; ?>
What would be the best way to achieve this? $topic
returns a single string containing {{ item.title }} {{ item.info }}
in the way I’ve set it up now.
I think you have two options here:
- only store the title as value, and get the info from the main topics structure using
findBy()
- Store info and title like you do now, but use a separator (e.g. a pipe character, a semicolon or whatever, in any case some character not contained in text or info) to separate title from info, then split the value the by this character.
I’d even go one step further and use a third key field in the main structure, and store this key as value in the fields that query this structure. The key should not change. That way, you can modify typos or so in the title and info fields in the main structure, and these changes would be reflected in the referencing fields.
Or better still, instead of the structure field for the topics, consider using a blocks field with a custom block type. Blocks come with ids out of the box and you could then store these ids, and find the related block by this id.
The custom block seems te right option here. I’ve added the field like this:
topics:
label: Topics
type: blocks
fieldsets:
- topic
and added a custom topic block:
name: topic
fields:
title:
label: Title
type: text
info:
label: info
type: writer
My multiselectfield looks like this
topics:
label: Topics
type: multiselect
options:
type: query
query: page.topics.toBlocks
text: " {{ item.title }}"
value: "{{ item.id }}"
So that I can get the ID of the selected topics like this:
<?php foreach($solution->topics()->toBlocks() as $topicID) : ?>
<?= $topicID ?>
<?php endforeach; ?>
But how can I get the right topic? Something like
<?= $page->topics()->toBlocks()->findByKey($topicID)->title() ?>
Is not working. (I know the naming with the two topics is not ideal here). What should I do here?
Could you explain what you are trying to do here? What does $solution
refer to? We are at the multiselect now and from the value store there, you want to get the corresponding block.
So how do I get to the multiselect?
Then I can help you from there…
Yes sorry so the multiselect is also inside a structure field in a foreach loop above:
<?php foreach($page->solutions()->toStructure() as $solution): ?>
Ok, so you don’t want to loop through the blocks at that point but fetch the block with the given id(s).
<?php foreach($page->solutions()->toStructure() as $solution): ?>
<?php
// loop through all block ids stored in the topics field of the solution item
foreach($solution->topics()->split() as $topicId) {
// and foreach id, we want to find the corresponding block
$block = $page->topics()->toBlocks()->findBy('id', $topicId);
// if we have a block, echo its fields
if (!is_null($block) {
echo $block->title();
echo $block->info();
}
}
?>
<?php endforeach ?>
Thanks a lot!
Have a nice Sunday eve:)