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 - #2 by texnixe

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: