def media(parser, token): bits = token.split_contents() if bits[0] == 'media': if len(bits) != 2: raise TemplateSyntaxError("'media' takes one argument (type)") type = parser.compile_filter(bits[1]) else: if len(bits) != 1: raise TemplateSyntaxError("'%s' does not take arguments" % bits[0]) type = bits[0] nodelist = parser.parse(('end' + bits[0],)) parser.delete_first_token() node = MediaNode(type, nodelist) try: block = parser.__medias_block block.nodelist.append(node) return TextNode('') except AttributeError: pass try: if BLOCK_MEDIAS in parser.__loaded_blocks: return node parser.__loaded_blocks.append(BLOCK_MEDIAS) except AttributeError: parser.__loaded_blocks = [BLOCK_MEDIAS] nodelist = NodeList() nodelist.contains_nontext = True nodelist.append(parser.create_variable_node(parser.compile_filter('block.super'))) nodelist.append(node) block = BlockNode(BLOCK_MEDIAS, nodelist) parser.__medias_block = block return block
def test_render_non_iterable(self): model = generate_random_model() nodelist = NodeList() nodelist.append(layout_helpers.RenderNextNode("'full_page'")) node = layout_helpers.RenderIterNode(Variable("list"), nodelist) with self.assertRaises(TypeError): rendered = node.render(Context({"list": model}))
def render(self, context): if 'forloop' in context: parentloop = context['forloop'] else: parentloop = {} context.push() try: values = self.sequence.resolve(context, True) except VariableDoesNotExist: values = [] if values is None: values = [] if not hasattr(values, '__len__'): values = list(values) len_values = len(values) if len_values < 1: context.pop() return self.nodelist_empty.render(context) nodelist = NodeList() if self.is_reversed: values = reversed(values) unpack = len(self.loopvars) > 1 # Create a forloop value in the context. We'll update counters on each # iteration just below. loop_dict = context['forloop'] = {'parentloop': parentloop} for i, item in enumerate(values): # Shortcuts for current loop iteration number. loop_dict['counter0'] = i loop_dict['counter'] = i+1 # Reverse counter iteration numbers. loop_dict['revcounter'] = len_values - i loop_dict['revcounter0'] = len_values - i - 1 # Boolean values designating first and last times through loop. loop_dict['first'] = (i == 0) loop_dict['last'] = (i == len_values - 1) pop_context = False if unpack: # If there are multiple loop variables, unpack the item into # them. try: unpacked_vars = dict(zip(self.loopvars, item)) except TypeError: pass else: pop_context = True context.update(unpacked_vars) else: context[self.loopvars[0]] = item for node in self.nodelist_loop: nodelist.append(node.render(context)) if pop_context: # The loop variables were pushed on to the context so pop them # off again. This is necessary because the tag lets the length # of loopvars differ to the length of each set of items and we # don't want to leave any vars from the previous loop on the # context. context.pop() context.pop() return nodelist.render(context)
def test_render_one_element(self): model = generate_random_model() nodelist = NodeList() nodelist.append(layout_helpers.RenderNextNode("'full_page'")) node = layout_helpers.RenderIterNode(Variable("list"), nodelist) rendered = node.render(Context({"list": [model]})) self.assertTrue(re.search(model.title, rendered))
def render(self, context): nodelist = NodeList() context.push() try: start = self.start.resolve(context) except VariableDoesNotExist: return '' except AttributeError: start = self.start try: end = self.end.resolve(context) except VariableDoesNotExist: return '' except AttributeError: end = self.end try: step = self.step.resolve(context) except VariableDoesNotExist: return '' except AttributeError: step = self.step for i in xrange(start, end+1, step): context[self.var_name] = i for node in self.nodelist_loop: nodelist.append(node.render(context)) context.pop() return nodelist.render(context)
def render(self, context): if 'forloop' in context: parentloop = context['forloop'] else: parentloop = {} context.push() try: values = self.sequence.resolve(context, True) except VariableDoesNotExist: values = [] if values is None: values = [] if not hasattr(values, '__len__'): values = list(values) len_values = len(values) if len_values < 1: context.pop() return self.nodelist_empty.render(context) nodelist = NodeList() if self.is_reversed: values = reversed(values) unpack = len(self.loopvars) > 1 # Create a forloop value in the context. We'll update counters on each # iteration just below. loop_dict = context['forloop'] = {'parentloop': parentloop} for i, item in enumerate(values): # Shortcuts for current loop iteration number. loop_dict['counter0'] = i loop_dict['counter'] = i+1 # Reverse counter iteration numbers. loop_dict['revcounter'] = len_values - i loop_dict['revcounter0'] = len_values - i - 1 # Boolean values designating first and last times through loop. loop_dict['first'] = (i == 0) loop_dict['last'] = (i == len_values - 1) pop_context = False if unpack: # If there are multiple loop variables, unpack the item into # them. try: unpacked_vars = dict(zip(self.loopvars, item)) except TypeError: pass else: pop_context = True context.update(unpacked_vars) else: context[self.loopvars[0]] = item for node in self.nodelist_loop: nodelist.append(node.render(context)) if pop_context: # The loop variables were pushed on to the context so pop them # off again. This is necessary because the tag lets the length # of loopvars differ to the length of each set of items and we # don't want to leave any vars from the previous loop on the # context. context.pop() context.pop() return nodelist.render(context)
def render (self, context): nodelist = NodeList () for i in range (int(self.value)): context['percentage'] = {'iter': i} for node in self.nodelist_loop: nodelist.append (node.render(context)) return nodelist.render (context)
def render(self, context): actual_form = self.form_var.resolve(context) bindings = get_bindings(actual_form) # bindings.reverse() # bind in reverse order ... nodelist = NodeList() js_info = get_js_info(actual_form) # Add the script to activate this form nodelist.append( HtmlContent( """ <script> %s $(document).ready(function(){ // new ManagementForm(parentForm, childTemplate, initialForms); %s }); </script> """ % (js_info, "\n".join(bindings)) ) ) nodelist.append(HtmlContent("</div>")) return nodelist.render(context)
def render(self, context): #resolve cube from context try: cube = self.cube.resolve(context, False) except VariableDoesNotExist: return '' #resolve dimensions dimensions = [] for dimension in self.dimensions: matched = re.match('(?P<quote>"|\')(?P<literal>\w+)(?P=quote)', dimension) if matched: dimensions.append(str(matched.group('literal'))) else: try: dimensions.append(str(Variable(dimension).resolve(context))) except VariableDoesNotExist: return '' #loop subcubes and render nodes nodelist = NodeList() for subcube in cube.subcubes(*dimensions): context[self.subcube_var] = subcube for node in self.nodelist: nodelist.append(node.render(context)) return nodelist.render(context)
def render(self, context): nodelist = NodeList() context.push() try: start = self.start.resolve(context) except VariableDoesNotExist: return '' except AttributeError: start = self.start try: end = self.end.resolve(context) except VariableDoesNotExist: return '' except AttributeError: end = self.end try: step = self.step.resolve(context) except VariableDoesNotExist: return '' except AttributeError: step = self.step for i in range(start, end, step): context[self.var_name] = i for node in self.nodelist_loop: nodelist.append(node.render(context)) context.pop() return nodelist.render(context)
def render(self, context): if (type(self.value) == StringType): context[self.key] = self.value else: nodelist = NodeList() for node in self.value: nodelist.append(node.render(context)) context[self.key] = nodelist.render(context) return ""
def do_render(self, context, sequence): nodelist = NodeList() context.push() for item in sequence: context[self.repeatvar.token] = item for node in self.nodelist: nodelist.append(node.render(context)) context.pop() return nodelist.render(context)
def render_mixers(self, context): nodelist = NodeList() inner_nodelist = self.inner_nodelist context.push() for mixer in self.mixers: context['mixer'] = mixer.template.render(context) nodelist.append(inner_nodelist.render(context)) context.pop() return nodelist.render(context)
def render_mixers(self, context): nodelist = NodeList() inner_nodelist = self.inner_nodelist context.push() for mixer in self.mixers: context['mixer'] = mixer.template.render(context) nodelist.append(inner_nodelist.render(context)) context.pop() return nodelist.render(context)
def test_render_multiple_elements_with_extra_nexts(self): models = [generate_random_model() for i in range(2)] nodelist = NodeList() nodelist.append(layout_helpers.RenderNextNode("'full_page'")) nodelist.append(layout_helpers.RenderNextNode("'full_page'")) nodelist.append(layout_helpers.RenderNextNode("'show_request'")) nodelist.append(layout_helpers.RenderNextNode("'show_request'")) node = layout_helpers.RenderIterNode(Variable("list"), nodelist) rendered = node.render(Context({"list": models})) self.assertTrue(re.search(models[0].title, rendered)) self.assertTrue(re.search(models[1].title, rendered)) self.assertFalse(re.search('request', rendered))
def render(self, context): content_type_id = self.content_type_id.resolve(context) content_type = ContentType.objects.get_for_id(content_type_id) if hasattr(content_type.model_class(), 'get_absolute_url'): pk = self.pk.resolve(context) nodelist = NodeList() nodelist.append(LINK_FORMAT % (content_type.pk, pk)) nodelist.append(self.inner_nodelist.render(context)) nodelist.append('</a>') return nodelist.render(context) else: return self.inner_nodelist.render(context)
def render(self, context): content_type_id = self.content_type_id.resolve(context) content_type = ContentType.objects.get_for_id(content_type_id) if hasattr(content_type.model_class(), 'get_absolute_url'): pk = self.pk.resolve(context) nodelist = NodeList() #nodelist.append(LINK_FORMAT % (content_type.pk, pk)) nodelist.append(self.inner_nodelist.render(context)) nodelist.append('</a>') return nodelist.render(context) else: return self.inner_nodelist.render(context)
def render(self, context): nodelist = NodeList() if 'forloop' in context: parentloop = context['forloop'] else: parentloop = {} context.push() try: values = self.sequence.resolve(context, True) except VariableDoesNotExist: values = [] if values is None: values = [] if not hasattr(values, '__len__'): values = list(values) len_values = len(values) if self.reversed: values = reversed(values) unpack = len(self.loopvars) > 1 for i, item in enumerate(values): context['forloop'] = { # Shortcuts for current loop iteration number. 'counter0': i, 'counter': i+1, # Reverse counter iteration numbers. 'revcounter': len_values - i, 'revcounter0': len_values - i - 1, # Boolean values designating first and last times through loop. 'first': (i == 0), 'last': (i == len_values - 1), 'parentloop': parentloop, } if unpack: # If there are multiple loop variables, unpack the item into # them. context.update(dict(zip(self.loopvars, item))) else: context[self.loopvars[0]] = item for node in self.nodelist_loop: nodelist.append(node.render(context)) if unpack: # The loop variables were pushed on to the context so pop them # off again. This is necessary because the tag lets the length # of loopvars differ to the length of each set of items and we # don't want to leave any vars from the previous loop on the # context. context.pop() context.pop() return nodelist.render(context)
def render(self, context): nodelist = NodeList() sidebar_list = Sidebar.all().order("order").fetch(100) context.push() for sidebar in sidebar_list: context.push() context["sidebar"] = sidebar for node in self.nodelist_loop: nodelist.append(node.render(context)) context.pop() context.pop() return nodelist.render(context)
def render(self, context): nodelist = NodeList() if context.has_key('forloop'): parentloop = context['forloop'] else: parentloop = {} context.push() try: values = self.sequence.resolve(context, True) except VariableDoesNotExist: values = [] if values is None: values = [] if not hasattr(values, '__len__'): values = list(values) len_values = len(values) if self.reversed: # From http://www.python.org/doc/current/tut/node11.html def reverse(data): for index in range(len(data) - 1, -1, -1): yield data[index] values = reverse(values) for i, item in enumerate(values): context['forloop'] = { # shortcuts for current loop iteration number 'counter0': i, 'counter': i + 1, # reverse counter iteration numbers 'revcounter': len_values - i, 'revcounter0': len_values - i - 1, # boolean values designating first and last times through loop 'first': (i == 0), 'last': (i == len_values - 1), 'parentloop': parentloop, } context[self.loopvar] = item for node in self.nodelist_loop: nodelist.append(node.render(context)) context.pop() return nodelist.render(context)
def test_render_multiple_elements_with_remainder(self): models = [generate_random_model() for i in range(random.randint(5, 8))] nodelist = NodeList() nodelist.append(RenderNextNode("'full_page'")) nodelist.append(RenderNextNode("'show_request'")) nodelist.append(RenderNextNode("'full_page'")) nodelist.append(RenderRemainderNode("'full_page'")) node = RenderIterNode(Variable("list"), nodelist) rendered = node.render(Context({"list": models})) self.assertTrue(re.search(models[0].title, rendered)) self.assertFalse(re.search(models[1].title, rendered)) self.assertTrue(re.search(models[2].title, rendered)) for model in models[3:]: self.assertTrue(re.search(model.title, rendered))
def render(self, context): nodelist = NodeList() if context.has_key('forloop'): parentloop = context['forloop'] else: parentloop = {} context.push() try: values = self.sequence.resolve(context, True) except VariableDoesNotExist: values = [] if values is None: values = [] if not hasattr(values, '__len__'): values = list(values) len_values = len(values) if self.reversed: # From http://www.python.org/doc/current/tut/node11.html def reverse(data): for index in range(len(data)-1, -1, -1): yield data[index] values = reverse(values) for i, item in enumerate(values): context['forloop'] = { # shortcuts for current loop iteration number 'counter0': i, 'counter': i+1, # reverse counter iteration numbers 'revcounter': len_values - i, 'revcounter0': len_values - i - 1, # boolean values designating first and last times through loop 'first': (i == 0), 'last': (i == len_values - 1), 'parentloop': parentloop, } context[self.loopvar] = item for node in self.nodelist_loop: nodelist.append(node.render(context)) context.pop() return nodelist.render(context)
def forcomment(context, nodelist, filediff, review=None): """ Loops over a list of comments beloning to a filediff. This will populate a special ``comment`` variable for use in the content. This is of the type :model:`reviews.Comment`. """ new_nodelist = NodeList() context.push() if not review: comments = filediff.comments.all() else: comments = filediff.comments.filter(review=review) for comment in comments: context['comment'] = comment for node in nodelist: new_nodelist.append(node.render(context)) context.pop() return new_nodelist.render(context)
def forcomment(context, nodelist, filediff, review=None): """ Loops over a list of comments beloning to a filediff. This will populate a special ``comment`` variable for use in the content. This is of the type :model:`reviews.Comment`. """ new_nodelist = NodeList() context.push() if not review: comments = filediff.comments.all() else: comments = filediff.comments.filter(review=review) for comment in comments: context['comment'] = comment for node in nodelist: new_nodelist.append(node.render(context)) context.pop() return new_nodelist.render(context)
def render(self, context): nodelist = NodeList() if context.has_key('parenttable'): parenttable = context['parenttable'] else: parenttable = {} context.push() values = self.get_values(context) len_values = len(values) innernodelist = NodeList() totalrows = int(math.ceil(float(len_values) / float(self.cols))) rowcount = 0 for i, item in enumerate(values): loopctx = { 'counter0': i, 'counter': i + 1, 'rowcounter0': (i / self.cols), 'rowcounter': ((i / self.cols) + 1), 'firstrow': (i < self.cols), 'lastrow': (i > len_values - self.cols), 'firstcell': (i == 0), 'lastcell': (i == len_values - 1), 'evencol': (i % 2) == 0, 'oddcol': (i % 2) == 1, 'parenttable': parenttable, } context[self.cellvar] = item loopctx['oddrow'] = False loopctx['evenrow'] = False loopctx['lastcellinrow'] = False loopctx["startrow"] = False loopctx["endrow"] = loopctx["lastcell"] if totalrows == 1 and i == len_values - 1: loopctx['lastcellinrow'] = True elif i == (len_values - 1): loopctx['lastcellinrow'] = True if i % self.cols == 0: nodelist.append(innernodelist.render(context)) innernodelist = NodeList() loopctx["startrow"] = True if (rowcount + 1) % 2 == 0: loopctx["oddrow"] = False loopctx["evenrow"] = True else: loopctx["oddrow"] = True loopctx["evenrow"] = False elif (i + 1) % self.cols == 0: loopctx['lastcellinrow'] = True loopctx["endrow"] = True rowcount += 1 context['table'] = loopctx for node in self.cellnodes: innernodelist.append(node.render(context)) if innernodelist and len(innernodelist) > 0: nodelist.append(innernodelist.render(context)) context.pop() return nodelist.render(context)
def render(self, context): nodelist = NodeList() if context.has_key('parenttable'): parenttable = context['parenttable'] else: parenttable = {} context.push() values = self.get_values(context) len_values = len(values) innernodelist = NodeList() totalrows = int(math.ceil(float(len_values) / float(self.cols))) rowcount = 0 for i, item in enumerate(values): loopctx = { 'counter0':i, 'counter':i+1, 'rowcounter0':(i/self.cols), 'rowcounter':((i/self.cols)+1), 'firstrow':(i<self.cols), 'lastrow':(i>len_values-self.cols), 'firstcell':(i==0), 'lastcell':(i==len_values-1), 'evencol':(i%2)==0, 'oddcol':(i%2)==1, 'parenttable':parenttable, } context[self.cellvar] = item loopctx['oddrow'] = False loopctx['evenrow'] = False loopctx['lastcellinrow'] = False loopctx["startrow"] = False loopctx["endrow"] = loopctx["lastcell"] if totalrows == 1 and i == len_values-1: loopctx['lastcellinrow'] = True elif i == (len_values-1): loopctx['lastcellinrow'] = True if i % self.cols == 0: nodelist.append(innernodelist.render(context)) innernodelist = NodeList() loopctx["startrow"] = True if (rowcount+1)%2==0: loopctx["oddrow"] = False loopctx["evenrow"] = True else: loopctx["oddrow"] = True loopctx["evenrow"] = False elif (i+1) % self.cols==0: loopctx['lastcellinrow'] = True loopctx["endrow"] = True rowcount += 1 context['table'] = loopctx for node in self.cellnodes: innernodelist.append(node.render(context)) if innernodelist and len(innernodelist)>0: nodelist.append(innernodelist.render(context)) context.pop() return nodelist.render(context)
def render(self, context, depth=0, values=False): nodelist = NodeList() if 'recurseloop' in context: parentloop = context['recurseloop'] else: parentloop = {} context.push() # On the first recursion pass, we have no values if not values: try: values = self.sequence.resolve(context, True) except VariableDoesNotExist: values = [] if values is None: values = [] if not hasattr(values, '__len__'): values = list(values) len_values = len(values) # Create a recurseloop value in the context. We'll update counters on each iteration just below. loop_dict = context['recurseloop'] = {'parent': parentloop} loop_dict['depth'] = depth + 1 loop_dict['depth0'] = depth for i, item in enumerate(values): # Add the additional arguments to the context # They come in the form of {'name':(initial,increment)} # As for now only numbers are supported, but also strings can be multiplied for k, v in self.kwargs.iteritems(): context[k] = v[0] + v[1] * depth # Shortcuts for current loop iteration number. loop_dict['counter0'] = i loop_dict['counter'] = i + 1 # Boolean values designating first and last times through loop. loop_dict['first'] = (i == 0) loop_dict['last'] = (i == len_values - 1) context[self.loopvar] = item for node in self.nodelist_first: nodelist.append(node.render(context)) if len(getattr(item, self.children_name)): nodelist.append( self.render(context, depth + 1, getattr(item, self.children_name))) for node in self.nodelist_second: nodelist.append(node.render(context)) context.pop() return nodelist.render(context)
def from_string(cls, template_soup, origin=''): result = TemplateComponentBucket() within = None node_bucket = NodeList() for m in Lexer(template_soup, origin).tokenize(): attributes = m.split_contents() if not attributes: continue if attributes[0] in cls.BLOCKTAGS: prop = cls._parse_parameters(attributes) within = attributes[0] node_bucket = NodeList() elif attributes[0] in cls.ENDBLOCKTAGS: prop['blocktag'] = within within = None rendered_inner = Parser(node_bucket).parse().render(TEMPLATECOMPONENTS_CONTEXT) result.append(TemplateComponentBlock(rendered_inner, origin=origin, **prop)) elif within: node_bucket.append(m) return result
def render(self, context, depth=0, values=False): nodelist = NodeList() if 'recurseloop' in context: parentloop = context['recurseloop'] else: parentloop = {} context.push() # On the first recursion pass, we have no values if not values: try: values = self.sequence.resolve(context, True) except VariableDoesNotExist: values = [] if values is None: values = [] if not hasattr(values, '__len__'): values = list(values) len_values = len(values) # Create a recurseloop value in the context. We'll update counters on each iteration just below. loop_dict = context['recurseloop'] = {'parent': parentloop} loop_dict['depth'] = depth + 1 loop_dict['depth0'] = depth for i, item in enumerate(values): # Add the additional arguments to the context # They come in the form of {'name':(initial,increment)} # As for now only numbers are supported, but also strings can be multiplied for k,v in self.kwargs.iteritems(): context[k] = v[0] + v[1]*depth # Shortcuts for current loop iteration number. loop_dict['counter0'] = i loop_dict['counter'] = i+1 # Boolean values designating first and last times through loop. loop_dict['first'] = (i == 0) loop_dict['last'] = (i == len_values - 1) context[ self.loopvar ] = item for node in self.nodelist_first: nodelist.append( node.render(context) ) if len( getattr( item, self.children_name ) ): nodelist.append( self.render( context, depth+1, getattr( item, self.children_name ) ) ) for node in self.nodelist_second: nodelist.append( node.render(context) ) context.pop() return nodelist.render(context)
def callback(tagname, label=None): if label is None: nodelist = parser.parse(('endtitle',)) parser.delete_first_token() return TitleNode(tagname, nodelist) else: # WARNING: Undocumented festures of Django are used here. from django.template import FilterExpression, NodeList, Parser, VariableNode from django.template.loader_tags import BlockNode nodelist = NodeList() nodelist.append(TitleComponentNode(tagname, label)) nodelist.append(VariableNode(FilterExpression('block.super', Parser('')))) nodelist2 = NodeList() nodelist2.append(BlockNode('title', nodelist)) return NodeListNode(nodelist2)
def callback(tagname, label=None, url=None, urlname=None): if label is None and url is None and urlname is None: nodelist = parser.parse(('endpath',)) parser.delete_first_token() return PathNode(tagname, nodelist) elif label is not None and (url is not None or urlname is not None): # WARNING: Undocumented festures of Django are used here. from django.template import FilterExpression, NodeList, Parser, VariableNode from django.template.loader_tags import BlockNode nodelist = NodeList() nodelist.append(VariableNode(FilterExpression('block.super', Parser('')))) nodelist.append(PathComponentNode(tagname, label, url, urlname)) nodelist2 = NodeList() nodelist2.append(BlockNode('path', nodelist)) return NodeListNode(nodelist2) else: raise template.TemplateSyntaxError('%s tag syntax error' % tagname)
def render(self, context): """ This class has to be able to deal with two classes essentially... NestedModelForm and BaseFormset. Key thing to note here is that when we get a BaseFormset, what is happening is that the form associated with that BaseFormset has children. """ top_level = self.top_level actual_form = self.form_var.resolve(context) is_formset = issubclass(actual_form.__class__, BaseFormSet) form_name = get_form_name(actual_form) if not is_formset else get_form_name(actual_form.parent_form) # print("== Rendering %s (Formset: %s) " % (form_name, is_formset)) if self.helper is not None: actual_helper = self.helper_var.resolve(context) else: actual_helper = get_default_helper() if not hasattr(actual_form, "helper") else actual_form.helper if actual_helper.form_tag: actual_helper.form_tag = False # raise template.TemplateSyntaxError("form_tag cannot be True on the helper, please go and rectify that") # Place a link on the formset back to its parent form if not is_formset and hasattr(actual_form, "inline_form"): actual_form.inline_form.parent_form = actual_form """ Basically we create a node list and all the following things to it: - <div id='{form_name}_form_div' class='form-container'> - HtmlContent - Fields from the parent form - The inline form which prints the children and management form (hidden) - <div id='{form_name}_children_div' class='form-children'> --- Kids printed here --- </div> - <div id='{form_name}_management_form_div' class='management-form-div'> - Management form (hidden) - Inline actions form (if one exists) - </div> - </div> Then we return nodelist.render """ # Add the forms to the nodelist nodelist = NodeList() # Add the main form to our node list # === PRINT THE PARENT FORM if not is_formset: form_div_class = "%s_form_div" % form_name # print("Creating form div class: %s" %form_div_class) nodelist.append(HtmlContent("<div id='%s' class='form-container'>" % form_div_class)) nodelist.append(CrispyFormNode(form=self.form, helper=self.helper)) # === PRINT THE KIDS if is_formset: # e.g. BuildingFormSet # We need to add each form AND print the management form # Add a DIV for the children children_div_class = "%s_children_div" % form_name nodelist.append(HtmlContent("<div id='%s' class='form-children'>" % children_div_class)) for child_index in range(len(actual_form.forms)): child_form = actual_form.forms[child_index] if not hasattr(child_form, "helper"): child_form.helper = get_default_helper() child_form_name = "%s_%s" % (get_form_name(child_form), child_index) # print(" Adding %s to the nodelist" % child_form_name) child_form_helper_name = "%s_helper" % child_form_name context[child_form_name] = child_form context[child_form_helper_name] = child_form.helper process_helper(child_form.helper) if hasattr(child_form, "inline_form"): # print(" %s is a NestedModelForm, wrapping it in a nested node" % child_form_name) nodelist.append(NestedFormNode(child_form_name, child_form_helper_name, top_level=False)) else: # print(" %s (%s) is NOT a NestedModelForm, wrapping it in a crispy node" % (child_form_name, child_form.__class__)) nodelist.append(CrispyFormNode(child_form_name, child_form_helper_name)) nodelist.append(HtmlContent("</div>")) # We need to print the management form for these kids management_form_helper = FormHelper() management_form_helper.form_tag = False management_form_helper.disable_csrf = True management_form = actual_form.management_form context["%s_management_form" % form_name] = management_form context["%s_management_form_helper" % form_name] = management_form_helper # Place a data binding on the management form for KnockoutJS fields = management_form.fields fields["TOTAL_FORMS"].widget.attrs["data-bind"] = "value: totalForms" fields["INITIAL_FORMS"].widget.attrs["data-bind"] = "value: initialForms" fields["MAX_NUM_FORMS"].widget.attrs["data-bind"] = "value: maxForms" # Let Crispy handle the printing of this... # print("Adding %s management_form to the node list" % form_name) # Add a div for the management form management_form_div_class = get_management_form_div_name(actual_form.parent_form) nodelist.append(HtmlContent("<div id='%s' class='management-form-div'>" % management_form_div_class)) nodelist.append(CrispyFormNode("%s_management_form" % form_name, "%s_management_form_helper" % form_name)) # Check if there is an inline form if hasattr(actual_form, "actions_form") and actual_form.actions_form is not None: inline_actions_form_name = "%s-inline_actions_form" % get_form_name(actual_form.actions_form) inline_actions_form_helper_name = "%s-helper" % inline_actions_form_name context[inline_actions_form_name] = actual_form.actions_form context[inline_actions_form_helper_name] = actual_form.actions_form().helper nodelist.append(CrispyFormNode(form=inline_actions_form_name, helper=inline_actions_form_helper_name)) nodelist.append(HtmlContent("</div>")) else: # not a formset """ We have two cases to deal with here: - BlockForm - it has an inline form that we need to print here - TenantForm - no inline form to worry about... If it has an inline form, note that we need to make a NestedModelNode """ if hasattr(actual_form, "inline_form"): context["%s_inline_form" % form_name] = actual_form.inline_form nodelist.append(NestedFormNode("%s_inline_form" % form_name, self.helper, top_level=False)) if not is_formset: # we didn't add this if it was a formset nodelist.append(HtmlContent("</div>")) # for the form if top_level: # print out ALL the script templates nodelist.append(KnockoutFormTemplate(self.form)) return nodelist.render(context)
def render(self, context): nodelist = NodeList() form = self.form_var.resolve(context) child_forms = [] # recursively find all inline_form that need to get printed while hasattr(form, "child_form"): child_forms.append((form.child_form, form)) form = form.child_form() """ All the nested forms we print out will have this general structure - <div id='{form_name}_form_div' class='form-container'> - HtmlContent - Fields from the parent form - The inline form which prints the children and management form (hidden) - <div id='{form_name}_children_div' class='form-children'> --- Kids printed here --- </div> - <div id='{form_name}_management_form_div' class='management-form-div'> - Management form (hidden) - Inline actions form (if one exists) - </div> - </div> """ # Loop through each and get the knockout templates for each for child_form, parent_form in child_forms: child_form = child_form() if isinstance(child_form, type) else child_form child_form.fields["delete_button"] = SubmitButtonField() # Add knockoutjs bindings to the child form fields for field_name, field in child_form.fields.iteritems(): attr = "{'id' : 'id_' + prefix + '-' + index + '-%s', 'name' : prefix + '-' + index + '-%s'}" % ( field_name, field_name, ) field.widget.attrs["data-bind"] = mark_safe("attr: %s" % attr) form_name = get_form_name(child_form) template_name = get_form_template_name(child_form) context["child_%s" % form_name] = child_form context["child_%s_helper" % form_name] = get_default_helper() # print out the script for the template nodelist.append(HtmlContent('<script type="text/html" id="%s">' % template_name)) form_container_attrs = "{'id': '%s_form_div' }" % get_form_name( child_form, prefix="' + prefix + '-' + index + '" ) nodelist.append( HtmlContent('<div data-bind="attr: %s" class="form-container">' % mark_safe(form_container_attrs)) ) nodelist.append(CrispyFormNode(form="child_%s" % form_name, helper="child_%s_helper" % form_name)) if hasattr(child_form, "inline_form"): # then print the management form as well """ If our child has a child (e.g. building has tenants) then print the management form for it's child (tenant) """ # first we need to actually print the div to hold the kids form_children_attrs = "{'id': '%s_children_div' }" % get_form_name( child_form, prefix="' + prefix + '-' + index +'" ) nodelist.append( HtmlContent( """ <div data-bind="attr: %s" class="form-children"></div> """ % mark_safe(form_children_attrs) ) ) management_form_div_class = get_management_form_div_name( parent_form, prefix="' + prefix + '-' + index + '" ) management_form_div_attrs = "{'id' : '%s'}" % management_form_div_class nodelist.append( HtmlContent( """ <div data-bind="attr: %s" class='management-form-div'> """ % management_form_div_attrs ) ) formset = child_form.inline_form grand_child_management_form = child_form.inline_form.management_form # Tweak it and adds Knockout bindings parent_prefix = parent_form.inline_form.prefix child_prefix = child_form.inline_form.prefix fields = grand_child_management_form.fields for field_name, field in fields.iteritems(): attr = ( "{'id' : 'id_' + prefix + '-' + index + '-%s-%s', 'name' : prefix + '-' + index + '-%s-%s'}" % (child_prefix, field_name, child_prefix, field_name) ) if field_name == "TOTAL_FORMS": attr = ( "{'id' : 'id_' + prefix + '-' + index + '-%s-%s', 'name' : prefix + '-' + index + '-%s-%s', 'value': totalForms }" % (child_prefix, field_name, child_prefix, field_name) ) field.widget.attrs["data-bind"] = mark_safe("attr: %s" % attr) context["child_%s_management_form" % form_name] = grand_child_management_form context["child_%s_management_form_helper" % form_name] = get_default_helper() nodelist.append( CrispyFormNode( "child_%s_management_form" % form_name, "child_%s_management_form_helper" % form_name ) ) if hasattr(formset, "actions_form") and formset.actions_form is not None: inline_actions_form_name = "%s-inline_actions_form" % get_form_name(child_form) inline_actions_form_helper_name = "%s-helper" % inline_actions_form_name context[inline_actions_form_name] = formset.actions_form context[inline_actions_form_helper_name] = formset.actions_form().helper nodelist.append( CrispyFormNode(form=inline_actions_form_name, helper=inline_actions_form_helper_name) ) nodelist.append(HtmlContent("</div>")) # end of the management form div nodelist.append(HtmlContent("</div>")) # end of form-cotnainer nodelist.append(HtmlContent("</script>")) return nodelist.render(context)
def render(self, context): if 'forloop' in context: parentloop = context['forloop'] else: parentloop = {} context.push() vals_list = [] len_values_list = [] for s in self.sequence_list: try: values = s.resolve(context, True) except VariableDoesNotExist: values = [] if values is None: values = [] if not hasattr(values, '__len__'): values = list(values) vals_list.append(values) len_values_list.append(len(values)) len_values = self.get_overall_len(len_values_list) if len_values < 1: context.pop() return self.nodelist_empty.render(context) nodelist = NodeList() def rev(revd, values): return revd and reversed(values) or values values_list = [rev(*v) for v in zip(self.is_reversed_list, vals_list)] unpack_list = [len(l) > 1 for l in self.loopvars_list] # Create a forloop value in the context. We'll update counters on each # iteration just below. loop_dict = context['forloop'] = {'parentloop': parentloop} for i, items in enumerate(self.zip(*values_list)): # Shortcuts for current loop iteration number. loop_dict['counter0'] = i loop_dict['counter'] = i+1 # Reverse counter iteration numbers. loop_dict['revcounter'] = len_values - i loop_dict['revcounter0'] = len_values - i - 1 # Boolean values designating first and last times through loop. loop_dict['first'] = (i == 0) loop_dict['last'] = (i == len_values - 1) uli_zip = zip(unpack_list, self.loopvars_list, items) for unpack, loopvars, item in uli_zip: if unpack: # If there are multiple loop variables, unpack the item # into them. context.update(dict(zip(loopvars, item))) else: context[loopvars[0]] = item for node in self.nodelist_loop: nodelist.append(node.render(context)) for unpack in unpack_list: if unpack: # The loop variables were pushed on to the context so pop # them off again. This is necessary because the tag lets # the length of loopvars differ to the length of each set # of items and we don't want to leave any vars from the # previous loop on the context. context.pop() context.pop() return nodelist.render(context)
def process_node_list(self, nodelist, context): new_nodes = NodeList() variable_nodes = [] i = nodelist.__len__() - 1 l = 0 while l <= i: while l <= i: this_node = nodelist[l] node_class = this_node.__class__.__name__ if node_class == "ForNode": this_node = self.assemble_for_node(this_node, context) if node_class == "IfNode": this_node = self.assemble_if_node(this_node, context) if node_class == 'TextNode': splitted = self.split_text_node(this_node.s) for item in splitted: new_nodes.append(item) else: new_nodes.append(this_node) if "VariableNode" in node_class: variable_nodes.append(new_nodes.__len__() - 1) l = l + 1 schema_props = [] for item in variable_nodes: node_in_question = new_nodes[item] schema_prop = '' if hasattr(node_in_question, 'filter_expression'): filter_exp = str(node_in_question.filter_expression) filter_exp = filter_exp.replace(self.object_name + '.', '') # ensure ones with added template tags work properly if '|' in filter_exp: filter_exp = filter_exp[:filter_exp.find('|')] try: schema_prop = schemaprop(self.obj, filter_exp, item) except: e = sys.exc_info()[0] raise TemplateSyntaxError(e) schema_props.append(schema_prop) prop_count = schema_props.__len__() - 1 prop_index = 0 while prop_index <= prop_count: prior_node_counter = 1 this_prop = schema_props[prop_index] prior_node = new_nodes[this_prop.variable_node - prior_node_counter] found_prior = False while not (found_prior or (prior_node_counter == this_prop.variable_node)): if prior_node.__class__.__name__ == 'CloseTagNode': prior_node.s = ' ' + str(this_prop) + prior_node.s found_prior = True elif prior_node.__class__.__name__ == 'OpenVoidNode': found_prior = True prior_node.s = prior_node.s + str(this_prop) + ' ' elif prior_node.__class__.__name__ == 'OpenTagNode': found_prior = True else: prior_node_counter = prior_node_counter + 1 prior_node = new_nodes[this_prop.variable_node - prior_node_counter] prop_index = prop_index + 1 scope = schemascope(self.obj) top_text = "<" + self.html_class + ' ' if self.html_attribute: top_text = top_text + self.html_attribute if self.id_attr: top_text = top_text + ' id="#' + self.id_attr + str(self.obj.pk) + '"' top_text = top_text + ' itemscope itemtype=' + scope + '>' bottom_text = "</" + self.html_class + ">" topnode = TextNode(top_text) bottomnode = TextNode(bottom_text) new_nodes.insert(0, topnode) new_nodes.append(bottomnode) return new_nodes
def render(self, context): if 'forloop' in context: parentloop = context['forloop'] else: parentloop = {} context.push() vals_list = [] len_values_list = [] for s in self.sequence_list: try: values = s.resolve(context, True) except VariableDoesNotExist: values = [] if values is None: values = [] if not hasattr(values, '__len__'): values = list(values) vals_list.append(values) len_values_list.append(len(values)) len_values = self.get_overall_len(len_values_list) if len_values < 1: context.pop() return self.nodelist_empty.render(context) nodelist = NodeList() def rev(revd, values): return revd and reversed(values) or values values_list = [rev(*v) for v in zip(self.is_reversed_list, vals_list)] unpack_list = [len(l) > 1 for l in self.loopvars_list] # Create a forloop value in the context. We'll update counters on each # iteration just below. loop_dict = context['forloop'] = {'parentloop': parentloop} for i, items in enumerate(self.zip(*values_list)): # Shortcuts for current loop iteration number. loop_dict['counter0'] = i loop_dict['counter'] = i+1 # Reverse counter iteration numbers. loop_dict['revcounter'] = len_values - i loop_dict['revcounter0'] = len_values - i - 1 # Boolean values designating first and last times through loop. loop_dict['first'] = (i == 0) loop_dict['last'] = (i == len_values - 1) uli_zip = zip(unpack_list, self.loopvars_list, items) for unpack, loopvars, item in uli_zip: if unpack: # If there are multiple loop variables, unpack the item # into them. context.update(dict(zip(loopvars, item))) else: context[loopvars[0]] = item for node in self.nodelist_loop: nodelist.append(node.render(context)) for unpack in unpack_list: if unpack: # The loop variables were pushed on to the context so pop # them off again. This is necessary because the tag lets # the length of loopvars differ to the length of each set # of items and we don't want to leave any vars from the # previous loop on the context. context.pop() context.pop() return nodelist.render(context)