Skip to content

Fields

components.fields

Various field components for read-only data display and formatting.

AccordianField

Bases: Field

A collapsible accordion panel.

Source code in components/fields.py
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
class AccordianField(Field):
    """A collapsible accordion panel."""
    def __init__(self, title: str | None = None, **kwargs):
        super().__init__(**kwargs)
        self.title = title

    def render_html(self, **kwargs) -> str:
        return f'''
        <div id="{self.uid}" class="{self.classes}">
            <div class="collapse collapse-arrow bg-base-200">
                <input type="checkbox" />
                <div class="collapse-title font-semibold">
                    {self.title}
                </div>
                <div class="collapse-content">
                    {"".join([child.build().render(**kwargs) for child in self.children])}
                </div>
            </div>
        </div>
        '''

CheckboxField

Bases: Field

Displays a boolean value as a check or cross icon.

Source code in components/fields.py
91
92
93
94
95
96
97
class CheckboxField(Field):
    """Displays a boolean value as a check or cross icon."""
    def render_html(self, **kwargs) -> str:
        value = self.get_value(**kwargs)
        if value:
            return f'<span id="{self.uid}">{{% heroicon_mini "check-circle" class="text-success" %}}</span>'
        return f'<span id="{self.uid}">{{% heroicon_mini "x-circle" class="text-error" %}}</span>'

DateField

Bases: Field

Formats and displays a date object.

Source code in components/fields.py
65
66
67
68
69
70
71
72
73
74
75
class DateField(Field):
    """Formats and displays a date object."""
    def render_html(self, **kwargs) -> str:
        value = self.get_value(**kwargs)
        if value is None:
            return ""
        if isinstance(value, date):
            value_str = value.strftime("%d %B, %Y")
        else:
            value_str = str(value)
        return f"{{% verbatim %}}{value_str}{{% endverbatim %}}"

DateTimeField

Bases: Field

Formats and displays a datetime object using timezone localization.

Source code in components/fields.py
51
52
53
54
55
56
57
58
59
60
61
62
class DateTimeField(Field):
    """Formats and displays a datetime object using timezone localization."""
    def render_html(self, **kwargs) -> str:
        value = self.get_value(**kwargs)
        if value is None:
            return ""
        if isinstance(value, datetime):
            value = timezone.localtime(value)
            value_str = value.strftime("%d %B, %Y, %I:%M %p")
        else:
            value_str = str(value)
        return f"{{% verbatim %}}{value_str}{{% endverbatim %}}"

Field

Bases: Component

Base class for read-only data display fields.

Source code in components/fields.py
14
15
16
class Field(Component):
    """Base class for read-only data display fields."""
    pass

ListField

Bases: Field

Iterates over a list of objects and renders child components for each.

Source code in components/fields.py
154
155
156
157
158
159
160
161
162
163
164
165
class ListField(Field):
    """Iterates over a list of objects and renders child components for each."""
    def render_html(self, **kwargs) -> str:
        value = self.get_value(**kwargs)
        list_html = ""
        for row in value:
            list_html += "<div>"
            for component in self.children:
                list_html += component.build().render(**{**kwargs, "object": row})
            list_html += "</div>"

        return list_html

ManyToManyField

Bases: Field

Displays a list of related objects, optionally as links.

Source code in components/fields.py
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
class ManyToManyField(Field):
    """Displays a list of related objects, optionally as links."""
    def __init__(self, display_attr: str = "__str__", **kwargs):
        super().__init__(**kwargs)
        self.display_attr = display_attr

    def render_html(self, **kwargs) -> str:
        values = self.get_value(**kwargs)
        if not values:
            return ""

        if not isinstance(values, (list, tuple)):
            values = [values]

        items_html = []
        for item in values:
            display_val = (
                str(item)
                if self.display_attr == "__str__"
                else str(getattr(item, self.display_attr, item))
            )

            item_url = None
            if self.url is not None:
                if isinstance(self.url, str):
                    item_url = self.url
                elif callable(self.url):
                    item_url = self.url(item)

            if item_url:
                items_html.append(
                    f'<a href="{item_url}" class="link link-primary">{{% verbatim %}}{display_val}{{% endverbatim %}}</a>'
                )
            else:
                items_html.append(
                    f"<span>{{% verbatim %}}{display_val}{{% endverbatim %}}</span>"
                )

        content = ", ".join(items_html)
        return f'<div id="{self.uid}" class="{self.classes}">{content}</div>'

MarkdownField

Bases: Field

Renders raw markdown content into safe HTML prose.

Source code in components/fields.py
142
143
144
145
146
147
148
149
150
151
class MarkdownField(Field):
    """Renders raw markdown content into safe HTML prose."""
    def render_html(self, **kwargs) -> str:
        value = self.get_value(**kwargs)
        if not value:
            return ""
        from theme.templatetags.markdown_extras import convert_markdown

        html_content = convert_markdown(value)
        return f'<div id="{self.uid}" class="prose prose-sm max-w-none">{html_content}</div>'

SubtitleField

Bases: Field

A muted text field for subtitles.

Source code in components/fields.py
43
44
45
46
47
48
class SubtitleField(Field):
    """A muted text field for subtitles."""
    def render_html(self, **kwargs) -> str:
        value = self.get_value(**kwargs)
        return f"""
            <div id="{self.uid}" class="text-md text-gray-500">{{% verbatim %}}{value}{{% endverbatim %}}</div>"""

TextField

Bases: Field

A standard text display field.

Source code in components/fields.py
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class TextField(Field):
    """A standard text display field."""
    def render_html(self, **kwargs) -> str:
        url = self.get_url(**kwargs)
        value = self.get_value(**kwargs)
        if url is None:
            return f"""
                <div id="{self.uid}" class="{self.classes}">{{% verbatim %}}{value}{{% endverbatim %}}</div>"""
        else:
            return f"""
                <a id="{self.uid}" class="{self.classes}" href="{url}">
                    {{% verbatim %}}{value}{{% endverbatim %}}
                </a>
            """

TimeField

Bases: Field

Formats and displays a time object.

Source code in components/fields.py
78
79
80
81
82
83
84
85
86
87
88
class TimeField(Field):
    """Formats and displays a time object."""
    def render_html(self, **kwargs) -> str:
        value = self.get_value(**kwargs)
        if value is None:
            return ""
        if isinstance(value, time):
            value_str = value.strftime("%I:%M %p")
        else:
            value_str = str(value)
        return f"{{% verbatim %}}{value_str}{{% endverbatim %}}"

TitleField

Bases: Field

A large, bold text field for titles.

Source code in components/fields.py
35
36
37
38
39
40
class TitleField(Field):
    """A large, bold text field for titles."""
    def render_html(self, **kwargs) -> str:
        value = self.get_value(**kwargs)
        return f"""
            <div id="{self.uid}" class="text-xl font-semibold text-primary {self.classes}">{{% verbatim %}}{value}{{% endverbatim %}}</div>"""