How to pageList->filterByTopic multiple topics?

Permalink
I would like to be able to filter my page list by multiple topics, how can I do this?

ob7dev
 
ob7dev replied on at Permalink Reply
ob7dev
ITS IMPOSSIBLE! That's why no one tried answering!
Parasek replied on at Permalink Best Answer Reply
Parasek
Actually it is not impossible. You just to need do create your own class, which extends original PageList class

1. create file application/src/Page/CustomPageList.php
(you can actually create it anywhere you want - you just need to use proper namespace)
and paste this code
<?php
namespace Application\Src\Page;
use PageList;
class CustomPageList extends PageList
{
    public function filterByMultipleTopics($topics = array())
    {
        if (is_array($topics) AND count($topics)>0) {
            $this->query->innerJoin('cv', 'CollectionAttributeValues', 'cavTopics',
                'cv.cID = cavTopics.cID and cv.cvID = cavTopics.cvID');
            $this->query->innerJoin('cavTopics', 'atSelectedTopics', 'atst', 'cavTopics.avID = atst.avID');
            $query = '';
            foreach ($topics as $topic) {
                if (is_object($topic)) {
                    $treeNodeID = $topic->getTreeNodeID();

It is modified function filterByTopic(), which is located in concrete/src/Page/PageList.php
But instead of one topic id, it requires and array of topic ids as argument

2. To display pagelist, use this code

<?php
$topicIDs = array(11, 8);
$list = new Application\Src\Page\CustomPageList();
$list->filterByMultipleTopics($topicIDs);
$pages = $list->getResults();
?>
ob7dev replied on at Permalink Reply
ob7dev
No wonder your avatar is of a coding ninja! You are one! Nice domain name btw.
ScottsdaleUnified replied on at Permalink Reply
ScottsdaleUnified
Where does the second snippet of code go?
ob7dev replied on at Permalink Reply
ob7dev
Are you adding this to a page type or a block view?
ScottsdaleUnified replied on at Permalink Reply
ScottsdaleUnified
The PageList Block is what I wanted to use to display multiple topics (multiple schools or types of schools)
ob7dev replied on at Permalink Reply
ob7dev
So basically building a new package?
ScottsdaleUnified replied on at Permalink Reply
ScottsdaleUnified
Excuse my ignorance - maybe?

Basically I have 30 Blogs or Topics ( II have not decided if it would be smarter to have 30 blog roots or 1 Blog Root and 30+ topics)

So on every school site, my web author uses the blog feature to add announcements which go to a page as well as get displayed on the homepage of the school in a list view.

We used to use ProBlog (discontinued now) and I am developing the new site using Fundamental and C5DK Blog. I would really like to be able to use only one PageList and select Multiple Topics so I do not need to add 2+ Page Lists to show multiple topics.
ob7dev replied on at Permalink Reply
ob7dev
Ahh I understand. So there is two ways I know of the embed this "multiple topic pagelist". One if via embedding the code within a page template ( i.e. full.php or blog.php inside a theme folder ) or two is coding a block that has this code within its view.php.

I will need to see if I can pull this off before trying to tell you how to do it.
ScottsdaleUnified replied on at Permalink Reply
ScottsdaleUnified
I appreciate all your help!
JohntheFish replied on at Permalink Reply
JohntheFish
There was something on c5 github about enhancing the data list class for filtering a list by OR as well as or instead of AND.
ob7dev replied on at Permalink Reply
ob7dev
do u have the link by chance?
JohntheFish replied on at Permalink Reply
JohntheFish
I am afraid not. It was posted or updated fairly recently, within the last few weeks.
ob7dev replied on at Permalink Reply
ob7dev
Maybe something we can look forward to in 8.2
JackVanson replied on at Permalink Reply
Hi I am trying to get the above code to work in 8.4.3. I am not having any luck. I just get a 500 error.

Can someone please help. I really need to filter with multiple Topics.

Thanks

Jack
JackVanson replied on at Permalink Reply
For Anyone looking to filter by multiple topics in v8+ i have updated the above code. This will also allow you to use an array of topic nodes or just the one.

<?php
namespace Application\Page;
class CustomPageList extends \Concrete\Core\Page\PageList
{
    /**
     * Filters by topic. Doesn't look at specific attributes –instead, actually joins to the topics table.
     */
    public function filterByTopics($topics)
    {
        $is_multi = false;
        if (is_array($topics))
        {
            $is_multi = true;
            $topic_id_list = "";
            foreach ($topics as $topic) {


For multiple topic nodes you can do this.

$list = new Application\Page\CustomPageList();
$nde_array = [
TopicTreeNode::getNodeByName("topicOne"),
TopicTreeNode::getNodeByName("topicTwo"),
TopicTreeNode::getNodeByName("topicThree"),
TopicTreeNode::getNodeByName("topicFour"),
TopicTreeNode::getNodeByName("topicFive")
 ];
$docList->filterByTopics($nde_array);
$pages = $list->getResults();


For just one topic node you can use this:

$list = new Application\Page\CustomPageList();
$topicNode = TopicTreeNode::getNodeByName($pageName);
$list->filterByTopics($topicNode);
$pages = $list->getResults();
aenowwebsite replied on at Permalink Reply
Updated Parasek's snippet for V8.4.4

use \Concrete\Core\Page\PageList as Base;
class PageList extends Base
{
    public function filterByMultipleTopics($topics = array())
    {
        if (is_array($topics) AND count($topics)>0) {
            $this->query->innerJoin('cv', 'CollectionAttributeValues', 'cavTopics',
                'cv.cID = cavTopics.cID and cv.cvID = cavTopics.cvID');
            $this->query->innerJoin('cavTopics', 'atSelectedTopics', 'atst', 'cavTopics.avID = atst.avID');
            $query = '';
            foreach ($topics as $topic) {
                if (is_object($topic)) {
                    $treeNodeID = $topic->getTreeNodeID();
                } else {
                    $treeNodeID = $topic;


This method accepts arguments of Arrays of treeNodeID for each of the topics you wish to filter by