Show pages published by a time interval (day, week, month etc.) without a date field

Recommended Posts

Hello all.

I am trying to find a way to have a query with all pages that were published on a specific date (today for example). I read a few posts where people had a specific date field and were limitting the results by that, however is there a way to filter results without a specific date field? As far as I am able to publish the timestamp using $page->created logically I should be able to filter by the result of it? What is the best way to accomplish a filter for a day, week, month etc.?

Share this post

Link to post
Share on other sites
27 minutes ago, MilenKo said:

I read a few posts where people had a specific date field and were limitting the results by that, however is there a way to filter results without a specific date field?

It's the same, just replace $page->custom_date_field with $page->created or $page->published

  • Like 1

Share this post

Link to post
Share on other sites

@Robin S Thanks for the advise. I thought so, but I am getting an error on my code:

<ul class="cs-recipes"> 

$start = strtotime( date('Y-m-d') . " 00:00:00");
$end = strtotime( date('Y-m-d') . " 23:59:59");

if($pages->get('/recipes/')->children) {
$items = $pages->find("template=recipes-inner, $page->published>$start, $page->published<$end, sort=date, limit=9"); 
foreach($items as $rotd) { ?>

	<li class="cs-recipe">
		<div class="cs-recipe-image">
			<div class="cs-recipe-details-button">
				<a href="recipe_single_layout_1.html">Details</a>
			<img src="<?=$rotd->recipe_image->url?>" alt="<?=$rotd->recipe_image->description?>">
		<div class="cs-recipe-meta">
			<span><i class="fa fa-hourglass-half"></i> <?=$rotd->recipe_cooktime?></span>
			<span><i class="fa fa-cutlery"></i> <?=$rotd->recipe_servings?></span>
			<a href="<?=$rotd->httpUrl?>"><?=$rotd->title?></a>
<? } ?>

Any ideas where did I messed it up this time? :)

Share this post

Link to post
Share on other sites

From the documentation for selectors

// single condition
// pages published today, sorted new->old
$recentItems = $pages->find("template=product, my_date_field>=today, sort=-my_date_field");

// multiple conditions with AND operator
// pages published this year until today
$thisYear = date('Y-01-01'); // 2017-01-01 or 2011-01-01 etc
$recentItems = $pages->find("template=product, published>=$thisYear, published<=today");


Share this post

Link to post
Share on other sites

You shouldn't put $page-> in there, just use the name of the field. And your sort field must be an existing field.

$items = $pages->find("template=recipes-inner, published>=$start, published<=$end, sort=-published, limit=9"); 

Also you don't have to manually build the boundaries of today, you can just use today

$items = $pages->find("template=recipes-inner, published>=today, sort=-published, limit=9"); 

In fact, you can use any valid PHP date that you can use with DateTime constructor.

published>="April 8, 2013"
  • Like 4

Share this post

Link to post
Share on other sites

OK, that seemed to work and shows some results.

Now if I want to show dates 2 or 3 days ago, would it be correct to have $start = strtotime( date(('Y-m-d')-2) . " 00:00:00"); or there is a better/correct way of doing it? 

Also let's say I need to show the pages for last 7 days?

Share this post

Link to post
Share on other sites

You can use DateTime class.

$today = new \DateTime();
$aFewDaysAgo = $today->modify('-2 days');
$lastYear = $today->modify('-1 year');

$latestPages = $pages->find("published>=$aFewDaysAgo");
$pagesSinceLastYear = $pages->find("published>=$lastYear");


  • Like 3

Share this post

Link to post
Share on other sites

Ok, so it looks like DateTime class would do the trick if I ever want to present some pages in a specific timeframe.

Thanks again @abdus & @Robin S

Share this post

Link to post
Share on other sites

@abdus I tested your code using DateTime class, but am getting a server error 500:

        $today = new DateTime();
        $aFewDaysAgo = $today->modify('-2 days');
        if($pages->get('/recipes/')->children) { 
        $latest = $pages->find("template=recipes-inner, published>=$aFewDaysAgo, sort=-published, limit=9");

and the error in exceptions.txt is: Object of class DateTime could not be converted to string.

Share this post

Link to post
Share on other sites
4 hours ago, MilenKo said:

$today = new DateTime();

Without a backslash class names resolve to current namespace (ProcessWire), and since DateTime class is in global namespace, you should put \ before DateTime.

$today = new \DateTime();

Also, I've realized that I am getting the same error, but $pages->find() is still returning a result (because when DateTime object is converted to string it turns into an empty string '', and the selector becomes "published>'' ", which returns all pages). You can fix the error using:

$today = new \DateTime();

// use UNIX timestamps
$aFewDaysAgo = $today->modify('-2 days')->getTimestamp();
$lastYear = $today->modify('-1 year')->getTimestamp();

// or convert to ISO format
// $aFewDaysAgo = $today->modify('-2 days')->format('c');
// $lastYear = $today->modify('-1 year')->format('c');

$latestPages = $pages->find("published>=$aFewDaysAgo");
$pagesSinceLastYear = $pages->find("published>=$lastYear");


  • Like 5

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By szabesz
      I moved a site to a new home and ran into a "strange" issue:

      No field is added. I have no error message "anywhere", not in the console, no PHP, not in server logs either.
      The strange thing is that I can Duplicate fields: Setup > Fields > Actions > Duplicate/clone this field?
      Meaning it is just the "Add New Field" which does nothing. I can also create pages.
      Also,  "Add New Field" does work in local development environment (same site and "same state", of course), it is just the new server environment which is problematic.
      Any ideas for troubleshooting? Thanks in advance
    • By dscONE
      Found myself needing to filter repeater items based upon start and end date fields.  These fields aren't required, so repeater items with no dates should be included and those with dates (or a just one date -- start or end) should be evaluated for inclusion.
      I slowly figured out that I was dealing with in-memory filtering (of a RepeaterPageArray) and not a database-driven operation.  So, that eliminated the possibility of using or-groups in my selector.  I still thought I could use the 'filter' and 'not' functions to get the job done.  Turns out the way selectors are handled for in-memory filtering is quite different from database-driven selectors.
      Here is what I want(ed) to do to filter the dates:
      // Start date not specified or in the past $repeater->filter('start_time<='.$now); // Not when end date is specified and has passed $repeater->not('end_time>0, end_time<'.$now); The first one worked exactly as expected.  The second it where I ran into problems.  The 'filter' function (which calls the 'filterData' function) takes a $selector argument.  From everything I read about selectors, I assumed that the entire selector would have to match.  In other words, each comma represented an 'and' scenario.  Turns out that each separate comma-separated-selector in the $selector as a whole gets evaluated independently.  In the case of the 'filterData' function, the elements are removed if any one of those selectors matches.  Essentially, we have an 'or' scenario instead of an 'and' scenario.
      In my case above, there was no way for me to filter for a non-empty date AND one that occurs before a given least that I could think of.
      So, my main question is if the filter (and related) function should operate on the entire selector passed to the function instead of its individual parts in some sequence.  That is what I would have assumed a selector to do.
      In my project, altering the segment of the WireArray::filterData function solved my problem for now. least till I forget about it and overwrite it when I upgrade next.  Here is the code I changed within the function
      // now filter the data according to the selectors that remain foreach($this->data as $key => $item) { $filter_item = true; foreach($selectors as $selector) { if(is_array($selector->field)) { $value = array(); foreach($selector->field as $field) $value[] = (string) $this->getItemPropertyValue($item, $field); } else { $value = (string) $this->getItemPropertyValue($item, $selector->field); } if($not === $selector->matches($value)) continue; $filter_item = false; break; } if($filter_item && isset($this->data[$key])) { $this->trackRemove($this->data[$key], $key); unset($this->data[$key]); } } I would love to hear what you all think.  If I have misunderstood something, then I would welcome a different solution.
    • By joelplambeck
      Hello everyone,
      My Website works just fine beside the one field which behaves strangely and I can't figure out why.
      I have a template called "main-subpage" which I use for most subpages. All of them have a header and on every other Page it works just fine.
      But on the one page it displays the first few letters random and sometimes the last ones corectly, sometimes the last ones are wrong as well. What iritates me is that this is only on the one Page and all the other pages with the same template don't have that issue. The rest of the page is displayed just fine.
      I tried different content in the field but it doesnt seem to help anything.
      Code in the template:
      <h1> <?php echo $page->header | $page->title; ?> </h1> on the page it should display: "Das Konzept des ZiSMed" but what I see is (attachement):
      Thank you for your help!
    • By pppws
      hey there,
      i'm using processwire for the first time, so maybe it's a dumb question. but i'm trying to have an options field which values are the users of the processwire. i don't need the values to be displayed, it's just for the administration of the page. but each time a new user is created / a user is deleted the options field should be updated automatically. is something like that possible?
    • By Sipho

      I have an issue where I want different formats for creating one page. When you are creating a new page I want it to offer different types of fields from when you are editing it.
      For example, I have a field called countries which is a multiple page reference field. This is desirable as it is in a very easy to edit format. Currently, I am using selectize.js which makes it possible to search for the pages and add them in a tag fashion. This is how I want it to be when a page is already created. However, when creating a new page it is often easier to just paste a list of all the countries as text. This is because the data is coming from an old website where the countries are written like this:
      I can code something which converts this text into the multiple page reference fields but I am not sure how to go about it. At first I tried making another template which had fields that were in this “quick” format. Then I planned to make it such that when you add one of these quick pages it creates a page in the standard format and deletes itself. This has it’s own problems such as where to place the new page, what title and name to give it, whether to have just one quick page or multiple and when to delete it. It just didn’t seem right. 
      Another possibility would be to show special quick fields when creating a new standard page but hide them when the page is saved and show the standard fields. I am not to sure how to achieve this though. 
      Does anyone know a better way of going about this? I feel like this is a simple problem which already has an elegant solution.