diff --git a/docs/plugins/development/templates.md b/docs/plugins/development/templates.md
index 64616c442..20838149f 100644
--- a/docs/plugins/development/templates.md
+++ b/docs/plugins/development/templates.md
@@ -215,6 +215,8 @@ The following custom template tags are available in NetBox.
::: utilities.templatetags.builtins.tags.checkmark
+::: utilities.templatetags.builtins.tags.customfield_value
+
::: utilities.templatetags.builtins.tags.tag
## Filters
diff --git a/docs/release-notes/version-3.3.md b/docs/release-notes/version-3.3.md
index ea9e67a38..f5cb8eee1 100644
--- a/docs/release-notes/version-3.3.md
+++ b/docs/release-notes/version-3.3.md
@@ -40,6 +40,7 @@
* [#9075](https://github.com/netbox-community/netbox/issues/9075) - Introduce `AbortRequest` exception for cleanly interrupting object mutations
* [#9092](https://github.com/netbox-community/netbox/issues/9092) - Add support for `ObjectChildrenView` generic view
* [#9414](https://github.com/netbox-community/netbox/issues/9414) - Add `clone()` method to NetBoxModel for copying instance attributes
+* [#9647](https://github.com/netbox-community/netbox/issues/9647) - Introduce `customfield_value` template tag
### Other Changes
diff --git a/netbox/templates/inc/panels/custom_fields.html b/netbox/templates/inc/panels/custom_fields.html
index b18d44030..90059447f 100644
--- a/netbox/templates/inc/panels/custom_fields.html
+++ b/netbox/templates/inc/panels/custom_fields.html
@@ -16,33 +16,7 @@
{{ field }}
- {% if field.type == 'integer' and value is not None %}
- {{ value }}
- {% elif field.type == 'longtext' and value %}
- {{ value|markdown }}
- {% elif field.type == 'boolean' and value == True %}
- {% checkmark value true="True" %}
- {% elif field.type == 'boolean' and value == False %}
- {% checkmark value false="False" %}
- {% elif field.type == 'url' and value %}
- {{ value|truncatechars:70 }}
- {% elif field.type == 'json' and value %}
- {{ value|json }}
- {% elif field.type == 'multiselect' and value %}
- {{ value|join:", " }}
- {% elif field.type == 'object' and value %}
- {{ value|linkify }}
- {% elif field.type == 'multiobject' and value %}
- {% for obj in value %}
- {{ obj|linkify }}{% if not forloop.last %} {% endif %}
- {% endfor %}
- {% elif value %}
- {{ value }}
- {% elif field.required %}
- Not defined
- {% else %}
- {{ ''|placeholder }}
- {% endif %}
+ {% customfield_value field value %}
|
{% endfor %}
diff --git a/netbox/utilities/templates/builtins/customfield_value.html b/netbox/utilities/templates/builtins/customfield_value.html
new file mode 100644
index 000000000..8fedb03d5
--- /dev/null
+++ b/netbox/utilities/templates/builtins/customfield_value.html
@@ -0,0 +1,27 @@
+{% if field.type == 'integer' and value is not None %}
+ {{ value }}
+{% elif field.type == 'longtext' and value %}
+ {{ value|markdown }}
+{% elif field.type == 'boolean' and value == True %}
+ {% checkmark value true="True" %}
+{% elif field.type == 'boolean' and value == False %}
+ {% checkmark value false="False" %}
+{% elif field.type == 'url' and value %}
+ {{ value|truncatechars:70 }}
+{% elif field.type == 'json' and value %}
+ {{ value|json }}
+{% elif field.type == 'multiselect' and value %}
+ {{ value|join:", " }}
+{% elif field.type == 'object' and value %}
+ {{ value|linkify }}
+{% elif field.type == 'multiobject' and value %}
+ {% for object in value %}
+ {{ object|linkify }}{% if not forloop.last %}
{% endif %}
+ {% endfor %}
+{% elif value %}
+ {{ value }}
+{% elif field.required %}
+ Not defined
+{% else %}
+ {{ ''|placeholder }}
+{% endif %}
diff --git a/netbox/utilities/templatetags/builtins/tags.py b/netbox/utilities/templatetags/builtins/tags.py
index 666b6a31c..ed464b332 100644
--- a/netbox/utilities/templatetags/builtins/tags.py
+++ b/netbox/utilities/templatetags/builtins/tags.py
@@ -18,6 +18,21 @@ def tag(value, viewname=None):
}
+@register.inclusion_tag('builtins/customfield_value.html')
+def customfield_value(customfield, value):
+ """
+ Render a custom field value according to the field type.
+
+ Args:
+ customfield: A CustomField instance
+ value: The custom field value applied to an object
+ """
+ return {
+ 'customfield': customfield,
+ 'value': value,
+ }
+
+
@register.inclusion_tag('builtins/badge.html')
def badge(value, bg_color=None, show_empty=False):
"""