Форматирование дат во Freemarker, где тип даты неизвестен

У меня есть функция Freemarker, цель которой - напечатать любое переданное ей значение, и у меня возникают трудности с обработкой дат, в частности.

Я понимаю, что когда Freemarker не может определить, какая часть даты используется, при попытке непосредственного вывода значения произойдет ошибка, поэтому для дат требуется определенный специальный регистр, но я не смог найти надежного обходного пути этой функции.

Моя функция выглядит примерно так:

<#function format value=''>
    <#if value?is_date>
        <#-- code to attempt to handle all types of date -->
    <#else>
        <#-- handle non-date values -->
    </#if>
</#function>

До сих пор я пробовал следующее:

Первая попытка: просто всегда печатать дату и время; например value?datetime

Проблема: бомбы, если значение уже "сказано", только на дату (например, format(value?date) - использование, которое я хочу поддержать)

Вторая попытка: попытка распечатать необработанное значение с использованием директив попытки / восстановления для обработки проблемных случаев; например

<#attempt>
    <#return value>
<#recover>
    <#return value?datetime>
</#attempt>

Проблема: директивы попытки / восстановления не удаются, ловят исключение - вместо этого это распространяется как прежде

Я пробовал много других вещей, но вышеупомянутые подходы были более разумными, и, к сожалению, ни один из них не был успешным. Кажется, есть ловушка-22: если тип даты неизвестен, я могу напечатать только, выбрав произвольный тип для применения ко всем значениям даты, но если я попытаюсь применить этот тип к дате известного типа, она потерпит неудачу где типы не совпадают.

Есть ли способ определить, известен ли тип даты значения, прежде чем пытаться напечатать значение? Если так, я мог бы использовать? Datetime, встроенный только тогда, когда это необходимо.

В идеале я мог бы попросить Freemarker просто напечатать полную дату, когда он не может определить точный тип, вместо бомбардировки - но я не уверен, что это в настоящее время возможно.

1 ответ

Решение

Обновление: в FreeMarker 2.3.21 вы можете использовать <#if value?is_date_like>${value?datetime_if_unknown}<#else>...

Да, должно существовать что-то вроде ?is_unknown_type_date, но это не так... Я - сопровождающий FM, поэтому я добавлю это в 2.3.21 (но не задерживайте дыхание, пока оно не выйдет). Между тем, вы можете написать TemplateMethodModelEx это делает именно это. Реализация этого тривиально, как вы увидите, как сделать их доступными для шаблонов, немного недокументировано... Один из способов - просто допинг TemplateMethodModelEx в модель данных или в набор "общих переменных" Configuration, Другой помещает это в некоторые из ваших обычно #importили #included шаблон как <#assign isUnknownTypeDate='com.example.IsUnknownTypeDateMethod'?new()>,

КСТАТИ, #recover у меня работает для этого (используется ночной 2.3.21, но я не помню, чтобы он когда-либо был сломан). Но не используйте его для этого в любом случае, так как это зарегистрирует ошибку. #recover только для аварийных ситуаций, а не для нормального выполнения программы.

Что касается предоставления формата по умолчанию для дат неизвестного типа... Я чувствую себя неловко по этому поводу, так как тогда эти проблемы не будут обнаружены во время разработки, и очень немногие будут использовать другую конфигурацию FM для производства, чем для разработки.

Другие вопросы по тегам