filter PageList by Date attribute

Permalink 2 users found helpful
hey,
i got stuck a bit once again with filtering a pagelist.

i have a lot of pages to which i added a custom date attribute (every page is gigs-date of a band)

now i have another page with 2 different pagelists on it.

one should list all pages with a date_value in the future (including the actual day)

the other one should show all pages with date_values in the past.

so in the end i have a gigs-page with one list for upcoming shows, and one for past shows, which finally updates itself automatically (that was the idea behind).

any ideas anybody? would be great!

VortexSurfer
 
VortexSurfer replied on at Permalink Reply
VortexSurfer
nobody anything?

i already spend hours in the forum checking for possible solutions and tried different codes, but nothing worked finally.

actually would also help to just use the public date for this filtering action, do not have to be a custom date attribute.
synlag replied on at Permalink Reply
synlag
VortexSurfer replied on at Permalink Reply
VortexSurfer
thanks a lot. but does not really help me, and i already have this before.

it's a bit confusing what is written there because it's mostly about the search block and als the calendar block.

but i would prefer using a simple pagelist.

you think it is possible with this?

so far i only added/modified the code of the view.php. do i also have to change the controller.php?

and as said before ... if easier to realize i can also use the Public Date for filtering.
VortexSurfer replied on at Permalink Reply
VortexSurfer
this code-snippet i also found in the forum herehttp://www.concrete5.org/community/forums/block_requests/improved_p...

<?php  
$pageList = Loader::model('page_list'); 
$pageList = new PageList();
$pageList->filterByPublicDate(date('Y-m-d 0:00:00',(date('U')+60*60*24*36)), '<');
$pages= $pageList->get();
 ?>


sounded good to me, but did not affect anything.

what i'm doing wrong?
ijessup replied on at Permalink Reply
ijessup
You are very close, but it would appear you don't have a full understanding of how the page list object works. If my assumption is wrong, I apologize, but I'll try to explain how it works by solving your request.

What you just did was filter a page list based on the date you published it, or rather the date it went public - filterByPublicDate().

What you want to do is sort a page list based on an attribute - sortByAttribute(). Specifically "date_value" or "gig_date" - what ever the attribute's handle.
Loader::model('page_list');
$pageList = new PageList();
$pageList->filterByCollectionAttribute('date_value');
$pageList->sortByCollectionAttribute('date_value');
$pages = $pageList->get();
First, we load the page list model.
Second, we create a new PageList object;
Third, we filter out every page that doesn't have the date_value attribute associated to it.
Fourth, we sort the page list based on the date_value object.
Last, we set $pages as the array of pages from the list.

By default the list is sorted ascending, but you can make it descending by using
$pageList->sortByCollectionAttribute('date_value', 'desc');
instead.
VortexSurfer replied on at Permalink Reply
VortexSurfer
it might be right that i did not really undertstand the page list object, but ....

actually i don't want to sort my pagelist results (i can easily do this via "edit" the block, so that's not my problem.)

i defintly want to filter the list! i only want to show result that have a date_value (public date or a costum date attribute)in the future!

the i want to do a second list, which only shows the results with a date_value in the past.

tried everything, but i don' get it.
RadiantWeb replied on at Permalink Reply
RadiantWeb
I would do as jess suggested. then what you have is an array with all pages that have a date.

Then create a custom view to sort that with an if/else to the effect of:

foreach($pages as $page){
  if($page['gig_date']>= date('m/d/y')){
    {FUTURE DATES HTML HERE}
  }
}


and for past dates do the opposite:

foreach($pages as $page){
  if($page['gig_date']< date('m/d/y')){
    {PAST DATES HTML HERE}
  }
}


there is a tutorial I posted a while back that walks through how to safely create custom views of blocks.

Chad
ijessup replied on at Permalink Reply
ijessup
Ok, I follow you now. That's easy. :p
Loader::model('page_list'); 
$pageList = new PageList();
$pages = array();
foreach($pageList->get() as $page) {
   if(strtotime($page->getCollectionAttributeValue('date_value')) >= time()) {
      array_push($pages, $page);   
   }
}
ijessup replied on at Permalink Reply
ijessup
Sorry, didn't explain whats going on...

Rather than filtering and sorting with c5's API, all I'm doing here is simply adding pages from a page list to the $pages array if the time of 'date_value' is greater than the current time.

Technically, this is filtering. And there is a way to do this with the API, but how to do that escapes me. I will look up the filtering by comparing function and report back, but this should work for you.
VortexSurfer replied on at Permalink Reply
VortexSurfer
sorry, i still do not get it.

creating a custom view is not the problem. i use it a lot. and also this pagelist-block i want to filte now is alreday a custom view.

but i dont't get what's to do with the codes you posted1? i tried different variatons, but only error messages or no filtering happens! :(

your last code:
<?php
Loader::model('page_list');
$pageList = new PageList();
$pages = array();
foreach($pageList->get() as $page) {
if(strtotime($page->getCollectionAttributeValue('date_value')) >= time()) {
array_push($pages, $page);
}
}
?>

i just have to put it in my view.php or what?
ijessup replied on at Permalink Best Answer Reply
ijessup
Place
$pageList = $cArray;
$cArray = array();
foreach($pageList as $page){
   if(strtotime($page->getCollectionAttributeValue('date_value')) >= time()) {
      array_push($cArray, $page);   
   }
}
right after
defined('C5_EXECUTE') or die(_("Access Denied."));
in your custom template.
ijessup replied on at Permalink Reply 1 Attachment
ijessup
Custom page_list template attached.

Unzip date.php to the /blocks/templates folder

Tested and works without errors on c5.4.0.5
VortexSurfer replied on at Permalink Reply
VortexSurfer
works just ..... WONDERFULL!!! THANKS A LOT!!!

once again i see, there s still a lot to learn.
VortexSurfer replied on at Permalink Reply
VortexSurfer
for my "gigs"-page where all shows are listed and just seperated in past and future shows this works totally wonderful nice!

but on my home-page i have another list which shows also the shows in the future, but only the next 2 or 3 ones.

there this method makes the shows disappear, i guess because also the past shows, which gut pushed away, are counted into the number of results to show.

any idea how to solve this? any chance to just modify the code? or does this method just not work in this case?
ijessup replied on at Permalink Reply 1 Attachment
ijessup
You are absolutely right.

You gotta understand that the PageList class and the page_list block are 2 separate things.

What is happening is: you generate a PageList when a page_list block is initialized. When we render this block the PageList gets used to create an array of Pages(technically its actually an array of Collections). The array is what gets modified/used by template code.

We should be using
$pageList->filterByCollectionAttribute('date_value', date(y-m-d).'00:00:00', '<=');
but unfortunately, the date attribute gets stored in the database as a string rather than a number. Consequently this filtering function is practically unusable. Very silly, IMO.

Honestly, I would write a whole new block at this point, because all we are using the page_list block for is a way to store variables.

And we don't have a way to order the pages other than by their site map order.

However, as long as you don't use pagination, the attached template should work.
VortexSurfer replied on at Permalink Reply
VortexSurfer
wow wow, works as smooth and wonderful as the other file you attached before.

again thanks a lot.
leinteractive replied on at Permalink Reply
leinteractive
So would this method work to also only display a single page based on date?

I'm listing a bunch of concerts on the Concert page, but on the homepage, I only want the next concert coming up to be displayed.

Wouldn't this do the same thing if I just tell the controller to only display 1 page from the list and let the code posted above filter out everything that isn't current?
TRRosen replied on at Permalink Reply
as a reference to others that might find this page the code needed is

$pl->filterByAttribute('attribute_handle', date("Y-m-d G:i:s", mktime(0, 0, 0, $month, $day, $year)) , '>')


In this case $month,$day and $year hold the numeric values for the date in question and the time is 12am. Datetime attributes are not really saved as plain text they are SQL datetimes that are text encoded so you have to encode the comparison date to SQL format.
To match the day on datetime attributes you need 2 filters to create a range from 12am to 11:59pm.