Forum

Thread tagged as: Question

Category list with files in Perch

I have the below code on my page that pulls out 'datasheets' from a product page and lists them, in this case filtered by the category 'red'.

<?php
  perch_content_custom('Products', array(
      'page' => '/products.php',
    'template' => 'datasheets.html',
        'category' => 'product-category/red',
  ));
?>

Here is the template:

<perch:before>
    <div class="container">
    <article class="datasheets">
        <section>
            <perch:categories id="product-category" set="product-category">
              <perch:category id="catTitle" />
            </perch:categories>
            <ul class="downloads">
</perch:before>

                <perch:if exists="datasheet_title">
                    <li>
                        <a href="<perch:content id="datasheet" type="file" label="Datasheet PDF" bucket="datasheets" order="2" />"><perch:content id="datasheet_title" type="text" label="Datasheet Title" required="true" title="true" size="xl" order="1" /></a>
                    </li>
                </perch:if>

<perch:after>
                </ul>

        </section>
    </article>
</div>
</perch:after>

Ideally, rather than adding the category manually (by repeating the above and changing to 'category' => 'product-category/blue' etc), I would like to pull in all categories and list the datasheets under each category. For example:

Red Datasheet A Datasheet C

Blue Datasheet B Datasheet D

What is the best method to do this? I have tried a few things but I get things like one category title will everything under it or just the category titles etc

Andy Knight

Andy Knight 1 points

  • 4 years ago
Drew McLellan

Drew McLellan 2638 points
Perch Support

Only output the title when it changes:

<perch:if different="catTitle">
    <perch:category id="catTitle" />
</perch:if>

Hi Drew,

Not sure I explained properly but the bit that is casing me the problem is as follows:

<?php
perch_content_custom('Products', array(
'page' => '/products.php',
'template' => 'datasheets.html',
'category' => 'product-category/red',
));
?>

Specifically this part

'category' => 'product-category/red',

I would like to list all categories with their associated datasheets.

Rachel Andrew

Rachel Andrew 394 points
Perch Support

What problem are you seeing when you use the solution in the template as suggested by Drew?

Hi Rachel,

I just get the first category title output with all 'datasheets' below it. New template code below:

<perch:before>
    <div class="container">
    <article class="datasheets">
        <section>
            <perch:categories id="product-category" set="product-category">
              <perch:if different="catTitle">
                    <perch:category id="catTitle" />
                </perch:if>
            </perch:categories>
            <ul class="downloads">
</perch:before>

                <perch:if exists="datasheet_title">
                    <li>
                        <a href="<perch:content id="datasheet" type="file" label="Datasheet PDF" bucket="datasheets" order="2" />"><perch:content id="datasheet_title" type="text" label="Datasheet Title" required="true" title="true" size="xl" order="1" /></a>
                    </li>
                </perch:if>

<perch:after>
                </ul>

        </section>
    </article>
</div>
</perch:after>

I guess its the below bit that is the issue though as I am asking Perch to just give me items with the category 'red'. I have tried 'category' => perch_get('cat'), as well but this doesnt work either.

<?php
  perch_content_custom('News', array(
      'page' => '/news.php',
    'template' => 'datasheets.html',
        'category' => 'product-category/red',
  ));
?>
Drew McLellan

Drew McLellan 2638 points
Perch Support

Looks like you're still filtering by category. I think you want to sort by category instead.

Hi Drew,

Thanks. I'm nearly there (I think). I have changed the template as follows:

<perch:before>
    <div class="container">
    <article class="datasheets">
        <section>

</perch:before>

    <perch:categories id="prod_cat" set="product-category">
      <perch:if different="catTitle">
            <h3><perch:category id="catTitle" /></h3>
        </perch:if>
    </perch:categories>

            <ul class="downloads">
            <perch:if exists="datasheet_title">
                <li>
                    <a href="<perch:content id="datasheet" type="file" label="Datasheet PDF" bucket="datasheets" order="2" />"><perch:content id="datasheet_title" type="text" label="Datasheet Title" required="true" title="true" size="xl" order="1" /></a>
                </li>
            </perch:if>
            </ul>

<perch:after>

        </section>
    </article>
</div>
</perch:after>

and the page is now:

<?php
  perch_content_custom('News', array(
      'page' => '/news.php',
    'template' => 'datasheets.html',
        'sort' => 'catTitle',
        'sort-order' => 'ASC',
    ));
?>

but this outputs nothing.

Debug from the page

Debug Message
[1] SELECT regionID, regionTemplate, regionPage, regionRev AS rev FROM perch2_content_regions WHERE regionKey='Product' AND (regionPage='/product.php' OR regionPage='*')
[nil] SELECT * FROM ( SELECT idx.itemID, c.regionID, idx.pageID, c.itemJSON, idx2.indexValue as sortval FROM perch2_content_index idx JOIN perch2_content_items c ON idx.itemID=c.itemID AND idx.itemRev=c.itemRev AND idx.regionID=c.regionID JOIN perch2_content_index idx2 ON idx.itemID=idx2.itemID AND idx.itemRev=idx2.itemRev AND idx2.indexKey='catTitle' WHERE ((idx.regionID=1 AND idx.itemRev=95)) AND idx.itemID=idx2.itemID AND idx.itemRev=idx2.itemRev ) as tbl GROUP BY itemID, pageID, itemJSON, sortval ORDER BY sortval ASC
Using template: /templates/content/datasheets.html

If I remove the 'sort' and 'sort-order' part, the page displays all results and still repeats the categories.

Debug from the page with no sorting:

Debug Message
[1] SELECT regionID, regionTemplate, regionPage, regionRev AS rev FROM perch2_content_regions WHERE regionKey='Product' AND (regionPage='/product.php' OR regionPage='*')
[6] SELECT * FROM ( SELECT idx.itemID, c.regionID, idx.pageID, c.itemJSON, idx2.indexValue as sortval FROM perch2_content_index idx JOIN perch2_content_items c ON idx.itemID=c.itemID AND idx.itemRev=c.itemRev AND idx.regionID=c.regionID JOIN perch2_content_index idx2 ON idx.itemID=idx2.itemID AND idx.itemRev=idx2.itemRev AND idx2.indexKey='_order' WHERE ((idx.regionID=1 AND idx.itemRev=95)) AND idx.itemID=idx2.itemID AND idx.itemRev=idx2.itemRev ) as tbl GROUP BY itemID, pageID, itemJSON, sortval ORDER BY sortval ASC
[6] Using template: /templates/content/datasheets.html
[1] SELECT * FROM perch2_categories ORDER BY catTreePosition ASC
Drew McLellan

Drew McLellan 2638 points
Perch Support

catTitle isn't a field that your blog posts have. You'll need to sort by the ID of the category field.

Hi Drew,

Sorted by the id of the category field 'sort' => 'prod_cat' but still shows no results.

Drew McLellan

Drew McLellan 2638 points
Perch Support

Hmm. Try using _category instead.

That give a result, but I am getting categories repeated before each 'datasheet'.

Drew McLellan

Drew McLellan 2638 points
Perch Support

Which part of the template is that?

Hi Drew,

I thought it best to start again with this as I have changed things a little trying to get this to work.

I have a list and detail setup for Products. Products have a category assigned to them. Each product also has a repeater for file downloads.

On another page called "datasheets.php", I need to list just the downloads from all products. These downloads need to be displayed by category under their category title.

Repeater part of the Products detail template 'product_detail.html':

<perch:repeater id="datasheets" label="Datasheets">
                    <perch:before>
                        <ul class="downloads">
                    </perch:before>
                        <li><a href="<perch:content id="datasheet" type="file" label="Datasheet PDF" bucket="datasheets" order="9" />"><perch:content id="datasheet_title" type="text" label="Datasheet Title" required="true" size="xl" order="8" divider-before="Datasheets" /></a></li>
                    <perch:after>
                        </ul>
                    </perch:after>
                </perch:repeater>

The page that displays the datasheets 'datasheets.php'

<?php    
    perch_content_custom('Products', array(
      'template' => 'datasheets.html',
      'page'=> '/products.php',
    ));
?>

The template for 'datasheets,php' - 'datasheets.html'

<perch:before>
    <div class="container">
    <article class="datasheets">
        <section>

</perch:before>

    <perch:categories id="prod_cat" set="category">
      <perch:if different="catTitle">
            <h3><perch:category id="catTitle" /></h3>
        </perch:if>
    </perch:categories>


            <perch:repeater id="datasheets" label="Datasheets">
                <perch:before>
                    <ul class="downloads">
                </perch:before>
                    <li><a href="<perch:content id="datasheet" type="file" label="Datasheet PDF" bucket="datasheets" order="9" />"><perch:content id="datasheet_title" type="text" label="Datasheet Title" required="true" size="xl" order="8" divider-before="Datasheets" /></a></li>
                <perch:after>
                    </ul>
                </perch:after>
            </perch:repeater>

<perch:after>

        </section>
    </article>
</div>
</perch:after>

This gives multiple versions of the category, with the associated downloads for each product below.

e.g. Cat A - File A, File B / Cat A - File C / Cat B - File D..... and so on

I need to have one title for each category and list all downloads associated to products with that category.

Drew McLellan

Drew McLellan 2638 points
Perch Support

Have you considered looping through your categories and displaying the matching items?

No, but that sounds like a good idea. Can you give me any pointers to any documentation on this?

Drew McLellan

Drew McLellan 2638 points
Perch Support

Sure: https://docs.grabaperch.com/functions/categories/perch-categories/

Use the each callback to query your content items based on the current category.

Drew McLellan said:

Sure: https://docs.grabaperch.com/functions/categories/perch-categories/

Use the each callback to query your content items based on the current category.

Hi Drew,

Im still struggling with this - specifically the 'Use the each callback to query your content items based on the current category.' part. Any ponters?

Rachel Andrew

Rachel Andrew 394 points
Perch Support

There are examples in the documentation https://docs.grabaperch.com/runway/collections/callback-functions-with-each/

I searched for 'each'. That example uses a Collection but all the _custom functions work in pretty much the same way.

Hi Rachel,

Nope, this has me stumped.

I am trying to follow the examples but I just cant get things to work as I need them.

On my datasheets.php page in now have:

<?php
        $productType = perch_categories(array(
          'set'=>'product-category',
          'template'=>'abc.html',
          'filter'=>'catID',
          'match'=>'gt',
          'value'=>'0',

          'each' => function($item) {
              $item['test'] = perch_content_custom('Products',array(
                  'page'=>'/products.php',
                'category'=>$item['catPath'],
                'template'=>'datasheets.html'
              ),true);

              return $item;
          },
        ));
        ?>

Which displays the category title but nothing else on the template.

Drew McLellan

Drew McLellan 2638 points
Perch Support

Have you added test to the template?

With test being an id of some Perch content?