Add a tag filter to the Page List block

Permalink 3 users found helpful
I love the page list block, but it would be much more useful if it had a tag filter so I could list all pages containing a specified tag.

Another option would be to list all pages with tags matching the current page.

View Replies:
olliephillips replied on at Permalink Reply
olliephillips
I can see how that would be useful, but very similar can be achieved by assigning your pages to specific "pages types", though this won't work if you are wanting to use mutliple tags per page - a page can only have one page type.

If you wanted to get into the code, the page list object has a number of methods you can filter on, and you can use a magic method to set filters on any custom attribute. So for tags:-

$pl->filterByTags($value, $comparison = '=');


Hope that helps
jordanlev replied on at Permalink Reply
jordanlev
I don't think that the code posted by @olliephillips won't work. There are some "special" things you need to do to handle the "select" attribute type (which is what the tags are I believe).

Instead, try this:
$tag = '???'; //You need to fill in this value somehow
$pl->filterByAttribute('tags', "%\n{$tag}\n%", "like");
admin replied on at Permalink Reply
Where would this code go?
jordanlev replied on at Permalink Reply
jordanlev
Unfortunately this code doesn't do anything on its own. You can add it to the page_list block's controller fairly easily, but the hard part is adding the edit interface that allows someone to choose which tags they want to filter on. I'm not sure how to do this myself off the top of my head. If you're a programmer you will need to do some exploration of how the page list block code works. If you're not a programmer, I don't think it's going to be possible to do this.

Do you need to allow users to choose which tags they want to filter on or is there just one tag you always want to search on? If it's only one tag, you could hard-code this into your page type template with something like this:
<?php
$tag = 'something'; //<-- the tag you want to search for
Loader::model('page_list');
$pl = new PageList();
$pl->sortByDisplayOrder();
$pl->filterByAttribute('tags', "%\n" . Loader::db()->escape($tag) . "\n%", 'LIKE');
$pages = $pl->get();
foreach ($pages as $page): ?>
  <p><a href="<?php echo View::url($page->getCollectionPath()); ?>"><?php echo $page->getCollectionName(); ?></a></p>
<?php endforeach; ?>


Sorry, I wish there were an easier answer :(
Danives replied on at Permalink Reply
To make it work in my code, I created a single page for displaying the page list. Then in the page list controller I added the following code in the 'getPages' query before it does the 'get'

<?php
if (isset($_GET['k'])) {
    $pl->filterByAttribute('tags', "%\n{$_GET[k]}\n%", "like");
}
?>


(Thats assuming that reading k as a get variable is your keyword).

I then created a new template for the tags block as follows:

<?php   defined('C5_EXECUTE') or die("Access Denied.");  ?>
<div class="ccm-tags-display">
<h4>Categories</h4>
<?php   if(strlen($title)) {
   ?><h2><?php   echo $title ?></h2><?php  
}
if($options instanceof SelectAttributeTypeOptionList && $options->count() > 0) {
   ?><ul class="ccm-tag-list">
      <?php   foreach($options as $opt) {
         $qs = $akc->field('atSelectOptionID') . '[]=' . $opt->getSelectAttributeOptionID();
         ?><li <?php   echo ($selectedOptionID == $opt->getSelectAttributeOptionID()?'class="ccm-tag-selected"':'')?>>
            <a href="<?php echo $this->url('the-news')?>?k=<?php  echo $opt; ?>"><?php   echo $opt ?></a></li><?php   
      }?>   
   </ul>
<?php   } ?>


'the-news' was the location of my single page. Then I added the page block on the one page I wanted it to show, and then added a tag cloud programmatically on my sidebar by coding in

<?php
   $bt_main = BlockType::getByHandle('tags'); 
   $bt_main->controller->displayMode = 'cloud';
   $bt_main->controller->cloudCount = 0;
   $bt_main->render('templates/categories');
?>


I hope that helps anyone who is trying to do the same thing, and doesn't confuse too much!
gd42 replied on at Permalink Reply
Hi! I know your comment is almost a year old, but I wanted to let you know, that it helped me lot.

I have one question: How can I use the hardcoded single page code with a custom Page List block template?
tiagovalverde replied on at Permalink Reply
tiagovalverde
Hello Danives,

The code that you referred worked for me.

if (isset($_GET['k'])) {
    $pl->filterByAttribute('tags', "%\n{$_GET[k]}\n%", "like");
}


But I put the code in a file of the core. How can I override this file?
/concrete/core/controllers/blocks/page_list.php

Thanks,
Tiago valverde
jordanlev replied on at Permalink Reply
jordanlev
If you need this functionality but aren't a coder at all, I think this addon from the marketplace will do what you want (but it's not free):
http://www.concrete5.org/marketplace/addons/ajax-page-tools/...
Danives replied on at Permalink Reply
Hey,

I have a similar issue, am trying to use the composer alongside a pagelist to create a 'blog' type effect. I have added the ability for tags to be placed on the posts, but for the life of me I can't figure out a way to filter the page list results by a selected tag.

I tried the suggested $pl->filterByTags() method but that doesn't work.

Have tried editing some of the core code but don't want to mess around too much if someone is aware of a simple solution.

Any help would be fantastic!

Dan
jordanlev replied on at Permalink Reply
jordanlev
How are people selecting the tag? Do you have a link somewhere, etc.?
Danives replied on at Permalink Reply
Hey Jordan,

I've just generated a tag block which outputs all the available tags - seeing as there is no functionality within that, I was then going to modify the view so it puts in a link to a single page of mine, passing through the keyword as a get variable.

Then I'd modify the page list controller so that if the get variable was set, to filter out by the specified keyword.

I'll try the code you provided in response to ollie and see if that does the trick :)

UPDATE: That code works great, thanks :)
admin replied on at Permalink Reply
This seems like a capability that would make sense in the core software. Is there a place to add feature requests? I found the bug tracker, but this is a new feature request, not a bug.
PatrickHeck replied on at Permalink Reply
PatrickHeck
You could post it as an issue at githubhttps://github.com/concrete5/concrete5/issues...
But I am not sure if this is the place where the core team wants feature requests to go...