A work-around to the feature limitation described at
http://groups.google.com/group/sprox/browse_thread/thread/5b1a002ec4110e7d
would be as follows (it can be improved upon). See problem statement
embedded in the code (with regards to __headers__ and __add_fields__
in RecordViewBase).
Thanks,
ozwyzard
# *-* coding: utf-8 *-*
from tw.api import Widget
from sprox.recordviewbase import RecordViewBase
from sprox.widgets import *
from sprox.widgetselector import WidgetSelector
import re
def name2label(name):
"""
Yanked from tw.forms, which in turn was yanked from TGFastData.
"""
"""
Convert a column name to a Human Readable name.
Yanked from TGFastData
"""
# Create label from the name:
# 1) Convert _ to spaces
# 2) Convert CamelCase to Camel Case
# 3) Upcase first character of Each Word
# Note: I *think* it would be thread-safe to
# memoize this thing.
return ' '.join([s.capitalize() for s in
re.findall(r'([A-Z][a-z0-9]+|[a-z0-9]+|[A-Z0-9]+)',
name)])
class MyRecordViewWidget(Widget):
#template = "genshi:sprox.widgets.templates.recordViewTable"
#Remove Name & Value headers
template = "genshi:mysite.controllers.my.MyRecordViewTable"
params = ["entity"]
class MyRecordFieldWidget(Widget):
# ORIGINAL sprox code (does not honor the __headers__ field of
RecordView
# template = "genshi:sprox.widgets.tempaltes.recordField"
# params = ["field_name"]
#
# My slightly modified code.
# Pass a new argument called field_name_header for each field and
use it in the template.
template = "genshi:mysite.controllers.my.MyRecordField"
params = ["field_name", "field_name_header"]
class MyRecordViewWidgetSelector(WidgetSelector):
def select(self, field):
return MyRecordFieldWidget
class MyRecordViewBase(RecordViewBase):
'''
Problem Statement:
1. Sprox 0.6.10 did not support __add_fields__ for
RecordViewBase.
The fields in __add_fields__ were assigned a simple Widget
in _do_get_field_widgets()
which did not set the required dictionary keys that are
used in the associated html template.
2. Sprox 0.6.10 did not honor __headers__ field for
RecordViewBase.
Solution:
Implement a child class of RecordViewBase to:
1. Override/Enhance _do_get_field_widgets() to add the
key:value entries to the Widget for
'field_name' & 'field_name_header' for fields belonging to
__add_fields__
2. Override/Enhance _do_get_field_widget_args() to add a new
custom key:value pair to the
Values dict, to store the field_name_header field which is
then used in the html template
'''
__base_widget_type__ = MyRecordViewWidget
__widget_selector_type__ = MyRecordViewWidgetSelector
def _my_custom_get_field_name_header(self, field_name):
if hasattr(self, '__headers__'):
# if __headers__ specified and has the mapping get it
(default to db field_name)
fnh_value = self.__headers__.get(field_name,
name2label(field_name))
else:
# else use (db) field_name
fnh_value = name2label(field_name)
return fnh_value
def _do_get_field_widget_args(self, field_name, field):
args = super(MyRecordViewBase,
self)._do_get_field_widget_args(field_name, field)
args['field_name_header'] =
self._my_custom_get_field_name_header(field_name)
return args
def _do_get_field_widgets(self, fields):
widgets = super(MyRecordViewBase,
self)._do_get_field_widgets(fields)
if hasattr(self, '__add_fields__'):
for field_name in widgets.keys():
if field_name in self.__add_fields__:
field_name_header =
self._my_custom_get_field_name_header(field_name)
field_args = {'field_name':field_name,
'field_name_header': field_name_header}
widgets[field_name] =
MyRecordFieldWidget(field_name, **field_args)
return widgets
===================
File: MyRecordField.html
===================
<tr xmlns="
http://www.w3.org/1999/xhtml" xmlns:py="http://
genshi.edgewall.org/"
class="${css_class}"
py:attrs='value_of("attrs", "")'
>
<td>
<b>$field_name_header</b>
</td>
<td> ${value[field_name]}
</td>
</tr>
=======================
File: MyRecordViewTable.html
=======================
<table xmlns="
http://www.w3.org/1999/xhtml" xmlns:py="http://
genshi.edgewall.org/"
id="${id}"
class="${css_class}"
py:attrs='value_of("attrs", "")'
>
<py:for each="child in children">
${child.display(value)}
</py:for>
</table>