Sort by time from a precise hour

Hi everyone,

I’m using the blueprint “time” and the sortBy() string. It’s working perfectly to organize the items. However, I need to begin the classification from a specific hour. For the instant, it begin at 00:00. I read the sorting and grouping page without find the answer.

Thank you for your help,
Simon.

You posted a link to the docs for sorting a structure field, but make no mention of them in your question. Is your “time” field inside a structure field?

I think you need to find the first one after the time you wish to start the list, get its index and use that use that number as an offset.

Yes, what I’m calling “time” is the structure field

horaire:
label: horaire
type: time
width: 1/3
interval: 15
format: 24

I’m reading your links “get its index” and “offset”, understand the principle but I’m not sure to know how to apply it. I don’t think I will need the “offset” function because I don’t need to hide anything, just to declare the start hour of the list. Still searching. Thank you Jimbobrjames.

I guess I need something like the php.net exemple

<?php $array = array(0 => 'blue', 1 => 'red', 2 => 'green', 3 => 'red'); $key = array_search('green', $array); // $key = 2; $key = array_search('red', $array); // $key = 1; ?>

Im a little confused, that looks like a time field. Could you please post the entire blueprint for the page?

Yes here it is:

Entire blueprint with "horaire"

title: Article

pages: true
:
num:
mode: time
field: added

fields:
title:
label: Title
type: title

coverimage:
label: Cover Image
type: image
width: 1/3

jour:
label: jour
type: title
width: 1/3

horaire:
label: horaire
type: time
width: 1/3
interval: 15
format: 24

scene:
label: scene
type: select
options:
stage 1: stage 1
stage 2: stage 2

website:
label: website
type: title
width: 1/3

bandcamp:
label: bandcamp
type: title
width: 1/3

soundcloud:
label: soundcloud
type: title
width: 1/3

text:
label: text
type: textarea

and the php is:

<?php $vendredi = page('vendredi')->children()->visible()->sortBy('horaire','asc'); if(isset($limit)) $vendredi = $vendredi->limit($limit); ?>
<?= $vendredi->horaire()->html() ?>

It would be helpful if you post the code you already have as a starting point, otherwise we don’t know what you want to filter.

Anyway, what you want to do here is filterBy() the horaire field, i.e. filter by any pages in the collection that have a horaire value greater then the given one, then sort your remaining pages.

This doesn’t make sense. From your above, it looks as if $vendredi is a collection of pages, not a single page. Or is this inside a foreach loop?

Yes it’s inside a foreach loop

<?php foreach($vendredi as $vendredi): ?>

I will consider the filterBy() function right now

Please, please NEVER use the same variable for the array expression(array or object you want to loop through) and the value, (foreach($array_expression as $value))this is really confusing and can have really unexpected results, especially if you want to use your original variable inside the loop again*.

<?php foreach($vendredi as $event): ?>

or whatever. I already explained that above

I think you have to use a custom filter with callback function here, because you will have to convert your time to a Unix timestamp first.

$vendredi = $page->children()->filter(function($child) {
  return strtotime($page->horaire()) >=  strtotime('5:00');
 })->sortBy('horaire', 'asc');

foreach($vendredi as $event) {
  echo $event->horaire();
}

* Consider this code example. It should make very clear why you shouldn’t do this:

foreach($vendredi as $vendredi) {
  // let's try to get the index of the item (the second $vendredi) within the collection(the first $vendredi)
  $index = $vendredi->indexOf($vendredi);
  // oops, error, now $vendredi is no longer a collection but a single item, so our call to `index()`will fail.
}

This would definitely throw an error, because in this example, indexOf() is a collection method that we want to call on the $vendredi collection, not on the value inside the loop.

I fixed that dumb syntax, sorry.
I replaced the YAML element “time” for “datetime” so I can use the Unix timestamp format.
I’ll try now to use your custom filter with callback function. I’ll let you know.
Thank you Texnixe.