from django.utils.translation import ugettext_lazy as _
from django.core.validators import RegexValidator
from django.core.exceptions import ValidationError
-from django.template import Template, Parser, Lexer, TOKEN_BLOCK, TOKEN_VAR
+from django.template import Template, Parser, Lexer, TOKEN_BLOCK, TOKEN_VAR, TemplateSyntaxError
from django.utils import simplejson as json
+from django.utils.html import escape, mark_safe
import re
+from philo.utils import LOADED_TEMPLATE_ATTR
-LOADED_TEMPLATE_ATTR = '_philo_loaded_template'
INSECURE_TAGS = (
'load',
'extends',
def json_validator(value):
try:
json.loads(value)
- except:
- raise ValidationError(u'\'%s\' is not valid JSON' % value)
+ except Exception, e:
+ raise ValidationError(u'JSON decode error: %s' % e)
class TemplateValidationParser(Parser):
raise ValidationError('Tag "%s" is not permitted here.' % command)
+def linebreak_iter(template_source):
+ # Cribbed from django/views/debug.py:18
+ yield 0
+ p = template_source.find('\n')
+ while p >= 0:
+ yield p+1
+ p = template_source.find('\n', p+1)
+ yield len(template_source) + 1
+
+
class TemplateValidator(object):
def __init__(self, allow=None, disallow=None, secure=True):
self.allow = allow
except ValidationError:
raise
except Exception, e:
+ if hasattr(e, 'source') and isinstance(e, TemplateSyntaxError):
+ origin, (start, end) = e.source
+ template_source = origin.reload()
+ upto = 0
+ for num, next in enumerate(linebreak_iter(template_source)):
+ if start >= upto and end <= next:
+ raise ValidationError(mark_safe("Template code invalid: \"%s\" (%s:%d).<br />%s" % (escape(template_source[start:end]), origin.loadname, num, e)))
+ upto = next
raise ValidationError("Template code invalid. Error was: %s: %s" % (e.__class__.__name__, e))
def validate_template(self, template_string):