feat: Add custom Tera filters for date/time formatting
- Add three new Tera filters: `format_hour`, `extract_hour`, and `format_time` for flexible date/time formatting in templates. - Improve template flexibility and maintainability by allowing customizable date/time display. - Enhance the user experience with more precise date/time rendering.
This commit is contained in:
@@ -26,11 +26,16 @@ impl std::fmt::Display for TemplateError {
|
||||
|
||||
impl std::error::Error for TemplateError {}
|
||||
|
||||
/// Registers custom Tera functions
|
||||
/// Registers custom Tera functions and filters
|
||||
pub fn register_tera_functions(tera: &mut tera::Tera) {
|
||||
tera.register_function("now", NowFunction);
|
||||
tera.register_function("format_date", FormatDateFunction);
|
||||
tera.register_function("local_time", LocalTimeFunction);
|
||||
|
||||
// Register custom filters
|
||||
tera.register_filter("format_hour", format_hour_filter);
|
||||
tera.register_filter("extract_hour", extract_hour_filter);
|
||||
tera.register_filter("format_time", format_time_filter);
|
||||
}
|
||||
|
||||
/// Tera function to get the current date/time
|
||||
@@ -140,6 +145,69 @@ impl Function for LocalTimeFunction {
|
||||
}
|
||||
}
|
||||
|
||||
/// Tera filter to format hour with zero padding
|
||||
pub fn format_hour_filter(
|
||||
value: &Value,
|
||||
_args: &std::collections::HashMap<String, Value>,
|
||||
) -> tera::Result<Value> {
|
||||
match value.as_i64() {
|
||||
Some(hour) => Ok(Value::String(format!("{:02}", hour))),
|
||||
None => Err(tera::Error::msg("Value must be a number")),
|
||||
}
|
||||
}
|
||||
|
||||
/// Tera filter to extract hour from datetime string
|
||||
pub fn extract_hour_filter(
|
||||
value: &Value,
|
||||
_args: &std::collections::HashMap<String, Value>,
|
||||
) -> tera::Result<Value> {
|
||||
match value.as_str() {
|
||||
Some(datetime_str) => {
|
||||
// Try to parse as RFC3339 first
|
||||
if let Ok(dt) = DateTime::parse_from_rfc3339(datetime_str) {
|
||||
Ok(Value::String(dt.format("%H").to_string()))
|
||||
} else {
|
||||
// Try to parse as our standard format
|
||||
match DateTime::parse_from_str(datetime_str, "%Y-%m-%d %H:%M:%S%.f UTC") {
|
||||
Ok(dt) => Ok(Value::String(dt.format("%H").to_string())),
|
||||
Err(_) => Err(tera::Error::msg("Invalid datetime string format")),
|
||||
}
|
||||
}
|
||||
}
|
||||
None => Err(tera::Error::msg("Value must be a string")),
|
||||
}
|
||||
}
|
||||
|
||||
/// Tera filter to format time from datetime string
|
||||
pub fn format_time_filter(
|
||||
value: &Value,
|
||||
args: &std::collections::HashMap<String, Value>,
|
||||
) -> tera::Result<Value> {
|
||||
let format = match args.get("format") {
|
||||
Some(val) => match val.as_str() {
|
||||
Some(s) => s,
|
||||
None => "%H:%M",
|
||||
},
|
||||
None => "%H:%M",
|
||||
};
|
||||
|
||||
match value.as_str() {
|
||||
Some(datetime_str) => {
|
||||
// Try to parse as RFC3339 first
|
||||
if let Ok(dt) = DateTime::parse_from_rfc3339(datetime_str) {
|
||||
Ok(Value::String(dt.format(format).to_string()))
|
||||
} else {
|
||||
// Try to parse as our standard format
|
||||
match DateTime::parse_from_str(datetime_str, "%Y-%m-%d %H:%M:%S%.f UTC") {
|
||||
Ok(dt) => Ok(Value::String(dt.format(format).to_string())),
|
||||
Err(_) => Err(tera::Error::msg("Invalid datetime string format")),
|
||||
}
|
||||
}
|
||||
}
|
||||
None => Err(tera::Error::msg("Value must be a string")),
|
||||
}
|
||||
}
|
||||
|
||||
/// Formats a date for display
|
||||
#[allow(dead_code)]
|
||||
pub fn format_date(date: &DateTime<Utc>, format: &str) -> String {
|
||||
|
||||
Reference in New Issue
Block a user