Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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
3 changes: 3 additions & 0 deletions admin_interface/templates/admin/base_site.html
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,9 @@
{% if theme.list_filter_highlight %} list-filter-highlight {% endif %}
{% if theme.list_filter_sticky %} list-filter-sticky {% endif %}

{% resolve_variable "adminform" as adminform %}
{% resolve_variable "inline_admin_formsets" as inline_admin_formsets %}

{% if adminform and inline_admin_formsets %}
{% admin_interface_use_changeform_tabs adminform inline_admin_formsets as admin_interface_use_changeform_tabs %}
{% if admin_interface_use_changeform_tabs %}
Expand Down
5 changes: 5 additions & 0 deletions admin_interface/templatetags/admin_interface_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,11 @@ def admin_interface_use_changeform_tabs(adminform, inline_forms):
return has_tabs


@register.simple_tag(takes_context=True)
def resolve_variable(context, var_name, default=""):
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please rename the template tag to admin_interface_resolve_variable?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done
renamed the template tag to admin_interface_resolve_variable as suggested.

return context.get(var_name, default)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This works only for top-level context keys. It doesn't resolve dotted variables like user.username, the correct approach is:

try:
    return template.Variable(var_name).resolve(context)
except VariableDoesNotExist:
    return default

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the suggestion!

I initially considered using template.Variable(var_name).resolve(context) directly, but the issue is that when a variable (or part of a dotted lookup like var.dottedvar) is missing, Variable.resolve() raises VariableDoesNotExist, which gets logged by Django and pollutes the logs. which brings us to the same issue that we are trying to prevent .

To avoid this, I’ve added a lightweight pre-check that verifies variable (normal and dotted) exists in the context.

If it does, I then delegate to Variable.resolve() so Django still handles callables, translations, etc. If not, I return the default immediately.



@register.filter
def admin_interface_slugify(name):
return slugify(str(name or ""))
31 changes: 31 additions & 0 deletions tests/test_resolve_variable.py
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a small thing: please use always the same variable name for coherence. I see sometimes you use res, sometimes result. Better to choose one (result) and use it everywhere to keep the code more clear.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Acknowledged, and thank you for pointing that out !

Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from django.template import Context, Template
from django.test import SimpleTestCase


class ResolveVariableTagTests(SimpleTestCase):
def render_template(self, tpl, context=None):
if context is None:
context = {}
return (
Template("{% load admin_interface_tags %}" + tpl)
.render(Context(context))
.strip()
)

def test_returns_existing_variable(self):
out = self.render_template(
'{% resolve_variable "myvar" as result %}{{ result }}', {"myvar": "hello"}
)
self.assertEqual(out, "hello")

def test_returns_default_when_missing(self):
out = self.render_template(
'{% resolve_variable "missingvar" as result %}{{ result }}'
)
self.assertEqual(out, "")

def test_returns_custom_default(self):
out = self.render_template(
'{% resolve_variable "missingvar" "fallback" as result %}{{ result }}'
)
self.assertEqual(out, "fallback")