Updated table tag

  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. update primary key (and cascade to child tables) by guettli 2 years, 1 month ago
  2. update primary key (cascade to child tables and inherited models) by variant 11 months, 3 weeks ago
  3. Prettify HTML5 middleware by runejuhl 2 years, 9 months ago
  4. {% if %} tag with {% elif %} support by amagee 3 years, 5 months ago
  5. grouper tag by visgean 2 years, 8 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"]

#

(Forgotten your password?)