I am having some issues having the pagination work on the Algolia search results page.
What am I doing wrong?
This is what I have in my templates/search.php
<?php $results = $results->paginate(20) ?>
<ul>
<?php foreach($results as $result): ?>
<li>
<?php echo $result->title() ?>
</li>
<?php endforeach ?>
</ul>
<?php if($results->pagination()->hasPages()): ?>
<nav class="pagination">
<?php if($results->pagination()->hasNextPage()): ?>
<a class="next" href="<?php echo $results->pagination()->nextPageURL() ?>">‹ next page</a>
<?php endif ?>
<?php if($results->pagination()->hasPrevPage()): ?>
<a class="prev" href="<?php echo $results->pagination()->prevPageURL() ?>">previous page ›</a>
<?php endif ?>
</nav>
<?php endif ?>
and in my controllers/search.php
<?php
return function($site, $pages, $page) {
$query = get('q');
$page = param('page');
if($query) {
$results = algolia()->search($query, $page);
$pagination = $results->pagination();
} else {
$results = array();
$pagination = null;
}
return compact('results', 'pagination');
};
The problem is that you paginate your results in your template, but you try to define the pagination object in the controller and then again in the template. Also, you can’t paginate an array, because paginate()
is a method of the collection class. Your controller and template should look like this:
<?php
return function($site, $pages, $page) {
$query = get('q');
$page = param('page');
if($query) {
$results = algolia()->search($query, $page);
} else {
$results = new Collection();
}
$results = $results->paginate(20);
$pagination = $results->pagination();
return compact('results', 'pagination');
};
Note that we now return an empty collection here.
<?php if($results->count()): ?>
<ul>
<?php foreach($results as $result): ?>
<li>
<?php echo $result->title() ?>
</li>
<?php endforeach ?>
</ul>
<?php if($pagination->hasPages()): ?>
<nav class="pagination">
<?php if($pagination->hasNextPage()): ?>
<a class="next" href="<?php echo $pagination->nextPageURL() ?>">‹ next page</a>
<?php endif ?>
<?php if($pagination->hasPrevPage()): ?>
<a class="prev" href="<?php echo $pagination->prevPageURL() ?>">previous page ›</a>
<?php endif ?>
</nav>
<?php endif ?>
<?php endif ?>
On the first part you need to remove the first line:
- <?php $results = $results->paginate(20) ?>
<ul>
<?php foreach($results as $result): ?>
<li>
<?php echo $result->title() ?>
</li>
<?php endforeach ?>
</ul>
On the second part you could use the $pagination
variable you are passing from the controller instead of $results->pagination()
.
Thank you for helping me.
I have updated both template and controller with the code suggested by texnixe.
It paginates the first page correctly:
http://localhost/site/search?q=item
totalCount() returns 1290 items:
<?php echo $results->totalCount() ?>
But when I click on the “Next page” link, I get a blank page with zero results.
The address bar points to the following, and totalCount() returns me 0
http://localhost/site/search/page:2/?q=item
What could it be?
Oh, I just had a look in the Algolia docs and it seems it does not use the paginate()
method, so we should remove the $results->paginate()
line from the controller.
<?php
return function($site, $pages, $page) {
$query = get('q');
$page = param('page');
if($query) {
$results = algolia()->search($query, $page);
} else {
$results = new Collection();
}
$pagination = $results->pagination();
return compact('results', 'pagination');
};
The number of results is instead set in the config options:
c::set('algolia.search.options', array(
'typoTolerance' => false,
'hitsPerPage' => 50
));
Explanation for the different pagination behavior: Results are always paginated because we’d otherwise need to get all results from Algolia – and that wouldn’t be good. 