Jump to content

subchildren selector


Martinus
 Share

Recommended Posts

I have this code which is working fine only using children of parents:

<?php 
    switch($page->parent->name) {
        case "sellers":
        case "brands":
        case "categories":
        case "departments":
        // If this page HAS a parent page named 'sellers, vendors, categories or departments'. 
        $items = $pages->find("parent=/products/, seller|brand|department|category=$page, sort=$order, limit=4");
        $file = "_products.php";
        break;
    } ?>

I am now moving categories under their departments, so, now, my url is this : /sitename/departments/hardware/heating/
Heating is a category under Hardware (which is a department). How do I address the parent of 'hardware' or children of 'hardware' if I do not know it's name?
I need to change the switch and also the selector and my question is, how would I make a switch to include my file and retrieve items? 

 

Link to comment
Share on other sites

I mean… it’s always going to be departments/<some department>/<some category>/, right? So when you navigate to a catetory page such as your example /sitename/departments/hardware/heating/, you want to see products that have both department=hardware and category=heating? Do you use the same template for sellers, brands, categories and departments? It would be easy if you had a specific category template. Otherwise you have to go by position in the page tree:

if ($page->matches('has_parent=departments')) { // you could also use $page->rootParent if /departments/ is immediately below root

    //now $page may be either a department or a category. we assume
    //that /departments/ has ONLY departments as children, and all
    //such departments have ONLY categories as children (or perhaps
    //they have things that don’t run this template)
    if ($page->parent->name === 'department')
        $items = $pages->find("parent=/products/, department=$page, sort=$order, limit=4");
    else
        $items = $pages->find("parent=/products/, department=$page->parent, category=$page, sort=$order, limit=4");

    $file = "_products.php";
}
else {
    //sellers and brands
}

 

  • Like 1
Link to comment
Share on other sites

@Martinusif I understand what you're trying to do correctly, I think url segments are the best approach.

I frequently use ProcessWire for organising and displaying categorised data and usually approach this sort of thing with url segments rather than working with the actual pages (if that makes sense).

So put all your items under a /items page rather than in a set structure. You can then you can create category pages as views of different sub pages by using the url segments in your selector.

The advantage is that you can have your items in multiple categories without any duplication of pages, you only have to maintain one parent 'category' template and from an SEO perspective the url segments appear the same as regular URLs. (You may need to manually inject them into your sitemaps though).

  • Like 1
Link to comment
Share on other sites

@Guy Incognito Your above explanation on url segments is very interesting. Can you expand any further on how you set this up?

I've read through https://processwire.com/docs/front-end/how-to-use-url-segments/ , but I'm still not fully absorbing what I think is your approach. I'm sure the parent could benefit from this approach as well.

  • Like 1
Link to comment
Share on other sites

Thanks for responding all. I think I actually have the same as @Guy Incognito

My page structure now is (order not important):

Home
- Departments (parent with each department in it)
- Categories (parent with each category in it)
- Sellers (parent with each seller in it)
- Brands (parent with each brand in it)
- Products (parent with each product in it)

I use 1 template (browse) for determining what link was clicked (switch case, declaring variables), and 1 template (product) for a single product. In my browse template I include one of two files: for Products or for parents. With markup and all. My browse template is used for all parents and their children.

The only thing is, I need occasional dropdown selects with values that are occupied with products. And if I use a direct query on Departments it would be easy but I need only those which have products (I hate pages that says 'nothing found' 😉

I solve this with the following example (some parts can be merged but for simplicity I type it like this):

// DEPARTMENT SELECT
$select2 = $pages->find("parent=/products/, department>0, sort=name");

// create new array
$array2 = array();

// loop through results
foreach($select2 as $item) {

// move each department in new array
array_push($array2, $item->department);

// place only unique values in variable
$totalDepartments = array_unique($array2);
}

And then I thought, maybe it was easier moving categories under departments, and products under categories. But maybe I just have to leave it as it is.

  • Like 1
Link to comment
Share on other sites

4 hours ago, Jim Bailie said:

@Guy Incognito Your above explanation on url segments is very interesting. Can you expand any further on how you set this up?

I've read through https://processwire.com/docs/front-end/how-to-use-url-segments/ , but I'm still not fully absorbing what I think is your approach. I'm sure the parent could benefit from this approach as well.

@Martinushas summed it up pretty well. This is basically the same approach I use. So you build your navs/links up using your category (or sub page names) rather than a 'traditional' link to a sub-page url and append them to the parent page URL.

<a href="<?=$page->url.{CAT-NAME-GOES-HERE};?>">Example Category</a>

Then you can get retrieve the url segment from the page URL and use it in your selectors for filling out the dynamic content.

  • Like 1
Link to comment
Share on other sites

I actually do not use url-segments for my normal pages. At least, not that I know off. I click the page Departments (menu item or product sub link), and this use the browse template. On the browse template the php switch determines I access a parent page, so I include the parent markup php file (no template), and it displays all children of the Departments: department x, y, z, etc. Same applies to Categories, Sellers and Brands. Since these are actual PW pages they are not url segments.

For the sorting, I do use url segments, which, btw, I still have to look at: 

// Here we use a switch case to determine how to sort.
        // we are only using 1 URL segment, so send a 404 if there's more than 1
        // DO WE NEED TO MAKE A 404 PAGE FOR THIS ???
        if(strlen($input->urlSegment2)) throw new Wire404Exception();
        switch($input->urlSegment1) {

        case 'name-asc': // NAME
            $order = "title";
            $sorted = "name asc";
            break;

etc.

 

Link to comment
Share on other sites

10 hours ago, Guy Incognito said:

So put all your items under a /items page rather than in a set structure. You can then you can create category pages as views of different sub pages by using the url segments in your selector.

My parent pages are just page-reference fields. But in my approach the Departments displays children under this parent: 'Apparel' etc. And when I click on this child link I get all products under Apparel. Each product has links referring to a category, department, etc. 

Link to comment
Share on other sites

1 hour ago, Martinus said:

I actually do not use url-segments for my normal pages. At least, not that I know off. I click the page Departments (menu item or product sub link), and this use the browse template. On the browse template the php switch determines I access a parent page, so I include the parent markup php file (no template), and it displays all children of the Departments: department x, y, z, etc. Same applies to Categories, Sellers and Brands. Since these are actual PW pages they are not url segments.

For the sorting, I do use url segments, which, btw, I still have to look at: 

// Here we use a switch case to determine how to sort.
        // we are only using 1 URL segment, so send a 404 if there's more than 1
        // DO WE NEED TO MAKE A 404 PAGE FOR THIS ???
        if(strlen($input->urlSegment2)) throw new Wire404Exception();
        switch($input->urlSegment1) {

        case 'name-asc': // NAME
            $order = "title";
            $sorted = "name asc";
            break;

etc.

 

Ah ok that all makes sense - maybe I misunderstood the original question sorry!

Re: the 404 page I can't see why your approach wouldn't work - but I think you can just do if($input->urlSegment2) btw to check for the segments. 🙂 

 

Edited by Guy Incognito
Edited for typo.
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...