Pluck datefields

Hello,
I try to pluck datefields by years:

$exhibits = $pages->findBy('autoid', '4')->children()->sortby('startdate', 'desc');
$years = $exhibits->pluck(date('Y','startdate'), 'true'); 

this is not working.

this works, but I need later only the year
$years = $exhibits->pluck('startdate', 'true');

before I was using:

$years = array();
  foreach($exhibits as $exhibit ): 
  $date = $exhibit->date('Y','startdate');
  array_push($years, $date);
endforeach; 
$years = array_unique($years);

but this seems a bit long-winded?!

You can only pass a field name to the pluck() method, so this indeed won’t work, I’m afraid.

Okay, thank you
then I know this. :slight_smile:

You could use pluck together with PHP’s array_map() though.

Now I have:

foreach ($years as $year): 
  $year = substr($year, 0, 4);

to fetch the year. How can I work with array_map()?

That would be something like this:

$exhibits = $pages->findBy('autoid', '4')->children()->sortby('startdate', 'desc');
$years = $exhibits->pluck('startdate', true);
$years = array_map(function($item) {
  return date('Y', $item);
}, $years);

thanks a lot, this is not working,
I think the returned value of ->pluck('startdate') is a string?!

But I made it with substr():

$years = array_unique(array_map(function($item) {
  return substr($item, 0, 4);
}, $years));

Try this:

$exhibits = $pages->findBy('autoid', '4')->children()->sortby('startdate', 'desc');
$years = $exhibits->pluck('startdate', ',', true);
$years = array_map(function($item) {
  return date('Y', strtotime($item));
}, $years);
2 Likes

Yesss, this works :grinning:

And to only get unique years:

$years = array_unique(array_map(function($item) {
  return date('Y', strtotime($item));
}, $years));

This is what I have now:

// get all exhibition years
$years = $exhibits->pluck('startdate');
$years = array_unique(array_map(function($item) {
   return date('Y', strtotime($item));
}, $years));

Hi, first post here. I’m having the same problem.
When I implement the code mentioned above I receive the following error messages:

Warning: array_map(): Argument #2 should be an array in /Applications/MAMP/htdocs/xxx/site/templates/calendar.php on line 14

Warning: array_unique() expects parameter 1 to be array, null given in /Applications/MAMP/htdocs/xxx/site/templates/calendar.php on line 14

I can openly admit being a .php and kirby noob, any help or pointers are very welcome.

Until now my code looks like this:

  <?php
  foreach(page('projects')->children()->sortBy('dates', 'desc')->visible() as $subpage): 
  $dates = $subpage->dates()->toStructure()->limit(1);
  foreach($dates as $date): ?>

<?php
$years = $subpage->pluck('opendate', ',', true);
$years = array_unique(array_map(function($item) {
  return date('Y', strtotime($item));
}, $years)); ?>

  <li>

    <a href="<?php echo $subpage->url() ?>">
   	  <?php echo $years ?>
      <?php echo $date->date('M d', 'opendate') ?>

Which is a bit sloppy, but getting there. I’m guessing that I have to turn the pluck into an array, and also define $item (?).

Thanks!

The problem here is that you are trying to pluck the dates from a single field whereas this method is meant to get the values of one field from a collection of pages.

Is opendate a field in a structure field? Could you pls. provide some more information?

Yes, opendate is a date field in a structure field.

I’m trying to output a list of projects with a opendate field, where the year is only printed once but the month and date are printed along side the project title, like this:

2016

OCT 12 – Project A
SEP 09 – Project B

2015

MAY 09 – Project C
JAN 02 – Project D

Hope this provides sufficient information.

Could you please post the blueprint of the page with the structure field? How do project name and those dates relate?

title: Project
pages: false
files:
  fields:
      space:
        label: Space Before
        type: checkbox
  sortable: true
fields:
  title:
    label: Title
    type:  text
  description:
    label: Description
    type:  text
  text:
    label: Text
    type:  textarea
  dates:
    label: Dates
    type: structure
    entry: >
      {{date}}<br />
      {{venue}}<br />
      {{city}}
    fields:
      opendate:
        label: Date
        type: date
      venue:
        label: Venue
        type: text
      city:
        label: City
        type: text
  media:
    label: Media embeds
    type: text
  tags:
    label: Tags
    type:  tags

Each project can have multiple date entries.
Does this make sense?

Well, here is a possible solution, there probably a less complicated way to achieve that:

<?php
$subpages = page('projects')->children()->visible();

// get all opendates from all pages' structure fields
foreach($subpages as $subpage):
  $dates = $subpage->dates()->yaml();
  foreach($dates as $date):
    $years[] = $date['opendate'];
  endforeach;
endforeach;
// only get unique years
$years = array_unique(array_map(function($item) {
  return date('Y', strtotime($item));
}, $years));
// sort years
sort($years);
?>


<?php
// loop through years
foreach($years as $year): ?>
  <h2><?= $year ?></h2>
  <?php foreach($subpages as $subpage):
    // get array items with key opendate
    $opendates = array_column($subpage->dates()->yaml(), 'opendate');

      foreach($opendates as $date):
        if(date('Y', strtotime($date)) == $year): ?>
          <li>
            <span><?= date('M d', strtotime($date)) ?> -- </span>
            <a href=""><?=$subpage->title()->html() ?></a>
          </li>
        <?php else:
          continue;
        endif;
      endforeach;
  endforeach;
endforeach;
?>

Thank you! It took me a while to comprehend your code, and it works magically!

Since implementing it I’ve tried to devise how to print the projects in chronological order (taking in account the months and days), right now the code produces this:

2016
Jul 28 – Hmm
Jul 26 – Hmm
Apr 25 – Hmm
May 14 – Las casas del ferrocarril
Sep 23 – Palace Ruin
May 20 – RRRRR
May 18 – RRRRR
Feb 24 – RRRRR
Feb 23 – RRRRR
Mar 05 – 10’01’’

But I’d like it to do this:

2016
Sep 23 – Palace Ruin
Jul 28 – Hmm
Jul 26 – Hmm
May 20 – RRRRR
May 18 – RRRRR
May 14 – Las casas del ferrocarril
Apr 25 – Hmm
Mar 05 – 10’01’’
Feb 24 – RRRRR
Feb 23 – RRRRR

I’ve tried to use rsort($dates), but I’m guessing it’s a product of using foreach, which fetches each project as they are structured in the content-folder? Is it even possible to do this?

Thanks again :blush: