Jump to content

best way to select a page


Frank Vèssia
 Share

Recommended Posts

Martijn's points are very valid, but I would also argue that the advantage to getting by ID rather than name, is that the client can change the name of the page if they want and the selector will still work, so it is a bit of a trade-off.

I agree that the second makes no sense. Any selector together with ID will always be meaningless as only one page can have that ID anyway. See Soma's post below.

  • Like 1
Link to comment
Share on other sites

Both the same and since you specify a id explicit, it will just get that page and the template wouldn't be required.

But actually there's a difference in it:

$pages->get($pageID);

Will get the page even if unpublished, in trash, hidden or user would have no access! It isn't doing a real "find" and it's much like getting a row from DB no matter what. It's like a shortcut PW is doing in this case not doing a usual page finder search.

$pages->get("template=book,id=$pageID");

This will convert the previous into a "page finder search" much like when using a find("template=book, title=Mytitle"), thus behave different.

It will not return a page if unpublished or hidden or in trash or the user has no access.

EDIT: In fact in the last one, it will even get the page even if the template isn't correct! So the id=id is the key here. Any selector will get ignored. So doesn't really make sense to add selector if you got the ID. Page ID is one of the things that's unique an always the same untill you delete it.

  • Like 4
Link to comment
Share on other sites

Also maybe worth noting is that if you specify multiple id's...

$pages->get(" id=1001|1004|2003|3233,template=book,title=Mytitle");

This will be again different since it's not explicit anymore, and additional selectors will again be validated.

Link to comment
Share on other sites

Thanks guys for the replies, i was thinking about performance in terms of time for getting the page, maybe using "template" or other fields in addition to the ID was faster for PW to get that page because its' like: don't search in all pages to find that ID but search only in the pages having that template....but i got the point :)

Link to comment
Share on other sites

Sevarf2, you are correct about something here in that theoretically, supplying the template to the find() call should enable it to run faster. ProcessWire needs to know the template for a page before it starts loading it. So it'll query the DB for the page's template if it doesn't already know it. However, we don't have that optimization in place for $pages->find() at present, so your $pages->get("id=123, template=book"); doesn't benefit from that. But you can take advantage of that optimization by using the $pages->getById() method. It would technically be the fastest way to retrieve a page, but it's rare that I would be up for using it when developing a site (I only use it for core development). But it may be worth trying if you are trying to optimize a large amount of page retrievals. I'm not sure it'll make much difference in the end, but it's worth a shot. 

$template = $templates->get('book');
$page = $pages->getById($page_id, $template)->first(); 

The getById() method is really meant for retrieving multiple pages, which is why it returns a PageArray. If you have multiple pages using the same template, you can retrieve all of them here:

$pageArray = $pages->getById(array(123,456,789), $template);

If you can also supply a parent_id to the method (meaning, you already know all the provided page IDs have the same template and parent), it can use that for a little further optimization: 

$pageArray = $pages->getById(array(123,45,789), $template, $parent_id); 

Btw, the purpose of $pages->getById() method is as a support for all the other get(), find() and children() methods in ProcessWire (or anything else that returns a Page or PageArray from the DB). All pages loaded from the database are loaded by the getById() method, so all the other get/find methods are actually front-ends to it. getById() was never intended to be part of the public API though. 

  • Like 7
Link to comment
Share on other sites

Ryan in my tests, this doesn't work as in your examples.

$template = $templates->get('basic-page');
$p = $pages->getById(1386, $template)->first();
The page 1386 has the template "basic-page" but the query doesn't return it.
 
But it does find it when using this:
$template = $templates->get('basic-page');
$p = $pages->getById(array(1386), $template)->first(); 

BUT it also returns the page when I specify a wrong template

$template = $templates->get('custom');
$p = $pages->getById(array(1386), $template)->first();

I'm not sure what all about it when using id's to retrieve a page how would a template be of any benefit?

  • Like 1
Link to comment
Share on other sites

The page 1386 has the template "basic-page" but the query doesn't return it.

Sorry, writing in browser, I forgot the quotes around the value. It expects an array or a csv string, but maybe I should update it to support a single integer as well. But currently any of these should work:

$p = $pages->getById("123", $template)->first();
$p = $pages->getById("123,456,789", $template)->first();
$p = $pages->getById(array(123), $template)->first();
$p = $pages->getById(array(123,456,789), $template)->first(); 
BUT it also returns the page when I specify a wrong template

This may be possible (though not yet sure how). But it assumes you are specifying a template because you know what template it should use. This is why it can increase performance: because it doesn't have to go determine that for itself. It may give you a frankenstein page by specifying the wrong template. There is a reason why this function is not meant for the public API–it's low-level and really meant to be accessed through the other API functions. So if you use it, and aren't certain of the template already, then it's best not to specify the template. 

Most of PW's internal calls (resulting from a find or a get) do use this optimization, passing the template and the parent to getById(). 

I'm not sure what all about it when using id's to retrieve a page how would a template be of any benefit?

It needs to know the template in order to know which fields are contained by the template's fieldgroup. This is so that it can determine which fields should be joined with the main page loading query (autojoin). A few years into this, I find that I don't really need to use autojoin fields all that much (perhaps MySQL has gotten faster), so we may be able to change or get rid of this down the road. 

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...