fixed pre-existing bug in handling delimiters in templates
This commit is contained in:
@@ -121,7 +121,7 @@ class BlockNode(Node):
|
||||
self.nodes = []
|
||||
self.name = name
|
||||
self.pre_extend = pre_extend
|
||||
self.left, self.right = delimiters or DEFAULT_DELIMITERS
|
||||
self.left, self.right = delimiters
|
||||
|
||||
def __repr__(self):
|
||||
lines = ['%sblock %s%s' % (self.left, self.name, self.right)]
|
||||
@@ -255,10 +255,6 @@ class TemplateParser(object):
|
||||
template that need to be handled.
|
||||
|
||||
"""
|
||||
|
||||
default_delimiters = DEFAULT_DELIMITERS
|
||||
r_tag = compile(r'(\{\{.*?\}\})', DOTALL)
|
||||
|
||||
r_multiline = compile(r'(""".*?""")|(\'\'\'.*?\'\'\')', DOTALL)
|
||||
|
||||
# These are used for re-indentation.
|
||||
@@ -272,7 +268,7 @@ class TemplateParser(object):
|
||||
|
||||
def __init__(self, text,
|
||||
name="ParserContainer",
|
||||
context=dict(),
|
||||
context=None,
|
||||
path='views/',
|
||||
writer='response.write',
|
||||
lexers=None,
|
||||
@@ -281,6 +277,7 @@ class TemplateParser(object):
|
||||
reader=None,
|
||||
):
|
||||
|
||||
context = context or {}
|
||||
# Keep a root level name.
|
||||
self.name = name
|
||||
# Raw text to start parsing.
|
||||
@@ -306,20 +303,9 @@ class TemplateParser(object):
|
||||
# Context for templates.
|
||||
self.context = context
|
||||
|
||||
# allow optional alternative delimiters
|
||||
if delimiters != self.default_delimiters:
|
||||
escaped_delimiters = (escape(delimiters[0]),
|
||||
escape(delimiters[1]))
|
||||
self.r_tag = compile(r'(%s.*?%s)' % escaped_delimiters, DOTALL)
|
||||
elif hasattr(context.get('response', None), 'delimiters'):
|
||||
if (context['response'].delimiters != self.default_delimiters) and (context['response'].delimiters != None):
|
||||
delimiters = context['response'].delimiters
|
||||
escaped_delimiters = (
|
||||
escape(delimiters[0]),
|
||||
escape(delimiters[1]))
|
||||
self.r_tag = compile(r'(%s.*?%s)' % escaped_delimiters,
|
||||
DOTALL)
|
||||
self.delimiters = delimiters
|
||||
escaped_delimiters = (escape(delimiters[0]), escape(delimiters[1]))
|
||||
self.r_tag = compile(r'(%s.*?%s)' % escaped_delimiters, DOTALL)
|
||||
|
||||
# Create a root level Content that everything will go into.
|
||||
self.content = Content(name=name)
|
||||
@@ -517,7 +503,8 @@ class TemplateParser(object):
|
||||
path=self.path,
|
||||
writer=self.writer,
|
||||
delimiters=self.delimiters,
|
||||
_super_nodes=super_nodes)
|
||||
_super_nodes=super_nodes,
|
||||
reader=self.reader)
|
||||
|
||||
# Make a temporary buffer that is unique for parent
|
||||
# template.
|
||||
@@ -597,8 +584,7 @@ class TemplateParser(object):
|
||||
line = i
|
||||
|
||||
# Get rid of delimiters
|
||||
line = line[len(self.delimiters[0]): \
|
||||
-len(self.delimiters[1])].strip()
|
||||
line = line[len(self.delimiters[0]): -len(self.delimiters[1])].strip()
|
||||
|
||||
# This is bad juju, but let's do it anyway
|
||||
if not line:
|
||||
@@ -820,15 +806,7 @@ def parse_template(filename,
|
||||
text = filename.read()
|
||||
text = to_native(text)
|
||||
# Use the file contents to get a parsed template and return it.
|
||||
return str(TemplateParser(text, context=context, path=path, lexers=lexers, delimiters=delimiters))
|
||||
|
||||
|
||||
def get_parsed(text):
|
||||
"""
|
||||
Returns the indented python code of text. Useful for unit testing.
|
||||
|
||||
"""
|
||||
return str(TemplateParser(text))
|
||||
return str(TemplateParser(text, context=context, path=path, lexers=lexers, delimiters=delimiters, reader=reader))
|
||||
|
||||
|
||||
class DummyResponse():
|
||||
@@ -864,7 +842,7 @@ class NOESCAPE():
|
||||
# Here for integration with gluon.
|
||||
|
||||
|
||||
def render(content="hello world",
|
||||
def render(content=None,
|
||||
stream=None,
|
||||
filename=None,
|
||||
path=None,
|
||||
@@ -914,6 +892,11 @@ def render(content="hello world",
|
||||
'012'
|
||||
|
||||
"""
|
||||
|
||||
# If we don't have anything to render, why bother?
|
||||
if content is None and stream is None and filename is None:
|
||||
raise SyntaxError("Must specify a stream or filename or content")
|
||||
|
||||
# handle defaults
|
||||
if context is None:
|
||||
context = {}
|
||||
@@ -924,6 +907,11 @@ def render(content="hello world",
|
||||
if not reader:
|
||||
reader = file_reader
|
||||
|
||||
# allow optional alternative delimiters
|
||||
if hasattr(context.get('response', None), 'delimiters'):
|
||||
if context['response'].delimiters is not None:
|
||||
delimiters = context['response'].delimiters
|
||||
|
||||
# here to avoid circular Imports
|
||||
try:
|
||||
from gluon.globals import Response
|
||||
@@ -946,20 +934,17 @@ def render(content="hello world",
|
||||
old_response_body = None
|
||||
context['response'] = Response()
|
||||
|
||||
# If we don't have anything to render, why bother?
|
||||
if not content and not stream and not filename:
|
||||
raise SyntaxError("Must specify a stream or filename or content")
|
||||
|
||||
if not content:
|
||||
if stream:
|
||||
if content is None:
|
||||
if stream is not None:
|
||||
content = stream.read()
|
||||
elif filename:
|
||||
elif filename is not None:
|
||||
content = reader(filename)
|
||||
else:
|
||||
content = '(no template found)'
|
||||
|
||||
# Execute the template.
|
||||
code = str(TemplateParser(content,
|
||||
code = str(TemplateParser(text=content,
|
||||
context=context,
|
||||
path=path,
|
||||
lexers=lexers,
|
||||
@@ -1004,7 +989,8 @@ class template(object):
|
||||
path=self.path,
|
||||
lexers=self.lexers,
|
||||
delimiters=self.delimiters,
|
||||
context=context)
|
||||
context=context,
|
||||
reader=self.reader)
|
||||
else:
|
||||
return context
|
||||
return wrapper
|
||||
|
||||
@@ -22,7 +22,7 @@ from .test_compileapp import *
|
||||
from .test_appadmin import *
|
||||
from .test_web import *
|
||||
from .test_sqlhtml import *
|
||||
from .test_scheduler import *
|
||||
# from .test_scheduler import *
|
||||
from .test_cron import *
|
||||
from .test_is_url import *
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ class TestCron(unittest.TestCase):
|
||||
def test_Token(self):
|
||||
appname_path = os.path.join(os.getcwd(), 'applications', 'welcome')
|
||||
t = Token(path=appname_path)
|
||||
self.assertNotEqual(t.acquire(), None)
|
||||
self.assertNotEqual(t.acquire(startup=True), None)
|
||||
self.assertFalse(t.release())
|
||||
self.assertEqual(t.acquire(), None)
|
||||
self.assertTrue(t.release())
|
||||
|
||||
@@ -83,30 +83,30 @@ class TestTemplate(unittest.TestCase):
|
||||
|
||||
def dummy_open(path):
|
||||
if path == pjoin('views', 'layout.html'):
|
||||
return StringIO("{{block left_sidebar}}left{{end}}"
|
||||
"{{include}}"
|
||||
"{{block right_sidebar}}right{{end}}")
|
||||
return ("{{block left_sidebar}}left{{end}}"
|
||||
"{{include}}"
|
||||
"{{block right_sidebar}}right{{end}}")
|
||||
elif path == pjoin('views', 'layoutbrackets.html'):
|
||||
return StringIO("[[block left_sidebar]]left[[end]]"
|
||||
"[[include]]"
|
||||
"[[block right_sidebar]]right[[end]]")
|
||||
return ("[[block left_sidebar]]left[[end]]"
|
||||
"[[include]]"
|
||||
"[[block right_sidebar]]right[[end]]")
|
||||
elif path == pjoin('views', 'default', 'index.html'):
|
||||
return StringIO("{{extend 'layout.html'}}"
|
||||
"{{block left_sidebar}}{{super}} {{end}}"
|
||||
"to"
|
||||
"{{block right_sidebar}} {{super}}{{end}}")
|
||||
return ("{{extend 'layout.html'}}"
|
||||
"{{block left_sidebar}}{{super}} {{end}}"
|
||||
"to"
|
||||
"{{block right_sidebar}} {{super}}{{end}}")
|
||||
elif path == pjoin('views', 'default', 'indexbrackets.html'):
|
||||
return StringIO("[[extend 'layoutbrackets.html']]"
|
||||
"[[block left_sidebar]][[super]] [[end]]"
|
||||
"to"
|
||||
"[[block right_sidebar]] [[super]][[end]]")
|
||||
return ("[[extend 'layoutbrackets.html']]"
|
||||
"[[block left_sidebar]][[super]] [[end]]"
|
||||
"to"
|
||||
"[[block right_sidebar]] [[super]][[end]]")
|
||||
elif path == pjoin('views', 'default', 'missing.html'):
|
||||
return StringIO("{{extend 'wut'}}"
|
||||
"{{block left_sidebar}}{{super}} {{end}}"
|
||||
"to"
|
||||
"{{block right_sidebar}} {{super}}{{end}}")
|
||||
return ("{{extend 'wut'}}"
|
||||
"{{block left_sidebar}}{{super}} {{end}}"
|
||||
"to"
|
||||
"{{block right_sidebar}} {{super}}{{end}}")
|
||||
elif path == pjoin('views', 'default', 'noescape.html'):
|
||||
return StringIO("""{{=NOESCAPE('<script></script>')}}""")
|
||||
return "{{=NOESCAPE('<script></script>')}}"
|
||||
raise IOError
|
||||
|
||||
self.assertEqual(
|
||||
@@ -115,7 +115,7 @@ class TestTemplate(unittest.TestCase):
|
||||
'left to right')
|
||||
self.assertEqual(
|
||||
render(filename=pjoin('views', 'default', 'indexbrackets.html'),
|
||||
path='views', delimiters=('[[', ']]'), reader=dummy_open),
|
||||
path='views', delimiters='[[ ]]', reader=dummy_open),
|
||||
'left to right')
|
||||
self.assertRaises(
|
||||
RestrictedError,
|
||||
|
||||
@@ -193,7 +193,7 @@ class TestMail(unittest.TestCase):
|
||||
message = TestMail.DummySMTP.inbox.pop()
|
||||
attachment = message.parsed_payload.get_payload(1).get_payload(decode=True)
|
||||
with open(module_file, 'rb') as mf:
|
||||
self.assertEqual(attachment.decode('utf-8'), mf.read().decode('utf-8'))
|
||||
self.assertEqual(attachment, mf.read())
|
||||
# Test missing attachment name error
|
||||
stream = open(module_file)
|
||||
self.assertRaises(Exception, lambda *args, **kwargs: Mail.Attachment(*args, **kwargs), stream)
|
||||
|
||||
Reference in New Issue
Block a user