Forum

Thread tagged as: Question, Runway

How do I filter the content based on both category and slug?

The list and detail tutorial explains how to filter content using a slug. I've successfully implemented this, but I was wondering how would I filter a full category path and slug? Or maybe there's a better way to do this?

I'm using perch_collections and categories to manage my content.

Using the solution outlined in the list and detail tutorial, my template in detail mode uses this HTML to generate a link:

   <a href="/project/<perch:content id="slug" type="slug" />">View project</a>

This outputs this URL

  /project/flower-world
  <!-- I'd like to display the category in the URL -->

This item (flower-world) is in a category called retail. I've updated the detail mode template to include the category path in the link:

   <a href="<perch:category id="catPath"/><perch:content id="slug" />">View project</a>

The URL now looks like this:

   /projects/retail/flower-world
<!-- the category is now part of the URL -->

I've also added a URL pattern to my /projects page:

     projects/[slug:cat]/[slug:s]

There's a subtle difference at the start of the new URL. The original link redirected to a page called project, this page included the PHP required to filter content based on the slug.

Now the template uses the full category path there's no redirect (both the category set and the page are called projects).

The new link just reloads the /projects page with the new URL, but the content doesn't change. I guess there needs to be another filter - but I don't know how to filter for both category and slug.

What would I add to my list and detail PHP to also filter the content based on both category and slug?

    // Detail mode - This lists all the items within a 'selected' category


    if (perch_get('cat')) {

      perch_category('/projects/'.perch_get('cat'),array(
      'template'=>'category_project_single.html' // Outputs heading for each category
      ));

      perch_collection('Projects', array(
      'category'=> array('projects/' . perch_get('cat')),
      'template' => 'rc_project_listing.html' // lists all items in category
      ));

    } 


    // List mode - This is the category home page, lists all categories.
    else {

      perch_content('Page heading');          
      perch_categories(array( 
      'set'=>'projects',
      'template' => 'category_project_hub_2.html'            

    ));

}
Stephen Meehan

Stephen Meehan 4 points

  • 6 years ago
Drew McLellan

Drew McLellan 2638 points
Perch Support

You can just filter on both.

perch_collection('Projects', array(
      'category'=> array('projects/' . perch_get('cat')),
      'filter' => 'slug',
      'match' => 'eq',
      'value' => perch_get('s'),
      'template' => 'rc_project_listing.html' // lists all items in category
));

Hi Drew

I've managed to include your code into my template.

This is what I currently have.

  • /projects lists all the categories
  • /projects/retail/ is a selected category (still on projects page)
  • /projects/retail/flower-world is a selected item within the retail category

The problem is when I get to /projects/retail/flower-world the template used in the if statement is still visible.

How would I conditionally show this part of the template? I've tried to use elseif but it doesn't seem to work? Any help would be greatly appreciated.

  // Displays single item from selected category
  // URL: /projects/retail/flower-world
  // Problem: The 'if statement' is underneath this content. How do I remove it when this bit is visible?
  perch_collection('Projects', array(
  'category'=> array('projects/' . perch_get('cat')),
  'filter' => 'slug',
  'match' => 'eq',
  'value' => perch_get('s'),
  'template' => 'rc_project_detail.html' // displays detail page
    ));


    // Lists all the items within a 'selected' category
    // URL: /projects/retail/

    if (perch_get('cat')) {

      perch_category('/projects/'.perch_get('cat'),array(
      'template'=>'category_project_single.html' // Outputs heading for each category     
      ));

      perch_collection('Projects', array(
      'category'=> array('projects/' . perch_get('cat')),
      'template' => 'rc_project_listing.html' // lists all items in category
      ));

    } 


    // Lists all categories, projects home page
    // URL: /projects
    else {
      perch_content('Page heading');          
      perch_categories(array( 
      'set'=>'projects',
      'template' => 'category_project_hub_2.html'            
    ));

}

Still having problems with this.

It'd be great if it could work this way because the URL works a bit like a breadcrumb.

Starts of at /projects then a category is selected the URL reads /projects/retail finally when a project within a category is selected the URL reads /projects/retail/flower-world

Using something like I've posted above, is is possible to do this in Perch?

Hope you can help.

Drew McLellan

Drew McLellan 2638 points
Perch Support

Can you show me what routes you have set up for the page?