Jump to content

Start operator ignored if limit is not set


schwarzdesign
 Share

Recommended Posts

I'm working on a news feed that will show the most recent news in a full teaser grid, and all older news as a simpler archive-type list view. My selectors so far:

$news_full = $page->children("template=news, limit={$page->feed_count_full}");
$news_archive = $page->children("template=news, start={$page->feed_count_full}, limit=9999");

The $page->feed_count_full field controls how many items to show in the teaser grid (I've confirmed it contains the correct value, and the $news_full selector works as intended).

This works, but I don't like the limit in the second selector. Unfortunately, if I leave it out (i.e. I only specify a start, not a limit), the start is ignored and I get all news instead. Not a big problem as we will never have more than 9999 news, but it still bothers me, as semantically speaking I don't want to set a limit in this case.

Is this the intended behaviour of start/limit selectors? Is there a cleaner way to specify an offset (start selector) without a limit?

ProcessWire Version 3.0.123

Thanks!

Link to comment
Share on other sites

That's currently the way it is implemented. If there's no limit given, then PW ignores the offset (for the curios, it's implemented in PageFinder::getQueryStartLimit). It makes sense from a database point of view since MySQL's LIMIT keyword always needs a row count.

So your approach is the correct one. You could perhaps use a reasonably high number (like MySQL's maximum unsigned integer, 18446744073709551615) for your limit. If you don't want to have to remember the value, just put it intosite/config.php like "$config->maxDbLimit = 18446744073709551615;" and then use "limit={$config->maxDbLimit}" in your selector.

  • Like 2
Link to comment
Share on other sites

Wouldn't it be better to do something like:

$news_full = $page->children("template=news, limit={$page->feed_count_full}");
$news_archive = $page->children("template=news, limit=50")->filter("id!=$news_full");

so you can keep a reasonable limit to the archive query, 50 for instance, instead of loading all the children at once?

  • Like 1
Link to comment
Share on other sites

2 hours ago, Sergio said:

Wouldn't it be better to do something like:


$news_full = $page->children("template=news, limit={$page->feed_count_full}");
$news_archive = $page->children("template=news, limit=50")->filter("id!=$news_full");

You would need to exclude by ID withing the children selector or else the first page of $news_archive would be an unequal quantity (or empty depending on the value of feed_count_full) because pages would be filtered out after they are found.

$news_archive = $page->children("template=news, id!=$news_full, limit=50");

 

If all of the results are appearing on the same page (no pagination is used) then you can achieve it without needing a second DB query...

$news = $page->children("template=news");
$news_full = $news->slice(0, $page->feed_count_full);
$news_archive = $news->slice($page->feed_count_full);

 

  • Like 3
Link to comment
Share on other sites

15 hours ago, BitPoet said:

That's currently the way it is implemented. If there's no limit given, then PW ignores the offset (for the curios, it's implemented in PageFinder::getQueryStartLimit). It makes sense from a database point of view since MySQL's LIMIT keyword always needs a row count.

So your approach is the correct one. You could perhaps use a reasonably high number (like MySQL's maximum unsigned integer, 18446744073709551615) for your limit. If you don't want to have to remember the value, just put it intosite/config.php like "$config->maxDbLimit = 18446744073709551615;" and then use "limit={$config->maxDbLimit}" in your selector.

Thanks, that's what I assumed. Though it would be cool if ProcessWire did this under the hood, since having a start/offset but no limit is a realistic scenario / requirement in this case for example.

12 hours ago, Robin S said:

If all of the results are appearing on the same page (no pagination is used) then you can achieve it without needing a second DB query...


$news = $page->children("template=news");
$news_full = $news->slice(0, $page->feed_count_full);
$news_archive = $news->slice($page->feed_count_full);

 

Thanks, that's exactly what I was looking for! For some reason I thought I needed two different queries since I need different fields from the two sections ^^ I need to look into the WireArray methods again, some really useful stuff there ... ?

  • Like 2
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

×
×
  • Create New...