Filtering multiple structure fields

I’m pulling data from two structure fields (videos and products) and have merged it into an episodes structure field per Fetch query from parent page

Here’s the episodes blueprint:

fields:
  gkm_episodes:
  label: Current Episodes
  type: structure
  style: table
  modalsize: large
  fields:
    name:
      label: Episode Title
      type: text

    episode:
      label: Associated Video
      type: episodes

    product:
      label: Associated Product
      type: products

    airdate:
      label: Air Date
      type: date
      format: MM/DD/YYYY

For each of the episodes, I’m trying to find the associated video and products. I tried something like this, but it isn’t filtering through the products structure to match the episode product with the product title.

<?php $episodes = $pages->find('episodes')->gkm_episodes()->toStructure() ?>
<?php $videos = $pages->find('videos')->gkm_videos()->toStructure() ?>
<?php $products = $pages->find('products')->gkm_products()->toStructure() ?>

<?php foreach($episodes as $episode): ?>

   <?php $productID = $episode->product(); ?>
   <?php $product = $products->filterBy('name', $productID); ?>
   
   <?= $product->name(); ?>

<?php endforeach ?>

Any ideas?

I’m not quite sure I understand what you are trying to achieve here.

A little while ago, I posted a little plugin to filter by structure field values in this post, maybe it helps: New Kirby Related Pages plugin

Sorry – maybe this will help. Here’s the products blueprint.

title: Products
icon: cube
fields:
  gkm_products:
    label: Products
    type: structure
    entry: >
      <strong>{{name}}</strong>
    modalsize: large
    fields:
      name:
        label: Product Title
        type: text
      cover:
        label: Product Image
        type: image
        width: 1/2
      link:
        label: Store Link
        type: url
        width: 1/2
     description:
        label: Product Description
        type: textarea
     contents:
        label: Product Contents
        type: textarea

So for each of the episodes, I’ve designated a specific product. What I’m trying to do is filter through the gkm_products structure, finding the matching product, and then have access to the rest of the collection for that product:

$product->name();
$product->cover();

I have previously accomplished this by matching the page uid like so:

<?php $productID = $episode->product(); ?>
<?php $product = page('products')->children()->findBy('uid', $productID); ?>

But I ended up making a lot of pages for data that would be better stored and accessed in a structure.

I see; I think findBy() will do the job here:

<?php $episodes = $pages->find('episodes')->gkm_episodes()->toStructure() ?>
<?php $videos = $pages->find('videos')->gkm_videos()->toStructure() ?>
<?php $products = $pages->find('products')->gkm_products()->toStructure() ?>

<?php foreach($episodes as $episode): ?>

   <?php $productID = $episode->product(); ?>
   <?php $product = $products->findBy('name', $productID); ?>
   
   <?= $product->name(); ?>

<?php endforeach ?>

I’ve tried that and I get:
Call to a member function name() on null.

Hm, there seems to be some sort of issue with the value returned from $episode->product(). It works if you either trim() it or use the value() method:

<?php $episodes = $pages->find('episodes')->gkm_episodes()->toStructure() ?>
<?php $videos = $pages->find('videos')->gkm_videos()->toStructure() ?>
<?php $products = $pages->find('products')->gkm_products()->toStructure() ?>

<?php foreach($episodes as $episode): ?>

   <?php $productID = $episode->product()->value(); ?>
   <?php $product = $products->findBy('name', $productID); ?>
   
   <?= $product->name(); ?>

<?php endforeach ?>

In any case, you should use an if statement to check if $product() exists before calling a method on it.

Thanks! That worked. :+1: