$page->children()->filterBy('template', 'template_name')

I’m trying to list partners and distributors. Both are in subfolders with different templates (partner and distributor). The blueprint is working. The panel does exactly what it is supposed to do. Adding a new distributor is creating a new folder with the distributor.txt etc.

Trying to get only the partners or distributors by filtering for the template doesn’t return anything. If I just do $page->children() I get everything.

Running out of ideas…



Does the template actually exist in /site/templates? If not, try filtering by intendedTemplate instead.

A small request: When posting code snippets, it usually makes much more sense to post it as code wrapped between three backticks on a separate line before and after the code. Users trying to help can then copy/paste the stuff and make changes where needed instead of having to type everything. Thank you!

1 Like

Thanks Sonja!

Yes, the template exists.

But I’ve just noticed something unusual. I checked the about-us.en.txt and it did not list the distributors that are showing in the panel. I deleted the about-us.en.txt (not the about-us.yml) and refreshed the panel. Now I’m getting the message that there is no blueprint. And it created a default.en.txt in the ‘about-us’ page folder. Very strange. I checked for typos, none.

Why should the distributors be listed in the about-us.en.txt file? Children are not listed in that file, they exists as subfolders of the page.

If $page->children() without the filter returns all children of the about page, then $page->children()->filterBy('template', 'distributor') should returns only the ones that use the distributor blueprint.

Why should the distributors be listed in the about-us.en.txt file? Children are not listed in that file, they exists as subfolders of the page.

This is what I meant with listing the distributors. But adding new distributors in the panel, doesn’t add them to the text file. I created the file manually. As mentioned, its showing correctly in the panel.

----

Partner:

- about-us/blue_ocean
- about-us/adesva
- about-us/bio_treat_center
- about-us/CeRSAA
- about-us/compas_agro
- about-us/Laimburg
- about-us/rgbg
- about-us/wageningen_university

----

Distributor-headline: Distributors & Partners

----

Distributor:

- about-us/Biogard

I think you are mixing up two things here:

  • a pages section: is used to create new pages (and shows them all in the Panel), but doesn’t store stuff in the text file: Pages section | Kirby CMS
  • a pages field: is used to select pages from a given set (works like a select/multiselect) field. It stores the selected values in the text files (but you cannot add new pages through pages field): Pages | Kirby CMS

So $page->children() returns the subpages of the current pages.

Whereas if you want to get pages stored in a field, you would get them like this:

$selectedPages = $page->partner()->toPages();
foreach ($selectedPages as $p) {
 // code here
}

But I wonder if you really want a pages field here… That would only make sense if you wanted to select only a few of the existing pages.

You’re right, I’ve been mixing it up. Corrected everything.

Hey Sonja,

I can’t see a difference to the code you provided, except “mine doesn’t work”. Any other idea?

<div class="distributor-grid">
       <?php foreach ($page->children()->filterBy('template'  ,'distributor') as $item ):?>
       <div class="distributor">
                  <?php if ($image = $item->logo()->toFile() ) : ?>
                           <img src="<?= $image->bw()->url() ?>" class="distributor-logo">
                  <?php endif; ?>
                            <h2><?= $item->country() ?></h2>
                            <h2><?= $item->name() ?></h2>
                            <h5><?= $item->url() ?></h5>
                            <h5><?= $item->description() ?></h5>
                            <h5><?= $item->company_country() ?></h5>
                       </div>
		<?php endforeach ?>
       </div>
</div>

I can’t see anything wrong with the logic, assuming you are using this in the about-us.php template.

If it doesn’t work, then either the distributor template does not exist or Kirby doesn’t recognize the distributor template as being the one to be used for the subpages.

You can test this by doing the loop without the filter and printing the template:

<div class="distributor-grid">
       <?php foreach ($page->children() as $item ):?>
         <?= $item->template()->name() . '<br>' ?>   
       <?php endforeach ?>
</div>

If the output of this is default instead of distributor or partner, then I wonder if your languages are not defined?

On a side note, your markup is not semantically correct.

Headings (h1to h6) should never be used to style the size of text, but only to structure of your content in a meaningful way. Use CSS styles to style your font-sizes.

You’re right, the output is only “default”.

templates/about-us.php is there and working. languages/en.php etc. are in place and working.

No distributor template? That is correct. But I didn’t know I need one. I didn’t create a template for the individual reference only the references overview ) templates/references.php. Similar to what I’m trying to achieve here and it works just fine.

Thanks for the markup hint. :wink:

No, you don’t need one if you don’t want to output distributors as pages. However, as I already mentioned above, then you have to filter by the intendedTemplate:

<div class="distributor-grid">
       <?php foreach ($page->children()->filterBy('intendedTemplate'  ,'distributor') as $item ):?>
       <div class="distributor">
                  <?php if ($image = $item->logo()->toFile() ) : ?>
                           <img src="<?= $image->bw()->url() ?>" class="distributor-logo">
                  <?php endif; ?>
                            <h2><?= $item->country() ?></h2>
                            <h2><?= $item->name() ?></h2>
                            <h5><?= $item->url() ?></h5>
                            <h5><?= $item->description() ?></h5>
                            <h5><?= $item->company_country() ?></h5>
                       </div>
		<?php endforeach ?>
       </div>
</div>

The intendedTemplate is the template that would be used if it existed (determined by the content file name).

1 Like

Problem solved, lesson learned.

I didn’t know ‘intendedTemplate’ even existed, but I’m sure I’m never going to forget it again.

Thank You!