Login

Updated table tag

Author:
bl4th3rsk1t3
Posted:
June 1, 2009
Language:
Python
Version:
1.0
Score:
3 (after 3 ratings)

This table tag helps with render tables, which can be fairly complex.

I updated the previous table tag (296).

I added support for oddrow,evenrow,lastcellinrow,oddcol,evencol. And made a few minor adjustments to syntax formatting, and some non needed if conditionals

These are all of the supported variables available in the context

{{table.counter0}} {{table.counter}} {{table.rowcounter0}} {{table.rowcounter}} {{table.startrow}} {{table.endrow}} {{table.oddrow}} {{table.evenrow}} {{table.firstrow}} {{table.lastrow}} {{table.firstcell}} {{table.lastcell}} {{table.lastcellinrow}} {{table.evencol}} {{table.oddcol}} {{table.parenttable}}

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
from django.template import NodeList,Template,Context,Variable,Library,Node,Variable,loader
from django.template import TemplateSyntaxError,VariableDoesNotExist
import math
register=Library()

class TableNode(Node):
	def __init__(self, cellvar, sequence, cols, cellnodes):
		self.cellvar=cellvar
		self.sequence=sequence
		self.cols=cols
		self.cellnodes=cellnodes
	
	def __iter__(self):
		for node in self.cellnodes: yield node
	
	def get_nodes_by_type(self,nodetype):
		nodes=[]
		if isinstance(self,nodetype): nodes.append(self)
		nodes.extend(self.cellnodes.get_nodes_by_type(nodetype))
		return nodes
	
	def render(self,context):
		nodelist=NodeList()
		if context.has_key('parenttable'): parenttable=context['parenttable']
		else: parenttable={}
		context.push()
		try: values=self.sequence.resolve(context,True)
		except VariableDoesNotExist: values=[]
		if not values: values=[]
		if not hasattr(values,'__len__'):values=list(values)
		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"]=False
			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)

@register.tag(name="table")
def do_table(parser,token):
	"""
	Tag to help rendering tables. Replicates the django for tag,
	but add's in more helpers specific to tables.
	
	{{table.counter0}}
	{{table.counter}}
	{{table.rowcounter0}}
	{{table.rowcounter}}
	{{table.startrow}}
	{{table.endrow}}
	{{table.oddrow}}
	{{table.evenrow}}
	{{table.firstrow}}
	{{table.lastrow}}
	{{table.firstcell}}
	{{table.lastcell}}
	{{table.lastcellinrow}}
	{{table.evencol}}
	{{table.oddcol}}
	{{table.parenttable}}
	
	EX:
	(this is a some what more complicated example, which
	hopefully illustrates this tags use better):
	<table width="100%">
		{% table genre artist.genres.all 5 %}
			{% if table.startrow %}
				{% if table.oddrow %}
				<tr class="highlight">
				{% else %}
				<tr>
				{% endif %}
			{% endif %}
			{% if table.lastcellinrow %}
				<td class="{% if table.oddrow %}highlightableCell {% endif %}cellAutoAdjust removeableGenre">
			{% else %}
				<td class="{% if table.oddrow %}highlightableCell {% endif %}left cellAutoAdjust removeableGenre">
			{% endif %}
				<div class="options displayNone"></div>
				{{genre.name}}
				</td>
			{% if table.endrow %}
			</tr>
			{% endif %}
		{% endtable %}
	</table>
	"""
	bits=token.contents.split()
	cellvar=bits[1]
	sequence=parser.compile_filter(bits[2])
	cols=int(bits[3])
	cellnodes=parser.parse(('endtable',))
	parser.delete_first_token()
	return TableNode(cellvar,sequence,cols,cellnodes)

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 10 months, 2 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 3 weeks ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
  5. Help text hyperlinks by sa2812 1 year, 7 months ago

Comments

JimH10 (on September 9, 2009):

Thanks for the tag. I find it very useful.

I can do this

 {% table auth authors_list 5 %}

and it works great. Is there a simple way to do this

 {% table auth authors_list num_cols %}

where ctext['num_cols']=5 ? I have tried as above, as {{num_cols}}, setting self.cols=int(cols) in the init fcn, etc., but to no avail.

The background is that I manipulate the array in a way that depends on the number of columns (I arrange the names alphabetically from up to down instead of from left to right) and I don't want the number of columns to be hard coded in two places.

#

dotsbb (on January 20, 2010):

{% if table.endrow %} [tr tag] {%a endif %}

Sometimes this works wrong for last row (for example in table with 2 rows and 9 cells)

To fix it, just replace 54 line

        loopctx["endrow"]=False

to

        loopctx["endrow"]=loopctx["lastcell"]

#

Please login first before commenting.