The page helper needs the id of a page. What you have to do is render the blog page with the tag value passed in the data array
I always get a 404 error (not found with this page(‘blog’).
Could the reason be my multi-language setup (EN & DE) + this config setting: ‘home’ => ‘blog’?
Then you better get the home
page.
This doesn’t help, I always get a 404.
Could it be because of the multi-language setting?
[
'pattern' => 'test/',
'action' => function ($value) {
$data = [
'tag' => $value,
];
if ($page = page('test/')) {
return $page;
} else {
return page('home')->render($data);
}
}
]
You can only use a variable here if your route contains a variable part
No trailing slash here.
Always a page not found error:
[
'pattern' => 'test/',
'action' => function () {
if ($page = page('test')) {
return $page;
} else {
return page('home');
}
}
]
You probably also have to remove the trailing slash from here
I had to rename ‘home’ to ‘blog’ even if the page blog has been moved to home by the mentioned config to make it work.
Only with the following addition it doesn’t work:
return page('blog')->filterBy('tags', 'test', ',');
I was hoping that I would be able to filter all articles with a specific tag only by this.
No, as mentioned above, you have to pass the tag you want to filter by to the controller, then do your filtering there.
Calling filterBy()
on a single page makes no sense at all, you can only filter a collection.
Probably my knowledge and understanding of PHP is far too low for this (and I really appreciate your constant support) but with this code all articles are displayed and not only the one with the tag “test”. Why is that?
config.php
[
'pattern' => '(test)',
'action' => function ($tag) {
if ($page = page('test')) {
return $page;
} else {
return page('blog')->render([
'tag' => $tag
]);
}
}
]
controllers/blog.php
<?php
return function($page, $tag) {
// fetch the basic set of pages
$articles = $page->children()->listed()->flip();
// fetch all tags
$tags = $articles->pluck('tags', ',', true);
// add the tag filter
if($tag = param('tag')) {
$articles = $articles->filterBy('tags', $tag, ',');
}
// apply pagination
$articles = $articles->paginate(5);
$pagination = $articles->pagination();
return compact('articles', 'tags', 'tag', 'pagination');
};
templates/blog.php
<?php snippet('header') ?>
<?php snippet('menu') ?>
<div class="blog">
<main class="blog" role="main">
<h1><?= $page->title()->html() ?></h1>
<?= $page->text()->kirbytext() ?>
<?php foreach($page->children()->listed()->flip()->paginate() as $article): ?>
<article>
<h1><?= $article->title()->html() ?></h1>
<?= $article->date()->toDate('%d.%m.%Y') ?>
<?= $article->intro()->kirbytext() ?>
<a href="<?= $article->url() ?>"><?php echo t('readmore', 'Weiterlesen…') ?></a>
</article>
<?php endforeach ?>
</main>
<!-- sidebar with tagcloud -->
<aside>
<h1>Tags</h1>
<ul class="tags">
<?php foreach($tags as $tag): ?>
<li>
<a href="<?= url($page->url(), ['params' => ['tag' => $tag]]) ?>">
<?= html($tag) ?>
</a>
</li>
<?php endforeach ?>
</ul>
<a class="twitter-timeline" height="500px" data-chrome="nofooter transparent" href="https://twitter.com/MaluNoPeleke?ref_src=twsrc%5Etfw">Tweets by MaluNoPeleke</a> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</aside>
<!-- pagination -->
<nav class="pagination">
<?php if($pagination->hasPrevPage()): ?>
<a href="<?= $pagination->prevPageUrl() ?>"><<</a>
<?php endif ?>
<?php if($pagination->hasNextPage()): ?>
<a href="<?= $pagination->nextPageUrl() ?>">>></a>
<?php endif ?>
</nav>
</div>
<?php snippet('footer') ?>
Since there is no parameter set in this case, you just check for $tag, see the docs: Controllers | Kirby CMS
if($tag) {
$articles = $articles->filterBy('tags', $tag, ',');
}
But with none of the following blog.php controller code variations articles will be filtered by tags (I would expect to see only articles with the tag “test”):
<?php
return function($page, $tag) {
// fetch the basic set of pages
$articles = $page->children()->listed()->flip();
// fetch all tags
$tags = $articles->pluck('tags', ',', true);
// add the tag filter
if($tag = param('tag')) {
$articles = $articles->filterBy('tags', 'test', ',');
}
// apply pagination
$articles = $articles->paginate(5);
$pagination = $articles->pagination();
return compact('articles', 'tags', 'tag', 'pagination');
};
<?php
return function($page, $tag) {
// fetch the basic set of pages
$articles = $page->children()->listed()->flip();
// fetch all tags
$tags = $articles->pluck('tags', ',', true);
// add the tag filter
if($tag) {
$articles = $articles->filterBy('tags', 'test', ',');
}
// apply pagination
$articles = $articles->paginate(5);
$pagination = $articles->pagination();
return compact('articles', 'tags', 'tag', 'pagination');
};
Does filtering work if you simply use the tag as parameter in the url and filter by param(‘tag’)?
http://yourdomain.test/tag:test
(or with language code in a multi-lang installation)
No, that doesn’t change anything either.
I followed the whole cookbook for the blog setup and created some articles with tags. What could be missing?
Is the field name correct? Feel free to send me a download link to the project. We are currently digging in the dark, it seems, although I’m sure it’s just a little thing.
The reason your filtering cannot possibly work is that you don’t use the $articles
variable in your template, but
<?php foreach($page->children()->listed()->flip()->paginate() as $article): ?>
which should be
<?php foreach($articles as $article): ?>
Thanks a lot, I didn’t look at that part anymore after I copied it from the example mentioned here: Creating a Kirby-powered blog | Kirby CMS
One question left: If I use the following code in the config.php to show only articles with the tag “test” on the virtual page “test” I still get all articles displayed:
[
'pattern' => 'test',
'action' => function () {
if ($page = page('test')) {
return $page;
} else {
return page('blog')->render([
'tag' => 'test'
]);
}
}
]
Why is that?
Finally it works, thanks a lot!
I used the wrong order, now I can use the virtual page or the normal tag filter with this code in the blog.php controller:
// add the tag filter
if($tag) {
$articles = $articles->filterBy('tags', $tag, ',');
}
if($tag = param('tag')) {
$articles = $articles->filterBy('tags', $tag, ',');
}
Initially I just pasted the mentioned code below the existing one.