Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: title prefix for different environments #1011 #1015

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
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
13 changes: 11 additions & 2 deletions docs/configuration/settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,19 @@ def dashboard_callback(request, context):

def environment_callback(request):
"""
Callback has to return a list of two values represeting text value and the color
type of the label displayed in top right corner.
Callback has to return a list or a dict with the values represeting:
- the text of the label displayed in the top right corner.
- the color accent of that label.
- and optionally a prefix to be prepend in the browser tab title if needed.
"""
# Return a list with the label and color accent only for backward compatiblity
return ["Production", "danger"] # info, danger, warning, success
# Return a dict containing the following keys
return {
"label": "Production", # Accepts translated strings also for example _("Production")
"color_accent": "danger",
"title_prefix": "[PROD]",
}


def badge_callback(request):
Expand Down
6 changes: 2 additions & 4 deletions docs/dashboard/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,8 @@ TEMPLATES = [
{% block breadcrumbs %}{% endblock %}

{% block title %}
{% if subtitle %}
{{ subtitle }} |
{% endif %}

{% if environment and environment.title_prefix %}{{ environment.title_prefix }}{% endif %}
{% if subtitle %}{{ subtitle }} | {% endif %}
{{ title }} | {{ site_title|default:_('Django site admin') }}
{% endblock %}

Expand Down
38 changes: 29 additions & 9 deletions src/unfold/sites.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,33 @@ def get_urls(self) -> List[URLPattern]:

return urlpatterns

def get_environment_context(self, request):
"""
Build the environment indicator needed template context if the environment callback is set.
"""
context = {}
environment_callback = get_config(self.settings_name)["ENVIRONMENT"]
if environment_callback and isinstance(environment_callback, str):
try:
callback = import_string(environment_callback)
environment = callback(request)
if isinstance(environment, list):
# Handle old environment callback return value
label, color_accent = environment
context.update(
{
"label": label,
"color_accent": color_accent,
"title_prefix": None,
}
)
else:
context.update(environment)
except ImportError:
pass

return context

def each_context(self, request: HttpRequest) -> Dict[str, Any]:
context = super().each_context(request)

Expand Down Expand Up @@ -121,18 +148,10 @@ def each_context(self, request: HttpRequest) -> Dict[str, Any]:
"sidebar_navigation": self.get_sidebar_list(request)
if self.has_permission(request)
else [],
"environment": self.get_environment_context(request),
}
)

environment = get_config(self.settings_name)["ENVIRONMENT"]

if environment and isinstance(environment, str):
try:
callback = import_string(environment)
context.update({"environment": callback(request)})
except ImportError:
pass

if hasattr(self, "extra_context") and callable(self.extra_context):
return self.extra_context(context, request)

Expand Down Expand Up @@ -212,6 +231,7 @@ def login(
self, request: HttpRequest, extra_context: Optional[Dict[str, Any]] = None
) -> HttpResponse:
extra_context = {} if extra_context is None else extra_context
extra_context.update({"environment": self.get_environment_context(request)})
image = self._get_value(
get_config(self.settings_name)["LOGIN"].get("image"), request
)
Expand Down
6 changes: 5 additions & 1 deletion src/unfold/templates/admin/app_index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@

{% load i18n %}

{% block title %}{% if subtitle %}{{ subtitle }} | {% endif %}{{ title }} | {{ site_title|default:_('Django site admin') }}{% endblock %}
{% block title %}
{% if environment and environment.title_prefix %}{{ environment.title_prefix }}{% endif %}
{% if subtitle %}{{ subtitle }} | {% endif %}
{{ title }} | {{ site_title|default:_('Django site admin') }}
{% endblock %}

{% block bodyclass %}{{ block.super }} app-{{ app_label }}{% endblock %}

Expand Down
6 changes: 5 additions & 1 deletion src/unfold/templates/admin/base_site.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
{% extends "admin/base.html" %}

{% block title %}{% if subtitle %}{{ subtitle }} | {% endif %}{{ title }} | {{ site_title|default:_('Django site admin') }}{% endblock %}
{% block title %}
{% if environment and environment.title_prefix %}{{ environment.title_prefix }}{% endif %}
{% if subtitle %}{{ subtitle }} | {% endif %}
{{ title }} | {{ site_title|default:_('Django site admin') }}
{% endblock %}

{% block branding %}
<h1 id="site-name"><a href="{% url 'admin:index' %}">{{ site_header|default:_('Django administration') }}</a></h1>
Expand Down
6 changes: 5 additions & 1 deletion src/unfold/templates/admin/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@

{% block breadcrumbs %}{% endblock %}

{% block title %}{% if subtitle %}{{ subtitle }} | {% endif %}{{ title }} | {{ site_title|default:_('Django site admin') }}{% endblock %}
{% block title %}
{% if environment and environment.title_prefix %}{{ environment.title_prefix }}{% endif %}
{% if subtitle %}{{ subtitle }} | {% endif %}
{{ title }} | {{ site_title|default:_('Django site admin') }}
{% endblock %}

{% block branding %}
<h1 id="site-name">
Expand Down
2 changes: 1 addition & 1 deletion src/unfold/templates/admin/login.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
{% block breadcrumbs %}{% endblock %}

{% block title %}
{{ title }} | {{ site_title }}
{% if environment and environment.title_prefix %} {{ environment.title_prefix }} {% endif %}{{ title }} | {{ site_title }}
{% endblock %}

{% block base %}
Expand Down
2 changes: 1 addition & 1 deletion src/unfold/templates/unfold/helpers/userlinks.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<div class="flex flex-row group items-center leading-none relative">
<div class="flex gap-4 items-center">
{% if environment %}
{% include "unfold/helpers/label.html" with text=environment.0 type=environment.1 %}
{% include "unfold/helpers/label.html" with text=environment.label type=environment.color_accent %}
{% endif %}

{% if extra_userlinks %}
Expand Down
6 changes: 5 additions & 1 deletion src/unfold/templates/unfold/layouts/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,8 @@ <h1 id="site-name">
</h1>
{% endblock %}

{% block title %}{% if subtitle %}{{ subtitle }} | {% endif %}{{ title }} | {{ site_title|default:_('Django site admin') }}{% endblock %}
{% block title %}
{% if environment and environment.title_prefix %}{{ environment.title_prefix }}{% endif %}
{% if subtitle %}{{ subtitle }} | {% endif %}
{{ title }} | {{ site_title|default:_('Django site admin') }}
{% endblock %}
39 changes: 36 additions & 3 deletions tests/test_environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,21 @@ def environment_callback(request):
return ["Testing Environment", "warning"]


def environment_callback_dict(request):
return {
"label": "Testing Environment",
"color_accent": "warning",
"title_prefix": "[TEST]",
}


@override_settings(UNFOLD={**CONFIG_DEFAULTS})
def test_environment_empty_environment_callback():
admin_site = UnfoldAdminSite()
request = RequestFactory().get("/rand")
request.user = AnonymousUser()
context = admin_site.each_context(request)
assert "environment" not in context
assert context["environment"] == {}


@override_settings(
Expand All @@ -32,7 +40,7 @@ def test_environment_incorrect_environment_callback():
request = RequestFactory().get("/rand")
request.user = AnonymousUser()
context = admin_site.each_context(request)
assert "environment" not in context
assert context["environment"] == {}


@override_settings(
Expand All @@ -43,10 +51,35 @@ def test_environment_incorrect_environment_callback():
},
}
)
def test_environment_correct_backward_compatible_environment_callback():
admin_site = UnfoldAdminSite()
request = RequestFactory().get("/rand")
request.user = AnonymousUser()
context = admin_site.each_context(request)
assert "environment" in context
assert context["environment"] == {
"label": "Testing Environment",
"color_accent": "warning",
"title_prefix": None,
}


@override_settings(
UNFOLD={
**CONFIG_DEFAULTS,
**{
"ENVIRONMENT": "tests.test_environment.environment_callback_dict",
},
}
)
def test_environment_correct_environment_callback():
admin_site = UnfoldAdminSite()
request = RequestFactory().get("/rand")
request.user = AnonymousUser()
context = admin_site.each_context(request)
assert "environment" in context
assert context["environment"] == ["Testing Environment", "warning"]
assert context["environment"] == {
"label": "Testing Environment",
"color_accent": "warning",
"title_prefix": "[TEST]",
}