From 24cdaa77fabf46dade40e47c0192c61d6c0a78ee Mon Sep 17 00:00:00 2001 From: Robert Wittams Date: Tue, 8 Nov 2005 21:46:21 +0000 Subject: [PATCH] Small template debugging fixes. Filter specs now have totally template driven output git-svn-id: http://code.djangoproject.com/svn/django/branches/new-admin@1128 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- .../contrib/admin/templates/admin/filter.html | 7 ++ .../admin/templates/admin/filters.html | 2 +- .../admin/templates/admin/template_debug.html | 4 +- .../contrib/admin/templatetags/admin_list.py | 12 +-- django/contrib/admin/views/main.py | 102 +++++++++--------- django/core/template/__init__.py | 33 ++++-- 6 files changed, 93 insertions(+), 67 deletions(-) create mode 100644 django/contrib/admin/templates/admin/filter.html diff --git a/django/contrib/admin/templates/admin/filter.html b/django/contrib/admin/templates/admin/filter.html new file mode 100644 index 0000000000..e79a14a2ce --- /dev/null +++ b/django/contrib/admin/templates/admin/filter.html @@ -0,0 +1,7 @@ +

{%blocktrans%} By {{title}} {%endblocktrans%}

+ \ No newline at end of file diff --git a/django/contrib/admin/templates/admin/filters.html b/django/contrib/admin/templates/admin/filters.html index 844571f08a..e3a34655d7 100644 --- a/django/contrib/admin/templates/admin/filters.html +++ b/django/contrib/admin/templates/admin/filters.html @@ -1,5 +1,5 @@ {% if cl.has_filters %}

Filter

{% for spec in cl.filter_specs %} - {% output_filter_spec cl spec %} + {% filter cl spec %} {% endfor %}
{% endif %} \ No newline at end of file diff --git a/django/contrib/admin/templates/admin/template_debug.html b/django/contrib/admin/templates/admin/template_debug.html index 55569e539a..779d571e54 100644 --- a/django/contrib/admin/templates/admin/template_debug.html +++ b/django/contrib/admin/templates/admin/template_debug.html @@ -4,8 +4,8 @@

Error in Template

-{{message}}
-{{traceback}}
+{{message|escape}}
+{{traceback|escape}}
 
{%if top%} diff --git a/django/contrib/admin/templatetags/admin_list.py b/django/contrib/admin/templatetags/admin_list.py index ea1b7bf619..3f155564c0 100644 --- a/django/contrib/admin/templatetags/admin_list.py +++ b/django/contrib/admin/templatetags/admin_list.py @@ -209,8 +209,6 @@ def items_for_result(cl, result): else: yield ('%s' % (row_class, result_repr)) - - def results(cl): for res in cl.result_list: yield list(items_for_result(cl,res)) @@ -224,7 +222,6 @@ def result_list(cl): result_list = inclusion_tag("admin/change_list_results")(result_list) - #@simple_tag def date_hierarchy(cl): lookup_opts, params, lookup_params, lookup_mod = \ @@ -278,10 +275,11 @@ def search_form(cl): 'search_var': SEARCH_VAR } search_form = inclusion_tag('admin/search_form')(search_form) -#@simple_tag -def output_filter_spec(cl, spec): - return spec.output(cl) -output_filter_spec = simple_tag(output_filter_spec) +#@inclusion_tag('admin/filter') +def filter(cl, spec): + return {'title': spec.title(), + 'choices' : list(spec.choices(cl))} +filter = inclusion_tag('admin/filter')(filter) #@inclusion_tag('admin/filters') def filters(cl): diff --git a/django/contrib/admin/views/main.py b/django/contrib/admin/views/main.py index 4694f8912d..7f0c5c5906 100644 --- a/django/contrib/admin/views/main.py +++ b/django/contrib/admin/views/main.py @@ -72,21 +72,26 @@ class FilterSpec(object): def has_output(self): return True + def choices(self, cl): + raise NotImplementedException() + + def title(self): + return self.field.verbose_name + def output(self, cl): t = [] if self.has_output(): - t.append(_('

By %s:

\n
    \n') % self.title) + t.append(_('

    By %s:

    \n
      \n') % self.title()) - for choice in self.choices: + for choice in self.choices(cl): t.append('%s\n' % \ - (self.is_selected(choice) and ' class="selected"' or ''), - self.get_query_string(choice) , - self.get_display(choice) ) + ((choice['selected'] and ' class="selected"' or ''), + choice['query_string'] , + choice['display'])) t.append('
    \n\n') return "".join(t) class RelatedFilterSpec(FilterSpec): - def __init__(self, f, request, params): super(RelatedFilterSpec, self).__init__(f, request, params) if isinstance(f, meta.ManyToManyField): @@ -100,20 +105,18 @@ class RelatedFilterSpec(FilterSpec): def has_output(self): return len(self.lookup_choices) > 1 - def output(self, cl): - t = [] - if self.has_output(): - t.append(_('

    By %s:

    \n
      \n') % self.lookup_title) - t.append('All\n' % \ - ((self.lookup_val is None and ' class="selected"' or ''), - cl.get_query_string({}, [self.lookup_kwarg]))) - for val in self.lookup_choices: - pk_val = getattr(val, self.field.rel.to.pk.column) - t.append('%s\n' % \ - ((self.lookup_val == str(pk_val) and ' class="selected"' or ''), - cl.get_query_string( {self.lookup_kwarg: pk_val}), val)) - t.append('
    \n\n') - return "".join(t) + def title(self): + return self.lookup_title + + def choices(self, cl): + yield {'selected': self.lookup_val is None, + 'query_string': cl.get_query_string({}, [self.lookup_kwarg]), + 'display': _('All') } + for val in self.lookup_choices: + pk_val = getattr(val, self.field.rel.to.pk.column) + yield { 'selected': self.lookup_val == str(pk_val), + 'query_string': cl.get_query_string( {self.lookup_kwarg: pk_val}), + 'display' : val } FilterSpec.register(lambda f: bool(f.rel), RelatedFilterSpec) class ChoicesFilterSpec(FilterSpec): @@ -123,18 +126,14 @@ class ChoicesFilterSpec(FilterSpec): self.lookup_kwarg = '%s__exact' % f.name self.lookup_val = request.GET.get(self.lookup_kwarg, None) - def output(self, cl): - t = [] - t.append(_('

    By %s:

      \n') % self.field.verbose_name) - t.append('All\n' % \ - ((self.lookup_val is None and ' class="selected"' or ''), - cl.get_query_string( {}, [self.lookup_kwarg]))) + def choices(self, cl): + yield {'selected' : self.lookup_val is None, + 'query_string': cl.get_query_string( {}, [self.lookup_kwarg]), + 'display': _('All') } for k, v in self.field.choices: - t.append('%s' % \ - ((str(k) == self.lookup_val) and ' class="selected"' or '', - cl.get_query_string( {self.lookup_kwarg: k}), v)) - t.append('
    \n\n') - return "".join(t) + yield {'selected': str(k) == self.lookup_val, + 'query_string' : cl.get_query_string( {self.lookup_kwarg: k}), + 'display' : v } FilterSpec.register(lambda f: bool(f.choices), ChoicesFilterSpec) class DateFieldFilterSpec(FilterSpec): @@ -161,16 +160,16 @@ class DateFieldFilterSpec(FilterSpec): '%s__month' % f.name: str(today.month)}), ('This year', {'%s__year' % self.field.name: str(today.year)}) ) - - def output(self, cl): - t = [] - t.append(_('

    By %s:

      \n') % self.field.verbose_name) + + def title(self): + return self.field.verbose_name + + def choices(self, cl): for title, param_dict in self.links: - t.append('%s\n' % \ - ((self.date_params == param_dict) and ' class="selected"' or '', - cl.get_query_string( param_dict, self.field_generic), title)) - t.append('
    \n\n') - return "".join(t) + yield { 'selected' : self.date_params == param_dict, + 'query_string' : cl.get_query_string( param_dict, self.field_generic), + 'display' : title } + FilterSpec.register(lambda f: isinstance(f, meta.DateField), DateFieldFilterSpec) class BooleanFieldFilterSpec(FilterSpec): @@ -182,19 +181,20 @@ class BooleanFieldFilterSpec(FilterSpec): self.lookup_val = request.GET.get(self.lookup_kwarg, None) self.lookup_val2 = request.GET.get(self.lookup_kwarg2, None) - def output(self, cl): - t = [] - t.append(_('

    By %s:

      \n') % self.field.verbose_name) + def title(self): + return self.field.verbose_name + + def choices(self, cl): for k, v in (('All', None), ('Yes', '1'), ('No', '0')): - t.append('%s\n' % \ - (((self.lookup_val == v and not self.lookup_val2) and ' class="selected"' or ''), - cl.get_query_string( {self.lookup_kwarg: v}, [self.lookup_kwarg2]), k)) + yield { 'selected' : self.lookup_val == v and not self.lookup_val2, + 'query_string' : cl.get_query_string( {self.lookup_kwarg: v}, [self.lookup_kwarg2]), + 'display': k + } if isinstance(self.field, meta.NullBooleanField): - t.append('%s\n' % \ - (((lookup_val2 == 'True') and ' class="selected"' or ''), - cl.get_query_string( {self.lookup_kwarg2: 'True'}, [self.lookup_kwarg]), 'Unknown')) - t.append('
    \n\n') - return "".join(t) + yield { 'selected' : lookup_val2 == 'True', + 'query_string' : cl.get_query_string( {self.lookup_kwarg2: 'True'}, [self.lookup_kwarg]), + 'display': _('Unknown') + } FilterSpec.register(lambda f: isinstance(f, meta.BooleanField) or isinstance(f, meta.NullBooleanField), BooleanFieldFilterSpec) diff --git a/django/core/template/__init__.py b/django/core/template/__init__.py index 937744151b..3e37b114a1 100644 --- a/django/core/template/__init__.py +++ b/django/core/template/__init__.py @@ -286,7 +286,8 @@ class Parser(object): elif token.token_type == TOKEN_VAR: if not token.contents: self.empty_variable(token) - self.extend_nodelist(nodelist, VariableNode(token.contents), token) + var_node = self.create_variable_node(token.contents) + self.extend_nodelist(nodelist, var_node,token) elif token.token_type == TOKEN_BLOCK: if token.contents in parse_until: # put token back on token list so calling code knows why it terminated @@ -313,6 +314,9 @@ class Parser(object): self.unclosed_block_tag(token, parse_until) return nodelist + def create_variable_node(self, contents): + return VariableNode(contents) + def create_nodelist(self): return NodeList() @@ -374,6 +378,9 @@ class DebugParser(Parser): def create_nodelist(self): return DebugNodeList() + def create_variable_node(self, contents): + return DebugVariableNode(contents) + def extend_nodelist(self, nodelist, node, token): node.source = token.source super(DebugParser, self).extend_nodelist(nodelist, node, token) @@ -866,14 +873,28 @@ class VariableNode(Node): def __repr__(self): return "" % self.var_string - def render(self, context): - output = resolve_variable_with_filters(self.var_string, context) + def encode_output(self, output): # Check type so that we don't run str() on a Unicode object if not isinstance(output, basestring): - output = str(output) + return str(output) elif isinstance(output, unicode): - output = output.encode(DEFAULT_CHARSET) - return output + return output.encode(DEFAULT_CHARSET) + else: + return output + + def render(self, context): + output = resolve_variable_with_filters(self.var_string, context) + return self.encode_output(output) + +class DebugVariableNode(VariableNode): + def render(self, context): + try: + output = resolve_variable_with_filters(self.var_string, context) + except TemplateSyntaxError, e: + if not hasattr(e, 'source'): + e.source = self.source + raise + return self.encode_output(output) def register_tag(token_command, callback_function): registered_tags[token_command] = callback_function