diff --git a/src/unfold/decorators.py b/src/unfold/decorators.py index e3304252..d5580edf 100644 --- a/src/unfold/decorators.py +++ b/src/unfold/decorators.py @@ -106,6 +106,7 @@ def display( dropdown: Optional[bool] = None, label: Optional[Union[bool, str, dict[str, str]]] = None, header: Optional[bool] = None, + template: Optional[str] = None, ) -> Callable: def decorator(func: Callable[[Model], Any]) -> Callable: if boolean is not None and empty_value is not None: @@ -129,6 +130,8 @@ def decorator(func: Callable[[Model], Any]) -> Callable: func.header = header if dropdown is not None: func.dropdown = dropdown + if template is not None: + func.template = template return func diff --git a/src/unfold/templatetags/unfold_list.py b/src/unfold/templatetags/unfold_list.py index 58a989b3..2492a5eb 100644 --- a/src/unfold/templatetags/unfold_list.py +++ b/src/unfold/templatetags/unfold_list.py @@ -32,6 +32,7 @@ display_for_field, display_for_header, display_for_label, + display_for_template, display_for_value, ) from unfold.widgets import UnfoldBooleanWidget @@ -229,6 +230,7 @@ def link_in_col(is_first: bool, field_name: str, cl: ChangeList) -> bool: label = getattr(attr, "label", False) header = getattr(attr, "header", False) dropdown = getattr(attr, "dropdown", False) + template = getattr(attr, "template", False) if label: result_repr = display_for_label(value, empty_value_display, label) @@ -238,6 +240,10 @@ def link_in_col(is_first: bool, field_name: str, cl: ChangeList) -> bool: ) elif header: result_repr = display_for_header(value, empty_value_display) + elif template: + result_repr = display_for_template( + value, empty_value_display, template + ) else: result_repr = display_for_value(value, empty_value_display, boolean) diff --git a/src/unfold/utils.py b/src/unfold/utils.py index 0851930f..92d81415 100644 --- a/src/unfold/utils.py +++ b/src/unfold/utils.py @@ -83,6 +83,24 @@ def display_for_label(value: Any, empty_value_display: str, label: Any) -> SafeT ) +def display_for_template( + value: dict, empty_value_display: str, template: str +) -> SafeText: + if not isinstance(value, dict): + raise UnfoldException("Display template requires dict") + + context = value or {} + + return mark_safe( + render_to_string( + template, + { + **context, + }, + ) + ) + + def display_for_value( value: Any, empty_value_display: str, boolean: bool = False ) -> str: