Forum

Thread tagged as: Question

Specify an item callback function in a collection?

Hi,

I'm using the code below to list items from a collection in my footer. I'm not sure why, but this part of the page is very slow to load. It takes 1.5 seconds.

The collection isn't particularly big, just 13 items. The template is fairly complicated though - about 20 fields, with a few repeaters.

Slow: Performance indicator, 1.6407


<?php perch_collection('Property developments', [ 'category' => 'developments/new-homes', 'template' =>'_property-developments/property-developments-footer-list.html', ]); ;?>

When I filter the collection like this, it loads quicker.

Much faster: Performance indicator, 0.0148

It'd be good to know why this is faster. Is it because it's filtering the output on a specific ID developmentName, rather than the entire collection?


<?php perch_collection('Property developments', [ 'category' => 'developments/new-homes', 'template' =>'_property-developments/property-developments-footer-list.html', 'filter' => 'developmentName', 'match' => 'eq', 'value' => 'Spring Gardens', ]); ;?>

I need the value to be dynamic, as there's multiple items in the category new homes

Will each help?

I feel like I need to use each as described in the docs: Specifying an item callback function. But I can't seem to get it work. The documentation just says: // process as necessary, then return the modified array An example in the docs would be really useful.

Stephen Meehan

Stephen Meehan 4 points

  • 11 months ago
Hussein Al Hammad

Hussein Al Hammad 103 points
Registered Developer

Hello Stephen,

If you need all the items in the collection, I don't see why you need to use filters. And I don't think the each option would help here.


If you're looking for an example using the each option, I wrote a blog post that explains how to use it to accomplish something else: https://grabapipit.com/blog/tags-in-post-listing

Hi Hussein,

Thanks for taking the time to look at this.

I got it working!

The Callback Functions with each page helped me with this.

<?php 

  $new_homes = perch_categories([
  'set' => 'developments',
  'template' => 'category--new-homes.html',
  'filter' => 'catPath',
  'match' => 'contains',
  'value' => 'developments/new-homes',
  'each'  =>  function($item) {
      $item['projects'] = perch_collection('Property developments',[
        'category' => $item['catPath'],
        'template' => '_property-developments/property-developments-footer-list.html'
      ],true);

      return $item;
    },
]);
  ;?>

perch_categories HTML template

<h6><perch:category id="catTitle" type="smarttext" label="Title" required="true" /></h6>
<perch:category id="catSlug" type="slug" for="catTitle" suppress="true" />
<perch:category id="desc" type="textarea" label="Description" editor="markitup" markdown="true" size="s" />
<!--** id="projects" must match the 'key' in 'each' **-->
<perch:category id="projects" type="hidden" encode="false" />

perch_collection HTML template

<perch:before><ul></perch:before>

<li><a title="<perch:content id="developmentName" />, new homes in <perch:content id="developmentAddress2"/>" href="/find-a-new-home/<perch:categories id="developmentStatus" set="developments"><perch:if exists="perch_item_first"><perch:category id="catSlug"/>/</perch:if></perch:categories><perch:content id="slug" type="slug" />"><i></i><perch:content id="developmentName" />, <perch:content id="developmentAddress2"/></a></li>

<perch:after></ul></perch:after>

This is even faster than my previous hardcoded demo. The performance indicator shows the property-developments-footer-list.html template now loads in 0.0038, it was originally slowing the page down at 1.6407.

Delighted. I can't believe how much faster the page is!

How it works (for my own benefit when I come back to the forum in 6 months time searching for how to do this!)

  • The php looks at all the items in perch_categories that are categorised as new-homes.
  • It then runs the each callback looking for any items in the perch_collection that are also categorised as new-homes.
  • The key (pun intended) to getting this to work is making sure the key in $item['projects'] is referenced in category--new-homes.html. When that template is used, it contains the output of the each callback.
Hussein Al Hammad

Hussein Al Hammad 103 points
Registered Developer

Nice!

I've implemented category filtering with perch_collection() recently, but there was no impact on performance like you are seeing.

Excuse my curiosity, what happens when you add the trailing slash to your category path developments/new-homes/? Is there any difference in performance?

perch_collection('Property developments', [
  'category' => 'developments/new-homes/',
  'template' =>'_property-developments/property-developments-footer-list.html',
]);

Hi

There's no significant change when I add a trailing slash.

No trailing slash. Performance indicator: 1.5116

perch_collection('Property developments', [
'category' => 'developments/new-homes',
'template' =>'_property-developments/property-developments-footer-list.html',
]);

With trailing slash. Performance indicator: 1.5288

perch_collection('Property developments', [
'category' => 'developments/new-homes/',
'template' =>'_property-developments/property-developments-footer-list.html',
]);

Hmmmm,

Looks like the "solution" I posted last week doesn't actually work any better. Not sure why I'm seeing different results this morning.

I've created a new post here, incase anyone runs into a similar issue. Crossing my fingers for a working solution soon.