feat: add Liquid filter ordinalize

This commit is contained in:
Benjamin Nussbaum 2025-10-06 22:33:13 +02:00
parent 91e222f7a6
commit c1786dfb6d
3 changed files with 128 additions and 0 deletions

View file

@ -2,6 +2,7 @@
namespace App\Liquid\Filters;
use App\Liquid\Utils\ExpressionUtils;
use Carbon\Carbon;
use Keepsuit\Liquid\Filters\FiltersProvider;
@ -22,4 +23,33 @@ class Date extends FiltersProvider
return Carbon::now()->subDays($days)->toDateString();
}
/**
* Format a date string with ordinal day (1st, 2nd, 3rd, etc.)
*
* @param string $dateStr The date string to parse
* @param string $strftimeExp The strftime format string with <<ordinal_day>> placeholder
* @return string The formatted date with ordinal day
*/
public function ordinalize(string $dateStr, string $strftimeExp): string
{
$date = Carbon::parse($dateStr);
$ordinalDay = $date->ordinal('day');
// Convert strftime format to PHP date format
$phpFormat = ExpressionUtils::strftimeToPhpFormat($strftimeExp);
// Split the format string by the ordinal day placeholder
$parts = explode('<<ordinal_day>>', $phpFormat);
if (count($parts) === 2) {
$before = $date->format($parts[0]);
$after = $date->format($parts[1]);
return $before . $ordinalDay . $after;
}
// Fallback: if no placeholder found, just format normally
return $date->format($phpFormat);
}
}

View file

@ -158,4 +158,39 @@ class ExpressionUtils
return $expression;
}
/**
* Convert strftime format string to PHP date format string
*
* @param string $strftimeFormat The strftime format string
* @return string The PHP date format string
*/
public static function strftimeToPhpFormat(string $strftimeFormat): string
{
$conversions = [
'%A' => 'l', // Full weekday name
'%a' => 'D', // Abbreviated weekday name
'%B' => 'F', // Full month name
'%b' => 'M', // Abbreviated month name
'%Y' => 'Y', // Full year (4 digits)
'%y' => 'y', // Year without century (2 digits)
'%m' => 'm', // Month as decimal number (01-12)
'%d' => 'd', // Day of month as decimal number (01-31)
'%H' => 'H', // Hour in 24-hour format (00-23)
'%I' => 'h', // Hour in 12-hour format (01-12)
'%M' => 'i', // Minute as decimal number (00-59)
'%S' => 's', // Second as decimal number (00-59)
'%p' => 'A', // AM/PM
'%P' => 'a', // am/pm
'%j' => 'z', // Day of year as decimal number (001-366)
'%w' => 'w', // Weekday as decimal number (0-6, Sunday is 0)
'%U' => 'W', // Week number of year (00-53, Sunday is first day)
'%W' => 'W', // Week number of year (00-53, Monday is first day)
'%c' => 'D M j H:i:s Y', // Date and time representation
'%x' => 'm/d/Y', // Date representation
'%X' => 'H:i:s', // Time representation
];
return str_replace(array_keys($conversions), array_values($conversions), $strftimeFormat);
}
}