web/lib/django/contrib/admin/views/template.py
changeset 38 77b6da96e6f1
equal deleted inserted replaced
37:8d941af65caf 38:77b6da96e6f1
       
     1 from django import template, forms
       
     2 from django.contrib.admin.views.decorators import staff_member_required
       
     3 from django.template import loader
       
     4 from django.shortcuts import render_to_response
       
     5 from django.contrib.sites.models import Site
       
     6 from django.conf import settings
       
     7 from django.utils.importlib import import_module
       
     8 from django.utils.translation import ugettext_lazy as _
       
     9 from django.contrib import messages
       
    10 
       
    11 
       
    12 def template_validator(request):
       
    13     """
       
    14     Displays the template validator form, which finds and displays template
       
    15     syntax errors.
       
    16     """
       
    17     # get a dict of {site_id : settings_module} for the validator
       
    18     settings_modules = {}
       
    19     for mod in settings.ADMIN_FOR:
       
    20         settings_module = import_module(mod)
       
    21         settings_modules[settings_module.SITE_ID] = settings_module
       
    22     site_list = Site.objects.in_bulk(settings_modules.keys()).values()
       
    23     if request.POST:
       
    24         form = TemplateValidatorForm(settings_modules, site_list,
       
    25                                      data=request.POST)
       
    26         if form.is_valid():
       
    27             messages.info(request, 'The template is valid.')
       
    28     else:
       
    29         form = TemplateValidatorForm(settings_modules, site_list)
       
    30     return render_to_response('admin/template_validator.html', {
       
    31         'title': 'Template validator',
       
    32         'form': form,
       
    33     }, context_instance=template.RequestContext(request))
       
    34 template_validator = staff_member_required(template_validator)
       
    35 
       
    36 
       
    37 class TemplateValidatorForm(forms.Form):
       
    38     site = forms.ChoiceField(_('site'))
       
    39     template = forms.CharField(
       
    40         _('template'), widget=forms.Textarea({'rows': 25, 'cols': 80}))
       
    41 
       
    42     def __init__(self, settings_modules, site_list, *args, **kwargs):
       
    43         self.settings_modules = settings_modules
       
    44         super(TemplateValidatorForm, self).__init__(*args, **kwargs)
       
    45         self.fields['site'].choices = [(s.id, s.name) for s in site_list]
       
    46 
       
    47     def clean_template(self):
       
    48         # Get the settings module. If the site isn't set, we don't raise an
       
    49         # error since the site field will.
       
    50         try:
       
    51             site_id = int(self.cleaned_data.get('site', None))
       
    52         except (ValueError, TypeError):
       
    53             return
       
    54         settings_module = self.settings_modules.get(site_id, None)
       
    55         if settings_module is None:
       
    56             return
       
    57 
       
    58         # So that inheritance works in the site's context, register a new
       
    59         # function for "extends" that uses the site's TEMPLATE_DIRS instead.
       
    60         def new_do_extends(parser, token):
       
    61             node = loader.do_extends(parser, token)
       
    62             node.template_dirs = settings_module.TEMPLATE_DIRS
       
    63             return node
       
    64         register = template.Library()
       
    65         register.tag('extends', new_do_extends)
       
    66         template.builtins.append(register)
       
    67 
       
    68         # Now validate the template using the new TEMPLATE_DIRS, making sure to
       
    69         # reset the extends function in any case.
       
    70         error = None
       
    71         template_string = self.cleaned_data['template']
       
    72         try:
       
    73             tmpl = loader.get_template_from_string(template_string)
       
    74             tmpl.render(template.Context({}))
       
    75         except template.TemplateSyntaxError, e:
       
    76             error = e
       
    77         template.builtins.remove(register)
       
    78         if error:
       
    79             raise forms.ValidationError(e.args)