diff --git a/debug_toolbar/templates/debug_toolbar/panels/request_vars.html b/debug_toolbar/templates/debug_toolbar/panels/request_vars.html
index 057f4dee8..c8664263d 100644
--- a/debug_toolbar/templates/debug_toolbar/panels/request_vars.html
+++ b/debug_toolbar/templates/debug_toolbar/panels/request_vars.html
@@ -1,4 +1,4 @@
-{% load i18n %}
+{% load i18n debug_toolbar_utils %}
{% trans 'View information' %}
@@ -71,7 +71,7 @@ {% trans 'SESSION Variables' %}
{% for key, value in session %}
{{ key|escape }} |
- {{ value|escape }} |
+ {{ value|escape|indent_dict }} |
{% endfor %}
diff --git a/debug_toolbar/templatetags/debug_toolbar_utils.py b/debug_toolbar/templatetags/debug_toolbar_utils.py
index c0573128f..5b2a1db3a 100644
--- a/debug_toolbar/templatetags/debug_toolbar_utils.py
+++ b/debug_toolbar/templatetags/debug_toolbar_utils.py
@@ -1,3 +1,5 @@
+#coding=utf-8
+from __future__ import unicode_literals
from django import template
from django.utils.numberformat import format
@@ -10,3 +12,43 @@ def dotted_number(number):
number = float(number)
return format(number, '.', 6)
+
+@register.filter
+def indent_dict(value, indent_nb_space=4):
+ indent = ' ' * indent_nb_space
+ indent_nb = 0
+ result = ''
+ cr = False
+ inc = 0
+ for v in value:
+ inc = inc + 1
+ ind = indent * indent_nb
+ if v == '{':
+ cr = True
+ indent_nb = indent_nb + 1
+ if value[inc] == '}':
+ result += v
+ prev_v = v
+ continue
+ result += '%s\n' % v
+ elif v == '}':
+ indent_nb = indent_nb - 1
+ ind = indent * indent_nb
+ if prev_v == '{':
+ result += v
+ prev_v = v
+ continue
+ result += '\n%s%s' % (ind, v)
+ elif v == ',':
+ result += '%s\n' % v
+ cr = True
+ elif cr:
+ if v == ' ':
+ continue
+ result += ind + v
+ cr = False
+ else:
+ result += v
+ prev_v = v
+
+ return result
diff --git a/tests/tests.py b/tests/tests.py
index ea2938d9b..7e1e09c20 100644
--- a/tests/tests.py
+++ b/tests/tests.py
@@ -1,3 +1,6 @@
+# coding=utf-8
+from __future__ import unicode_literals
+
import thread
from django.conf import settings
@@ -13,6 +16,7 @@
from debug_toolbar.toolbar.loader import DebugToolbar
from debug_toolbar.utils import get_name_from_obj
from debug_toolbar.utils.tracking import pre_dispatch, post_dispatch, callbacks
+from debug_toolbar.templatetags.debug_toolbar_utils import indent_dict
rf = RequestFactory()
@@ -252,6 +256,92 @@ def test_queryset_hook(self):
self.assertIn('<>', ctx)
+class TemplateTagsTestCase(BaseTestCase):
+ def test_indent_dict(self):
+ input = (
+ "{'step_files': {u'1': {}, u'0': {}, u'3': {}, "
+ "u'2': {}}, 'step': u'4', 'extra_data': {}, 'step_data': "
+ "{u'1': {u'1-fax': [u''], u'1-site': [u''], "
+ "u'inscription_wizard-current_step': [u'1'], "
+ "u'1-city': [u'paris'], u'1-zip_code': [u'XXXXX'], "
+ "u'submit': [u'next step'], "
+ "u'1-phone': [u'XX XX XX XX XX'], "
+ "u'csrfmiddlewaretoken': [u'X'], "
+ "u'1-address': [u'xxx xxx xxx.'], "
+ "u'1-mobile_phone': [u'XX XX XX XX XX']}, "
+ "u'0': {u'0-email': [u'xxx@xxx.xx'], "
+ "u'inscription_wizard-current_step': [u'0'], "
+ "u'submit': [u'next step'], "
+ "u'csrfmiddlewaretoken': [u'X'], "
+ "u'0-origin': [u'0']}, "
+ "u'3': {u'3-honeypot': [u''], u'3-select_paiement': [u'1'], "
+ "u'inscription_wizard-current_step': [u'3'], "
+ "u'submit': [u'next step'], u'3-reglement': [u'on'], "
+ "u'csrfmiddlewaretoken': [u'X'], "
+ "u'3-keywords': [u''], "
+ "u'files[]': [u'']}, u'2': {u'2-co_first_name': [u''], "
+ "u'inscription_wizard-current_step': [u'2'], "
+ "u'2-co_fonction': [u''], u'2-name': [u'Dupond'], "
+ "u'submit': [u'next step'], "
+ "u'2-first_name': [u'Xavier'], "
+ "u'csrfmiddlewaretoken': [u'X']}}}"
+ )
+
+ output = (
+ "{\n"
+ " 'step_files': {\n"
+ " u'1': {},\n"
+ " u'0': {},\n"
+ " u'3': {},\n"
+ " u'2': {}\n"
+ " },\n"
+ " 'step': u'4',\n"
+ " 'extra_data': {},\n"
+ " 'step_data': {\n"
+ " u'1': {\n"
+ " u'1-fax': [u''],\n"
+ " u'1-site': [u''],\n"
+ " u'inscription_wizard-current_step': [u'1'],\n"
+ " u'1-city': [u'paris'],\n"
+ " u'1-zip_code': [u'XXXXX'],\n"
+ " u'submit': [u'next step'],\n"
+ " u'1-phone': [u'XX XX XX XX XX'],\n"
+ " u'csrfmiddlewaretoken': [u'X'],\n"
+ " u'1-address': [u'xxx xxx xxx.'],\n"
+ " u'1-mobile_phone': [u'XX XX XX XX XX']\n"
+ " },\n"
+ " u'0': {\n"
+ " u'0-email': [u'xxx@xxx.xx'],\n"
+ " u'inscription_wizard-current_step': [u'0'],\n"
+ " u'submit': [u'next step'],\n"
+ " u'csrfmiddlewaretoken': [u'X'],\n"
+ " u'0-origin': [u'0']\n"
+ " },\n"
+ " u'3': {\n"
+ " u'3-honeypot': [u''],\n"
+ " u'3-select_paiement': [u'1'],\n"
+ " u'inscription_wizard-current_step': [u'3'],\n"
+ " u'submit': [u'next step'],\n"
+ " u'3-reglement': [u'on'],\n"
+ " u'csrfmiddlewaretoken': [u'X'],\n"
+ " u'3-keywords': [u''],\n"
+ " u'files[]': [u'']\n"
+ " },\n"
+ " u'2': {\n"
+ " u'2-co_first_name': [u''],\n"
+ " u'inscription_wizard-current_step': [u'2'],\n"
+ " u'2-co_fonction': [u''],\n"
+ " u'2-name': [u'Dupond'],\n"
+ " u'submit': [u'next step'],\n"
+ " u'2-first_name': [u'Xavier'],\n"
+ " u'csrfmiddlewaretoken': [u'X']\n"
+ " }\n"
+ " }\n"
+ "}"
+ )
+ self.assertEquals(indent_dict(input), output)
+
+
def module_func(*args, **kwargs):
"""Used by dispatch tests"""
return 'blah'