Collections, pages, etc...

Hey everyone!
I was trying to code an autonav block into a theme, which worked perfectly on localhost C5, but did not produce output on the hosted site. I made some small changes to the Collection::getByHandle method, through which I could retrieve a page object with knowing only it's handle. It turned out, that the problem is, that on my loal machine, there were exactly one rows with the given cHandle value in the database (in the Collections table), whereas on the live server, there were two entries with the same cHandle value. When I arrived home, I realized, that there are 'similar' problems on my local machine too, but not the same as on the server - thus, the problem did not arise with the pages being requested locally. So... I was wondering, for what reason can there be two entries in the Collections table with the same handle, when there is only one page on the site with that handle. Also, I made the same steps when installing C5 on the remote server, but it has different 'similar entires', than on localhost. Can anyone explain what is going on under the hood? Thanks!

View Replies: View Best Answer
xaritas replied on at Permalink Best Answer Reply
You're probably better off using Collection::getByPath if the location is static, or generating a page list query and filtering by the page type and attributes you expect, if you need to dynamically figure out the page.

Page by path example:
$myPage = Page::getByPath('about-us/ginger/bio');

If you can't rely on the path, you need to search for it:
/* Real code from a working app! Can't have more than one match in my app but your situation may differ so adjust accordingly */
  static function findOne($farmCode, $crop, $fieldCode) {
    $pl = new PageList();
    $pl->filterByAttribute('farm_code', $farmCode, '=');
    $pl->filterByAttribute('field_code', $fieldCode, '=');
    $pl->filterByAttribute('crop_code', $crop, '=');
    $farmFields = $pl->get();
    return $farmFields ? new FarmField($farmFields[0]) : null;

There are other filters you can apply, too, see:

I don't think that there is any expectation that collection handles are unique in the system, so you shouldn't rely on it.

As to why, I'm too lazy to double check, so the following should be treated as guess or speculation: I think the handle is used to generate the slug for the canonical URL when you invoke Page::add, so it is entirely reasonable to have duplicates (e.g., 'about-us/fred/bio' and 'about-us/ginger/bio' would both have 'bio'). I don't know if the duplicates are cleaned up when you trash or delete a page, but since you modified Collection::getByHandle you probably saw that you can at least have the same handle for a Page Collection and a non-Page Collection, and the system will create-on-fetch if a non-Page Collection doesn't exist when you asked for it.
szucslaszlo replied on at Permalink Reply
Hey there!
You are right, Page::getByPath() did exactly what I was trying to emulate with my little hacking around! I found it eventually on my own, but didn't have the time to post it out, yet. I somehow missed this method, when I was strolling about in the Collection/Page classes for the first couple of times. I had the same impression about why would there be more than one entries with the same cHandle in the Collections table. Actually, your answer would deserve a second "best answer" mark, because I was wondering on what to do, if I don't know the exact path to a page, or if it is restructured at some point, etc... so I'll have a nice look into this PageList object too. :) Thanks!