Hello,
I found one problem when I surf the page which is it’s not possible to filter the paginated page.
Like this…
As you can see, in page : 5, the web page cannot filter works.
So I wonder if it is possible to filter all works at the paginated web page ? (the pagination might be reset and filter all works at the page :1)
This is my code
<?php
return function ($site, $pages, $page) {
$workcategory = param('category');
$worktimeline = param('timeline');
$artworks = page('home/works')->children()->listed();
$categories = $artworks->pluck('category', ',', true);
$timelines = $artworks->pluck('timeline', ',', true);
$artworks = $artworks
->when($workcategory, function ($workcategory) {
return $this->filterBy('category', $workcategory, ',');
})
->when($worktimeline, function ($worktimeline) {
return $this->filterBy('timeline', $worktimeline);
});
$query = get('q');
$results = $artworks->search($query, 'title');
// pagination
$artworks = $artworks->paginate(30);
$pagination = $artworks->pagination();
return compact('artworks', 'categories','timelines', 'query', 'results', 'pagination');
};
Please help!
Thank you:)
Could you please post your template code as well?
Sure!
This is the one
<?php if ($works = page('home/works')): ?>
<div id="container__contents" class="container--works">
<div class="container--works__filters">
<?php snippet('filters/category') ?>
<?php snippet('filters/timeline') ?>
</div>
<div class="container--works">
<?php snippet('loader') ?>
<?php foreach ($artworks as $p): ?>
<div class="container--works--items">
<div class="container--works--items__thumbnail">
<?php if ($mainImg = $p->workImgMain()->toFile()): ?>
<img class="worksmainImg" src="<?= $mainImg->url() ?>">
<?php endif ?>
<span>
<?= $p->title()->kt() ?>
</span>
</div>
<?php endforeach ?>
<div class="bottom">
<?php snippet('pagination') ?>
<?php snippet('copyright') ?>
</div>
</div>
</div>
<?php endif ?>
Those snippets contain the interesting part…
Oh I see,
This the code of ‘filters/category’
<div class="filter">
<p class="filter--title">Category</p>
<ul class="filter--category">
<?php $activeTag = param('category'); ?>
<?php $cate = kirby()->request()->params()->tag(); ?>
<li>
<a <?php e($categories == $cate, 'class="activebtn"') ?> href="<?= url($page->url()) ?>">All</a>
</li>
<?php foreach($categories as $categories): ?>
<li>
<a <?= $activeTag === $categories ? ' class="activebtn"' : '' ?> href="<?= url($page->url(), ['params' => array_merge(params(),['category' => $categories])]) ?>">
<?= html($categories) ?>
</a>
</li>
<?php endforeach ?>
</ul>
</div>
Hm, this doesn’t make sense, $categories is defined as an array of all your categories plucked from $artworks. Comparing that to the parameter string, will not do what you expect.
Don’t have time now to look into this in details…
Ok, I think your snippet should look like this:
div class="filter">
<p class="filter--title">Category</p>
<ul class="filter--category">
<?php $activeTag = param('category'); ?>
<li>
<a <?php
// All is active if no parameter is set!
e(empty($activeTag), 'class="activebtn"') ?> href="<?= url($page->url()) ?>">All</a>
</li>
<?php
// never use the same variable for the array and the item!
foreach($categories as $category): ?>
<li>
<a <?= $activeTag === $category ? ' class="activebtn"' : '' ?> href="<?= url($page->url(), ['params' => array_merge(params(),['category' => $category])]) ?>">
<?= html($category) ?>
</a>
</li>
<?php endforeach ?>
</ul>
</div>
Thank you for your reply!
I change the templates like this but still web doesn’t work on the page “http://…/works/page:5/timeline:2014”
It only works when the filtered page has page:5.
<div class="filter">
<p class="filter--title">Category</p>
<ul class="filter--category">
<?php $activeTag = param('category'); ?>
<?php $cate = kirby()->request()->params()->tag(); ?>
<li>
<a <?php e(empty($activeTag), 'class="activebtn"') ?> href="<?= url($page->url()) ?>">All</a>
</li>
<?php foreach($categories as $category): ?>
<li>
<a <?= $activeTag === $category ? ' class="activebtn"' : '' ?> href="<?= url($page->url(), ['params' => array_merge(params(),['category' => $category])]) ?>">
<?= html($category) ?>
</a>
</li>
<?php endforeach ?>
</ul>
</div>
<div class="filter">
<p class="filter--title">Timeline</p>
<ul class="filter--category">
<?php $activeTag = param('timeline'); ?>
<?php foreach($timelines as $timeline): ?>
<li>
<a <?= $activeTag === $timeline ? ' class="activebtn"' : '' ?> href="<?= url($page->url(), ['params' => array_merge(params(),['timeline' => $timeline])]) ?>">
<?= html($timeline) ?>
</a>
</li>
<?php endforeach ?>
</ul>
</div>
Please comment this if you have any idea…!
Thank you
This is the problem. You merge the parameters here, but the page number parameter doesn’t make sense for a new category, because the number of pages can change. Therefore, pagination should never be included here.
Oh, Thank you for answering!
Like you said, I changed the code like this but now from this code, I just got a new problem.
If I change the code like this, I cannot select two filter at once like this : (/category:Objects/time:2020).
Only one filter works at once currently.
<li>
<a <?= $activeTag === $category ? ' class="activebtn"' : '' ?> href="<?= url($page->url(), ['params' => ['category' => $category]]) ?>">
<?= html($category) ?>
</a>
</li>
...
<li>
<a <?= $activeTag === $timeline ? ' class="activebtn"' : '' ?> href="<?= url($page->url(), ['params' => ['timeline' => $timeline]]) ?>">
<?= html($timeline) ?>
</a>
</li>
Do you have any solution at this situation?
<?php
$params = [];
if (param('timeline') {
$params['timeline'] = param('timeline'];
}
if (param('category') {
$params['category'] = param('category'];
}
?>
<a <?= $activeTag === $category ? ' class="activebtn"' : '' ?> href="<?= url($page->url(), ['params' => array_merge($params['timeline'] ?? [],['category' => $category])]) ?>">
And then the same for the other link, using $params['category']
instead.
Hi, I have one more question! Sorry that I keep asking…
Like you told me, I changed the code like this
<?php
$params = [];
if (param('timeline')) {
$params['timeline'] = param('timeline');
}
if (param('category')) {
$params['category'] = param('category');
}
?>
<a <?= $activeTag === $category ? ' class="activebtn"' : '' ?> href="<?= url($page->url(), ['params' => array_merge($params['timeline'] ?? [],['category' => $category])]) ?>">
<?= html($category) ?>
</a>
But I keep getting this error so that I cannot access to the filter at all
: array_merge(): Expected parameter 1 to be an array, string given
Do you think I should put some code on the controller.php?
<?php
return function ($site, $pages, $page) {
$workcategory = param('category');
$worktimeline = param('timeline');
$artworks = page('home/works')->children()->listed();
$categories = $artworks->pluck('category', ',', true);
$timelines = $artworks->pluck('timeline', ',', true);
$artworks = $artworks
->when($workcategory, function ($workcategory) {
return $this->filterBy('category', $workcategory, ',');
})
->when($worktimeline, function ($worktimeline) {
return $this->filterBy('timeline', $worktimeline);
});
$query = get('q');
$results = $artworks->search($query, 'title');
// pagination
$artworks = $artworks->paginate(30);
$pagination = $artworks->pagination();
return compact('artworks', 'categories','timelines', 'query', 'results', 'pagination');
};
Thank you!
Oops, that was silly of me, sorry should have been
array_merge($params , ['category' => $category])])
1 Like
Now it works!
Thank you so much