-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Can't use custom date header #1641
Comments
This is actually to be expected. When using a custom field to order by, Grav really has no clue what type of field that is, so it's not smart enough to convert it do a date and compare it that way. One way to fix this would be to store the custom date field as a timestamp. |
@rhukster Maybe you can add |
It's uncomfortable for reading or changing such date by a human. I see two ways to solve this problem:
|
You can already convert a date to a time stamp. https://stackoverflow.com/questions/9242072/how-can-i-convert-a-date-to-a-unix-timestamp-with-twig |
@Sogl |
@rhukster In latest Grav 1.3.8 I can use this code But I'm still can't order collections by custom date header. I found a workaround:
<?php
namespace Grav\Theme;
use Grav\Common\Grav;
class CollectionSorter
{
protected $grav;
protected $field;
protected $asc;
public function __construct() {
$this->grav = Grav::instance();
}
public function byDate($collection, $field, $asc = true)
{
$this->field = $field;
$this->asc = $asc;
$array = [];
foreach($collection as $p) {
$array[] = $p;
}
usort($array, function($a, $b) {
if (!isset($a->header()->{$this->field}, $b->header()->{$this->field})) {
return 0;
}
$valA = $a->header()->{$this->field};
$valB = $b->header()->{$this->field};
if ($valA == $valB) {
return 0;
}
if ($this->asc) {
return strtotime($valA) - strtotime($valB);
}
return strtotime($valB) - strtotime($valA);
});
return $array;
}
}
public function onTwigSiteVariables()
{
require_once __DIR__ . '/class/CollectionSorter.php';
$this->grav['twig']->twig_vars['sorter'] = new CollectionSorter();
}
{% set asc_order = sorter.byDate(page.collection, 'custom_date_field') %}
{% set desc_order = sorter.byDate(page.collection, 'custom_date_field', false) %} But what if I want to handle things like |
Devs please @rhukster @w00fz @OleVik @flaviocopes @mahagr I returned to my project and still can't sort custom header dates with built-in functional 😢 I saw much similar issues: For now.
in items: //tour 1
returnDate: '31-08-2018 23:01'
//tour 2
returnDate: '30-07-2018 23:01'
//tour 3
returnDate: '01-08-2018 23:01' In frontmatter: nearest:
items:
'@page.children': '/tours'
dateRange:
start: today
field: header.returnDate in twig: {% set nearest_collection = page.collection('nearest')
.order('header.returnDate', 'desc', null, 1) %}
{% for tour in nearest_collection %}
{{ dump(tour) }}
{{ dump(tour.header.returnDate) }}
{% endfor %} Tried to change No way:
Also tried to disable this thing: Maybe any of you @inktrap @erichgoldman @tboulogne @akoebbe @vitopepito |
@Sogl I just tried this out in the Custom item headers (note the years): #item 1
custom_date: '01/01/2010'
#item 2
custom_date: '02/01/2010'
#item 3
custom_date: '03/01/2019'
#item 4
custom_date: '04/01/2019' Collection definition (used a blog page for this test): content:
items: '@self.children'
order:
by: header.custom_date
dir: desc
dateRange:
start: today
field: header.custom_date
pagination: true
url_taxonomy_filters: true With this set up I only see two items on the page and they are sorted as expected. |
@akoebbe Try different dates and months, not only years. Looks like Grav uses string comparsion for custom fields.
It should be:
Wrong (my situation):
|
So are you saying you're using |
I tried only with dashes and also with dots (see 1st msg here). |
Ok. I see what you're saying. Here is a more clear example... #item 1
custom_date: '01/01/2010'
#item 2
custom_date: '03/01/2010'
#item 3
custom_date: '02/01/2020'
#item 4
custom_date: '04/01/2019' is sorted...
So the question is can you use an ISO9601 format instead |
I also wonder if it would be reasonable to pull a blueprint field definition in to know how to cast the value... OR add a property content:
items: '@self.children'
order:
by: header.custom_date
value_type: date
dir: desc |
I just did some testing and ISO 9601 formatted dates work with both sorting and range limits using the dates my last example above. |
I'm open to hearing what other devs think about either option I mentioned above for a real solution. Perhaps there are other options? |
Date fields on the page frontmatter are strings and as such, they are always ordered as strings, not dates. There is really no way to do anything about it as pages aren't aware of field content type, which makes the proper comparison not possible. I am personally aware of this issue and we have plans to replace current page logic with something better in upcoming versions (= 2.0). BTW: be careful when using dashes in the dates: it's in American format: |
@mahagr could we not tap into the blueprint to inform sorting? |
Blueprints are not used really outside of CRUD (admin). |
For great ordering you can add option "format" and set like this header.event.start_datetime: |
I'm confused as to is there a solution to this problem? I'm in the exact same situation. Building a page for a customer and stuck on this. |
As I said, there is a general solution in works and it will be part of Grav 2.0. In the meantime, the only way to fix this would be to add an attribute to the ordering which tells that the field is a date and should be ordered after converting it to |
Thanks. I ended up using Sogl's solutions and his CollectionSorter class... |
I modified Sogl's solution a little to be compatible with the https://github.com/getgrav/grav-plugin-pagination Plugin, I know it's a bit dirty recreating the collection, but I did not found any better solution without adding a "setItmes" method to the Collection class: `<?php use Grav\Common\Grav; class CollectionSorter public function __construct() { public function byDate($collection, $field, $asc = true)
} The rest remains as described in #1641 (comment) In combination with pagination: |
Out of interest @Hydraner — where would I start in terms of a php fix for this, I wasn't sure where your php code would go? Presumably here? |
Hi!
I found a problem.
If I have
date: 09.02.2017
in blog post header and this code:than my sorting works correctly.
{{ dump(post.header.date) }}
shows me timestamp date.But if I have custom date header like
releaseDate
and order by this header, then sorting breaks down. For example,01.09.2012
is older then09.02.2017
.{{ dump(post.header.releaseDate) }}
shows me string date as is.Later @flaviocopes told me to use
Y.m.d
format (2017.02.09
for example). This temporarily resolved my problem until I want to output the date in the post.I put
{{ dump(page.header.releaseDate|date('d')) }}
line in twig and see an error:How to fix?
p.s. Same problem in the forum:
https://discourse.getgrav.org/t/date-format/1555/8
The text was updated successfully, but these errors were encountered: