Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion src/unfold/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from django.utils.text import capfirst

from .settings import get_config
from .utils import display_for_field
from .utils import display_for_field, prettify_json
from .widgets import CHECKBOX_LABEL_CLASSES, LABEL_CLASSES


Expand Down Expand Up @@ -138,6 +138,14 @@ def _get_contents(self) -> str:
and value is not None
):
result_repr = self.get_admin_url(f.remote_field, value)
elif isinstance(f, models.JSONField):
formatted_output = prettify_json(value)

if formatted_output:
return formatted_output

result_repr = display_for_field(value, f, self.empty_value_display)
return conditional_escape(result_repr)
elif isinstance(f, models.URLField):
return format_html(
'<a href="{}" class="text-primary-600 underline whitespace-nowrap">{}</a>',
Expand Down
22 changes: 21 additions & 1 deletion src/unfold/utils.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import datetime
import decimal
import json
from typing import Any, Iterable, List
from typing import Any, Iterable, List, Optional

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

return (r, g, b)


def prettify_json(data: Any) -> Optional[str]:
try:
from pygments import highlight
from pygments.formatters import HtmlFormatter
from pygments.lexers import JsonLexer
except ImportError:
return None

def format_response(response: str, theme: str) -> str:
formatter = HtmlFormatter(style=theme, noclasses=True, nobackground=True)
return highlight(response, JsonLexer(), formatter)

response = json.dumps(data, sort_keys=True, indent=4)

return mark_safe(
f'<div class="block dark:hidden">{format_response(response, "colorful")}</div>'
f'<div class="hidden dark:block">{format_response(response, "monokai")}</div>'
)