Skip to content

Commit c947162

Browse files
authored
feat: optionally format json with pygments (#451)
1 parent c01a1ba commit c947162

File tree

2 files changed

+30
-2
lines changed

2 files changed

+30
-2
lines changed

src/unfold/fields.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from django.utils.text import capfirst
1919

2020
from .settings import get_config
21-
from .utils import display_for_field
21+
from .utils import display_for_field, prettify_json
2222
from .widgets import CHECKBOX_LABEL_CLASSES, LABEL_CLASSES
2323

2424

@@ -138,6 +138,14 @@ def _get_contents(self) -> str:
138138
and value is not None
139139
):
140140
result_repr = self.get_admin_url(f.remote_field, value)
141+
elif isinstance(f, models.JSONField):
142+
formatted_output = prettify_json(value)
143+
144+
if formatted_output:
145+
return formatted_output
146+
147+
result_repr = display_for_field(value, f, self.empty_value_display)
148+
return conditional_escape(result_repr)
141149
elif isinstance(f, models.URLField):
142150
return format_html(
143151
'<a href="{}" class="text-primary-600 underline whitespace-nowrap">{}</a>',

src/unfold/utils.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import datetime
22
import decimal
33
import json
4-
from typing import Any, Iterable, List
4+
from typing import Any, Iterable, List, Optional
55

66
from django.db import models
77
from django.template.loader import render_to_string
@@ -121,3 +121,23 @@ def hex_to_rgb(hex_color: str) -> List[int]:
121121
b = int(hex_color[4:6], 16)
122122

123123
return (r, g, b)
124+
125+
126+
def prettify_json(data: Any) -> Optional[str]:
127+
try:
128+
from pygments import highlight
129+
from pygments.formatters import HtmlFormatter
130+
from pygments.lexers import JsonLexer
131+
except ImportError:
132+
return None
133+
134+
def format_response(response: str, theme: str) -> str:
135+
formatter = HtmlFormatter(style=theme, noclasses=True, nobackground=True)
136+
return highlight(response, JsonLexer(), formatter)
137+
138+
response = json.dumps(data, sort_keys=True, indent=4)
139+
140+
return mark_safe(
141+
f'<div class="block dark:hidden">{format_response(response, "colorful")}</div>'
142+
f'<div class="hidden dark:block">{format_response(response, "monokai")}</div>'
143+
)

0 commit comments

Comments
 (0)