Permalink
Browse files

Backed out the changes in [5482] for a bit whilst some more investiga…

…tion into

side-effects is done. Refs #4565.


git-svn-id: http://code.djangoproject.com/svn/django/trunk@5511 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
1 parent dbebf54 commit 880e3cfaa6040bb745ecfdbd91be0234cdb87278 @malcolmt malcolmt committed Jun 22, 2007
@@ -94,15 +94,15 @@ def get_nodelist(cls, klass):
return cls.nodelists[klass]
get_nodelist = classmethod(get_nodelist)
- def iter_render(self, context):
+ def render(self, context):
bound_field = template.resolve_variable(self.bound_field_var, context)
context.push()
context['bound_field'] = bound_field
- for chunk in self.get_nodelist(bound_field.field.__class__).iter_render(context):
- yield chunk
+ output = self.get_nodelist(bound_field.field.__class__).render(context)
context.pop()
+ return output
class FieldWrapper(object):
def __init__(self, field ):
@@ -157,7 +157,7 @@ class EditInlineNode(template.Node):
def __init__(self, rel_var):
self.rel_var = rel_var
- def iter_render(self, context):
+ def render(self, context):
relation = template.resolve_variable(self.rel_var, context)
context.push()
if relation.field.rel.edit_inline == models.TABULAR:
@@ -169,9 +169,10 @@ def iter_render(self, context):
original = context.get('original', None)
bound_related_object = relation.bind(context['form'], original, bound_related_object_class)
context['bound_related_object'] = bound_related_object
- for chunk in loader.get_template(bound_related_object.template_name()).iter_render(context):
- yield chunk
+ t = loader.get_template(bound_related_object.template_name())
+ output = t.render(context)
context.pop()
+ return output
def output_all(form_fields):
return ''.join([str(f) for f in form_fields])
@@ -7,7 +7,7 @@ class AdminApplistNode(template.Node):
def __init__(self, varname):
self.varname = varname
- def iter_render(self, context):
+ def render(self, context):
from django.db import models
from django.utils.text import capfirst
app_list = []
@@ -54,7 +54,7 @@ def iter_render(self, context):
'models': model_list,
})
context[self.varname] = app_list
- return ()
+ return ''
def get_admin_app_list(parser, token):
"""
@@ -10,14 +10,14 @@ def __init__(self, limit, varname, user):
def __repr__(self):
return "<GetAdminLog Node>"
- def iter_render(self, context):
+ def render(self, context):
if self.user is None:
context[self.varname] = LogEntry.objects.all().select_related()[:self.limit]
else:
if not self.user.isdigit():
self.user = context[self.user].id
context[self.varname] = LogEntry.objects.filter(user__id__exact=self.user).select_related()[:self.limit]
- return ()
+ return ''
class DoGetAdminLog:
"""
@@ -24,7 +24,7 @@ def __init__(self, content_type, obj_id_lookup_var, obj_id, free,
self.photo_options, self.rating_options = photo_options, rating_options
self.is_public = is_public
- def iter_render(self, context):
+ def render(self, context):
from django.conf import settings
from django.utils.text import normalize_newlines
import base64
@@ -33,7 +33,7 @@ def iter_render(self, context):
try:
self.obj_id = template.resolve_variable(self.obj_id_lookup_var, context)
except template.VariableDoesNotExist:
- return
+ return ''
# Validate that this object ID is valid for this content-type.
# We only have to do this validation if obj_id_lookup_var is provided,
# because do_comment_form() validates hard-coded object IDs.
@@ -67,17 +67,17 @@ def iter_render(self, context):
context['hash'] = Comment.objects.get_security_hash(context['options'], context['photo_options'], context['rating_options'], context['target'])
context['logout_url'] = settings.LOGOUT_URL
default_form = loader.get_template(COMMENT_FORM)
- for chunk in default_form.iter_render(context):
- yield chunk
+ output = default_form.render(context)
context.pop()
+ return output
class CommentCountNode(template.Node):
def __init__(self, package, module, context_var_name, obj_id, var_name, free):
self.package, self.module = package, module
self.context_var_name, self.obj_id = context_var_name, obj_id
self.var_name, self.free = var_name, free
- def iter_render(self, context):
+ def render(self, context):
from django.conf import settings
manager = self.free and FreeComment.objects or Comment.objects
if self.context_var_name is not None:
@@ -86,7 +86,7 @@ def iter_render(self, context):
content_type__app_label__exact=self.package,
content_type__model__exact=self.module, site__id__exact=settings.SITE_ID).count()
context[self.var_name] = comment_count
- return ()
+ return ''
class CommentListNode(template.Node):
def __init__(self, package, module, context_var_name, obj_id, var_name, free, ordering, extra_kwargs=None):
@@ -96,14 +96,14 @@ def __init__(self, package, module, context_var_name, obj_id, var_name, free, or
self.ordering = ordering
self.extra_kwargs = extra_kwargs or {}
- def iter_render(self, context):
+ def render(self, context):
from django.conf import settings
get_list_function = self.free and FreeComment.objects.filter or Comment.objects.get_list_with_karma
if self.context_var_name is not None:
try:
self.obj_id = template.resolve_variable(self.context_var_name, context)
except template.VariableDoesNotExist:
- return ()
+ return ''
kwargs = {
'object_id__exact': self.obj_id,
'content_type__app_label__exact': self.package,
@@ -127,7 +127,7 @@ def iter_render(self, context):
comment_list = [c for c in comment_list if not c.is_hidden or (user_id == c.user_id)]
context[self.var_name] = comment_list
- return ()
+ return ''
class DoCommentForm:
"""
@@ -309,7 +309,7 @@ def finish_response(self):
"""
if not self.result_is_file() and not self.sendfile():
for data in self.result:
- self.write(data, False)
+ self.write(data)
self.finish_content()
self.close()
@@ -377,7 +377,7 @@ def send_preamble(self):
else:
self._write('Status: %s\r\n' % self.status)
- def write(self, data, flush=True):
+ def write(self, data):
"""'write()' callable as specified by PEP 333"""
assert type(data) is StringType,"write() argument must be string"
@@ -394,8 +394,7 @@ def write(self, data, flush=True):
# XXX check Content-Length and truncate if too many bytes written?
self._write(data)
- if flush:
- self._flush()
+ self._flush()
def sendfile(self):
"""Platform-specific file transmission
@@ -422,6 +421,8 @@ def finish_content(self):
if not self.headers_sent:
self.headers['Content-Length'] = "0"
self.send_headers()
+ else:
+ pass # XXX check if content-length was too short?
def close(self):
try:
@@ -222,12 +222,6 @@ def _get_content(self):
content = ''.join(self._container)
if isinstance(content, unicode):
content = content.encode(self._charset)
-
- # If self._container was an iterator, we have just exhausted it, so we
- # need to save the results for anything else that needs access
- if not self._is_string:
- self._container = [content]
- self._is_string = True
return content
def _set_content(self, value):
@@ -237,10 +231,14 @@ def _set_content(self, value):
content = property(_get_content, _set_content)
def __iter__(self):
- for chunk in self._container:
- if isinstance(chunk, unicode):
- chunk = chunk.encode(self._charset)
- yield chunk
+ self._iterator = self._container.__iter__()
+ return self
+
+ def next(self):
+ chunk = self._iterator.next()
+ if isinstance(chunk, unicode):
+ chunk = chunk.encode(self._charset)
+ return chunk
def close(self):
if hasattr(self._container, 'close'):
@@ -309,10 +309,6 @@ def html2python(data):
return data
html2python = staticmethod(html2python)
- def iter_render(self, data):
- # this even needed?
- return (self.render(data),)
-
def render(self, data):
raise NotImplementedError
@@ -7,7 +7,7 @@
from django.db.models.manager import Manager
def render_to_response(*args, **kwargs):
- return HttpResponse(loader.render_to_iter(*args, **kwargs))
+ return HttpResponse(loader.render_to_string(*args, **kwargs))
load_and_render = render_to_response # For backwards compatibility.
def get_object_or_404(klass, *args, **kwargs):
@@ -55,7 +55,6 @@
'\n<html>\n\n</html>\n'
"""
import re
-import types
from inspect import getargspec
from django.conf import settings
from django.template.context import Context, RequestContext, ContextPopException
@@ -168,12 +167,9 @@ def __iter__(self):
for subnode in node:
yield subnode
- def iter_render(self, context):
- "Display stage -- can be called many times"
- return self.nodelist.iter_render(context)
-
def render(self, context):
- return ''.join(self.iter_render(context))
+ "Display stage -- can be called many times"
+ return self.nodelist.render(context)
def compile_string(template_string, origin):
"Compiles template_string into NodeList ready for rendering"
@@ -699,26 +695,10 @@ def resolve_variable(path, context):
del bits[0]
return current
-class NodeBase(type):
- def __new__(cls, name, bases, attrs):
- """
- Ensures that either a 'render' or 'render_iter' method is defined on
- any Node sub-class. This avoids potential infinite loops at runtime.
- """
- if not (isinstance(attrs.get('render'), types.FunctionType) or
- isinstance(attrs.get('iter_render'), types.FunctionType)):
- raise TypeError('Unable to create Node subclass without either "render" or "iter_render" method.')
- return type.__new__(cls, name, bases, attrs)
-
class Node(object):
- __metaclass__ = NodeBase
-
- def iter_render(self, context):
- return (self.render(context),)
-
def render(self, context):
"Return the node rendered as a string"
- return ''.join(self.iter_render(context))
+ pass
def __iter__(self):
yield self
@@ -734,12 +714,13 @@ def get_nodes_by_type(self, nodetype):
class NodeList(list):
def render(self, context):
- return ''.join(self.iter_render(context))
-
- def iter_render(self, context):
+ bits = []
for node in self:
- for chunk in node.iter_render(context):
- yield chunk
+ if isinstance(node, Node):
+ bits.append(self.render_node(node, context))
+ else:
+ bits.append(node)
+ return ''.join(bits)
def get_nodes_by_type(self, nodetype):
"Return a list of all nodes of the given type"
@@ -748,25 +729,24 @@ def get_nodes_by_type(self, nodetype):
nodes.extend(node.get_nodes_by_type(nodetype))
return nodes
+ def render_node(self, node, context):
+ return(node.render(context))
+
class DebugNodeList(NodeList):
- def iter_render(self, context):
- for node in self:
- if not isinstance(node, Node):
- yield node
- continue
- try:
- for chunk in node.iter_render(context):
- yield chunk
- except TemplateSyntaxError, e:
- if not hasattr(e, 'source'):
- e.source = node.source
- raise
- except Exception, e:
- from sys import exc_info
- wrapped = TemplateSyntaxError('Caught an exception while rendering: %s' % e)
- wrapped.source = node.source
- wrapped.exc_info = exc_info()
- raise wrapped
+ def render_node(self, node, context):
+ try:
+ result = node.render(context)
+ except TemplateSyntaxError, e:
+ if not hasattr(e, 'source'):
+ e.source = node.source
+ raise
+ except Exception, e:
+ from sys import exc_info
+ wrapped = TemplateSyntaxError('Caught an exception while rendering: %s' % e)
+ wrapped.source = node.source
+ wrapped.exc_info = exc_info()
+ raise wrapped
+ return result
class TextNode(Node):
def __init__(self, s):
@@ -775,9 +755,6 @@ def __init__(self, s):
def __repr__(self):
return "<Text Node: '%s'>" % self.s[:25]
- def iter_render(self, context):
- return (self.s,)
-
def render(self, context):
return self.s
@@ -801,9 +778,6 @@ def encode_output(self, output):
else:
return output
- def iter_render(self, context):
- return (self.render(context),)
-
def render(self, context):
output = self.filter_expression.resolve(context)
return self.encode_output(output)
@@ -892,9 +866,6 @@ class SimpleNode(Node):
def __init__(self, vars_to_resolve):
self.vars_to_resolve = vars_to_resolve
- #def iter_render(self, context):
- # return (self.render(context),)
-
def render(self, context):
resolved_vars = [resolve_variable(var, context) for var in self.vars_to_resolve]
return func(*resolved_vars)
@@ -917,7 +888,7 @@ class InclusionNode(Node):
def __init__(self, vars_to_resolve):
self.vars_to_resolve = vars_to_resolve
- def iter_render(self, context):
+ def render(self, context):
resolved_vars = [resolve_variable(var, context) for var in self.vars_to_resolve]
if takes_context:
args = [context] + resolved_vars
@@ -933,7 +904,7 @@ def iter_render(self, context):
else:
t = get_template(file_name)
self.nodelist = t.nodelist
- return self.nodelist.iter_render(context_class(dict))
+ return self.nodelist.render(context_class(dict))
compile_func = curry(generic_tag_compiler, params, defaults, getattr(func, "_decorated_function", func).__name__, InclusionNode)
compile_func.__doc__ = func.__doc__
Oops, something went wrong. Retry.

0 comments on commit 880e3cf

Please sign in to comment.