Forms declarative style

4 views
Skip to first unread message

Ronald Jaramillo

unread,
Nov 16, 2005, 2:39:22 PM11/16/05
to turbo...@googlegroups.com
Hi,
The discussion yesterday about Form styles got me thinking.
Personally I don't like the proposed declarative style.
I like the idea that this style has the same feel as SQLObject (+1),
though I don't buy the point about subclassing.
As it is now, you can already subclass a form.

But my main objection has something to do with consistency.
If a form is a widget (and a widget container as well), why should
they differ in style to other widget elements.
Say we have a CheckboxGroup widget. Should it be used like this?

niceDogs(CheckboxGroupBase):
chiguagua = widgets.CheckBox()
rodesian = widgets.CheckBox()
pitbull = widgets.CheckBox(checked=true)

I will rather see widgets as elements that can embed and be embeded
as well.

Cheers
Ronald


________________________________
Ronald Jaramillo
mail: ronald AT checkandshare DOT com
blog: http://www.checkandshare.com/blog



Kevin Dangoor

unread,
Nov 16, 2005, 3:17:08 PM11/16/05
to turbo...@googlegroups.com
On 11/16/05, Ronald Jaramillo <ron...@checkandshare.com> wrote:
>
> Hi,
> The discussion yesterday about Form styles got me thinking.
> Personally I don't like the proposed declarative style.
> I like the idea that this style has the same feel as SQLObject (+1),
> though I don't buy the point about subclassing.
> As it is now, you can already subclass a form.

Correct, you could subclass Form if you want customized behavior.

> But my main objection has something to do with consistency.
> If a form is a widget (and a widget container as well), why should
> they differ in style to other widget elements.
> Say we have a CheckboxGroup widget. Should it be used like this?
>
> niceDogs(CheckboxGroupBase):
> chiguagua = widgets.CheckBox()
> rodesian = widgets.CheckBox()
> pitbull = widgets.CheckBox(checked=true)
>
> I will rather see widgets as elements that can embed and be embeded
> as well.

I think people were viewing forms as being different from individual
widgets. Implementation-wise, right now, Forms are widgets and it
functionally makes sense to have them that way.

I was just thinking about the actual implementation of making forms
support the declarative style and have two issues with the mechanics
of it:

1) maintaining the order of the widgets
2) mechanics of actually using a Form

As for #1, how does it work?

widgetcounter = 0

class Widget(object):
def __init__(...stuff...):
global widgetcounter
# acquire a lock
self.widgetnum = widgetcounter
widgetcounter += 1
# release lock

class MetaForm(MetaWidget):
def __init__(cls, name, bases, dct):
super(MetaForm, cls).__init__(name, bases, dct)
widgetlist =
# get all of the widgets from dct.values()
# sort them by widgetnum

I believe that will work. But, yuck.

As for the mechanics of using the form, what do people have in mind.
As normal Widget instances, you use a form by doing

form.insert(...)

Would you still do MyForm.insert(...)? (So insert on a Form would have
to be a classmethod, rather than an instance method?)

So, it's like Ronald said: do you want Forms to be consistent with
Widgets (and they *are* Widgets), or should they be consistent with
SQLObject? The devil, as they say, is in the details...

Kevin

Jeff Grimmett

unread,
Nov 16, 2005, 8:00:54 PM11/16/05
to turbo...@googlegroups.com
On 11/16/05, Kevin Dangoor <dan...@gmail.com> wrote:

So, it's like Ronald said: do you want Forms to be consistent with
Widgets (and they *are* Widgets), or should they be consistent with
SQLObject? The devil, as they say, is in the details...

Personally, I favor a widget library that models known GUI idioms - that is, after all, what forms are - a GUI. The layout and handling of a GUI should be totally *indifferent* to what is handling the data.

Maybe I'm reading too much into that last paragraph, but the implication is something unexpected.

*sigh* I appologize if I'm speaking out of turn here, and plead ignorance. I haven't had time to look at the widget stuff, and have just barely touched forms at all.

But I have looked through the source a little and it *appears* to be a nice way of programatically generating forms and retrieving data from them, which to me sounds like a web-baed GUI library, and that suggests to me that it would be a good idea to follow standard GUI idioms here and be as flexible as possible. That means, to me, that the library gives the programmer the means to lay things out, respond to events, and retrieve data as needed, but nothing beyond that ( i.e. the programmer should be the one stuffing it into a database, not the widget itself).

And again, I appologize for making any statements out of ignorance on this subject. I'm REALLY behind the curve here.  Hope this is helpful in some way.

--
"Things fall apart. The Center cannot hold."
                  - Life as a QA geek, in a nutshell.

Best,

    Jeff

Kevin Dangoor

unread,
Nov 16, 2005, 10:26:33 PM11/16/05
to turbo...@googlegroups.com
On 11/16/05, Jeff Grimmett <grimm...@gmail.com> wrote:
> On 11/16/05, Kevin Dangoor <dan...@gmail.com> wrote:
>
> > So, it's like Ronald said: do you want Forms to be consistent with
> > Widgets (and they *are* Widgets), or should they be consistent with
> > SQLObject? The devil, as they say, is in the details...
> >
>
> Personally, I favor a widget library that models known GUI idioms - that
> is, after all, what forms are - a GUI. The layout and handling of a GUI
> should be totally *indifferent* to what is handling the data.
>
> Maybe I'm reading too much into that last paragraph, but the implication is
> something unexpected.

Yep, you're reading too much into that last paragraph. What I meant was...

forms are currently declared like this:

myform = TableForm([TextField("foo1"), TextField("foo2")])

and SQLObjects are declared like this:

class MyTable(SQLObject):
foo1 = StringCol()
foo2 = StringCol()

Some folks have expressed that they'd like forms to be like this:

class MyForm(TableForm):
foo1 = TextField()
foo2 = TextField()

which is consistent with the SQLObject style, but is not consistent
with how other widgets (TextField, for example) work.

> But I have looked through the source a little and it *appears* to be a nice
> way of programatically generating forms and retrieving data from them, which
> to me sounds like a web-baed GUI library, and that suggests to me that it
> would be a good idea to follow standard GUI idioms here and be as flexible
> as possible. That means, to me, that the library gives the programmer the
> means to lay things out, respond to events, and retrieve data as needed, but
> nothing beyond that ( i.e. the programmer should be the one stuffing it into
> a database, not the widget itself).

Yep. While some day someone may write a data-aware widget, the core,
basic widgets know nothing and care nothing about what happens to the
information once it gets into your controller method.

Kevin

Don Hopkins

unread,
Nov 16, 2005, 10:44:41 PM11/16/05
to turbo...@googlegroups.com
>Some folks have expressed that they'd like forms to be like this:

class MyForm(TableForm):
foo1 = TextField()
foo2 = TextField()

>which is consistent with the SQLObject style, but is not consistent
>with how other widgets (TextField, for example) work.

The problem with the class based approach is that there's no way to
reconstruct the order of the fields in the class, which is required for
generating forms (of more than one field ;-). Since the fields are
defined in the class's dictionary, which is unordered, there's no way to
determine the order they appear in the source code, so you have to use
an array of fields instead.

Maybe you could hack around it by using a @decorator that recorded the
order it was applied to methods in another class variable. Oh, but those
are fields not methods. You can't apply decorators to fields, but you
could still call a function for every field that remembered its order.
Eww, that's gross, never mind...

-Don


Ian Bicking

unread,
Nov 16, 2005, 10:47:56 PM11/16/05
to turbo...@googlegroups.com
Don Hopkins wrote:
>>Some folks have expressed that they'd like forms to be like this:
>
>
> class MyForm(TableForm):
> foo1 = TextField()
> foo2 = TextField()
>
>
>>which is consistent with the SQLObject style, but is not consistent
>>with how other widgets (TextField, for example) work.
>
>
> The problem with the class based approach is that there's no way to
> reconstruct the order of the fields in the class, which is required for
> generating forms (of more than one field ;-). Since the fields are
> defined in the class's dictionary, which is unordered, there's no way to
> determine the order they appear in the source code, so you have to use
> an array of fields instead.

If you control the source of TextField(), you can make it increment a
counter everytime it is instantiated. Then you sort according to this
counter, essentially sorting them by their creation time.

This is how SQLObject started (if only recently) to keep track of the
order of its columns.

--
Ian Bicking / ia...@colorstudy.com / http://blog.ianbicking.org

Ian Bicking

unread,
Nov 16, 2005, 10:52:35 PM11/16/05
to turbo...@googlegroups.com
Kevin Dangoor wrote:
> myform = TableForm([TextField("foo1"), TextField("foo2")])
>
> and SQLObjects are declared like this:
>
> class MyTable(SQLObject):
> foo1 = StringCol()
> foo2 = StringCol()
>
> Some folks have expressed that they'd like forms to be like this:
>
> class MyForm(TableForm):
> foo1 = TextField()
> foo2 = TextField()

I'd played around unsuccessfully with weird dual object/class objects,
but I never quite figured it out. But I must know more now, because it
wasn't too hard. Here's an example with a very brief test:

http://svn.colorstudy.com/home/ianb/subclass_instance/

Basically this:

class MyForm(TableForm):
foo1 = TextField()
foo2 = TextField()

Is exactly equivalent to:

MyForm = type(TableForm)('MyForm', (TableForm,), {'foo1':
TextField(), 'foo2': TextField})

So if TableForm is an instance, then type(TableForm) is the class, and
the class is called with those arguments (i.e., instantiating).

It's all a little wacky, so I don't know that I'd recommend the trick.
But it does make large keyword-based instanciation easier on the eye.

Don Hopkins

unread,
Nov 16, 2005, 10:58:06 PM11/16/05
to turbo...@googlegroups.com
>If you control the source of TextField(), you can make it increment a
>counter everytime it is instantiated. Then you sort according to this
>counter, essentially sorting them by their creation time.
>
>This is how SQLObject started (if only recently) to keep track of the
>order of its columns.

Great point, bravo! I had wished there was a way to get the order of
SQLObject fields, but I didn't realize you've already figured out a way
to do it!

There is nothing wrong with your television set. Do not attempt to
adjust the picture. We are controlling the transmission. If we wish to
make it louder, we will bring up the volume. If we wish to make it
softer, we will tune it to a whisper. We will control the horizontal. We
will control the vertical. We can roll the image; make it flutter. We
can change the focus to a soft blur or sharpen it to crystal clarity.
For the next hour, sit quietly and we will control all that you see and
hear. We repeat: there is nothing wrong with your television set. You
are about to participate in a great adventure. You are about to
experience the awe and mystery which reaches from the inner mind to the
Outer SQLObject.

-Don


bon...@gmail.com

unread,
Nov 16, 2005, 11:04:13 PM11/16/05
to TurboGears

Don Hopkins wrote:
> The problem with the class based approach is that there's no way to
> reconstruct the order of the fields in the class, which is required for
> generating forms (of more than one field ;-). Since the fields are
> defined in the class's dictionary, which is unordered, there's no way to
> determine the order they appear in the source code, so you have to use
> an array of fields instead.
>
> Maybe you could hack around it by using a @decorator that recorded the
> order it was applied to methods in another class variable. Oh, but those
> are fields not methods. You can't apply decorators to fields, but you
> could still call a function for every field that remembered its order.
> Eww, that's gross, never mind...
>
>
To me, the order in the class doesn't matter. What usually matter is
when it is passed to the "view" in MVC which in TurboGear's case is a
dict for Kid to consume. I just created a "preferred ordered dict"
which has an optional "field sequence" list member.

So for my CRUD requirement, I just use py:for in Kid and still control
the order of how those fields appears. And if I later decide to
customize the layout in Kid, the same dict can still be used for direct
name access.

Jeff Grimmett

unread,
Nov 16, 2005, 11:38:28 PM11/16/05
to turbo...@googlegroups.com
On 11/16/05, Kevin Dangoor <dan...@gmail.com> wrote:

Yep, you're reading too much into that last paragraph. What I meant was...

forms are currently declared like this:

myform = TableForm([TextField("foo1"), TextField("foo2")])

and SQLObjects are declared like this:

class MyTable(SQLObject):
    foo1 = StringCol()
    foo2 = StringCol()

Some folks have expressed that they'd like forms to be like this:

class MyForm(TableForm):
    foo1 = TextField()
    foo2 = TextField()

which is consistent with the SQLObject style, but is not consistent
with how other widgets (TextField, for example) work.

Well, I can see the point of "some folks" in this case since it certainly jibes with typical GUI idioms I've used, at their simplest.
 
Yep. While some day someone may write a data-aware widget, the core, basic widgets know nothing and care nothing about what happens to the information once it gets into your controller method.

To me, that just seems like the right way to do it, but I'm fairly naive with regards to web apps.

Jeff Grimmett

unread,
Nov 16, 2005, 11:40:05 PM11/16/05
to turbo...@googlegroups.com
On 11/16/05, Don Hopkins <dhop...@donhopkins.com> wrote:

The problem with the class based approach is that there's no way to
reconstruct the order of the fields in the class, which is required for
generating forms (of more than one field ;-). Since the fields are

Beware of stupid question.

Here it is.

Why is it important to reconstruct the order of the fields?

bon...@gmail.com

unread,
Nov 17, 2005, 12:13:10 AM11/17/05
to TurboGears

Jeff Grimmett wrote:
> On 11/16/05, Don Hopkins <dhop...@donhopkins.com> wrote:
>
> The problem with the class based approach is that there's no way to
> > reconstruct the order of the fields in the class, which is required for
> > generating forms (of more than one field ;-). Since the fields are
>
>
> Beware of stupid question.
>
> Here it is.
>
> Why is it important to reconstruct the order of the fields?
>
presentation. But I don't think class level definition order is the
solution(see my other post about this).

Take the current catwalk module.

It allows you to drag/drop columns for presentation purpose. However, a
refresh would wipe it. It would be nice these things can be changed
easily and stored.

Don Hopkins

unread,
Nov 17, 2005, 1:28:05 AM11/17/05
to turbo...@googlegroups.com

Good question actually.

It’s user friendly to group related elements together in the form (like x and y coordinates), and put important ones near the top (like title and description), so you need some way to control the order of dynamically generated form elements (and also a way to further customize each element).

 

Now that Ian’s invented a way to order the fields of an SQLObject, it’s possible to automatically generate forms to edit their fields in the same order they were specified by the database designer (or declared in the python class).

 

I want to be able to declare not only the order, but also other metadata about each field.

 

I made a database browser for OpenLaszlo based on SQLObject, but I resorted to awkward kludgery to order the fields with sequence numbers.

http://www.donhopkins.com/drupal/node/44

 

Using an older version of SQLObject, I subclassed the various field and join classes so the constructors took an extra user defined “data” parameter that I could retrieve later.

So I could hang a dictionary off of each field, to give it a sequence number to sort by, and store other presentation related information.

I also had to subclass the various join fields so they had data parameters too.

 

The goal was to declare extra information about each field and join, like its sequence number, the name of a custom editor, user friendly label, help text, and other presentation parameters, so the server can automatically generate XML to drive a Laszlo user interface for browsing and editing the database, with custom widgets like checkboxes, image views, date pickers, map widgets, etc.

(BTW: I can’t wait till Google Base drops the other shoe and publishes a web API!)

 

The new version of SQLObject now has a similar but undocumented feature that I don’t quite understand, with the _extra_vars Field instance variable, so I may be able to clean up my code and use that, instead of wrapping everything with my own subclasses.

 

Ian, how did you intend _extra_vars to be used: is it meant to hang user data off of fields, or am I subverting its true goal in life (remaining secret and behind the scenes in an undisclosed location)?

The Join classes would also need to support _extra_vars as well.

It would be great for dynamic user interface generation, if SQLObject supported an easy, documented way to attach metadata to fields and joins, and officially exposed the field order too, please!  

 

            -Don

Ian Bicking

unread,
Nov 17, 2005, 2:02:55 AM11/17/05
to turbo...@googlegroups.com
Don Hopkins wrote:
> The new version of SQLObject now has a similar but undocumented feature
> that I don’t quite understand, with the _extra_vars Field instance
> variable, so I may be able to clean up my code and use that, instead of
> wrapping everything with my own subclasses.
>
>
>
> Ian, how did you intend _extra_vars to be used: is it meant to hang user
> data off of fields, or am I subverting its true goal in life (remaining
> secret and behind the scenes in an undisclosed location)?
>
> The Join classes would also need to support _extra_vars as well.

It is meant to hang data user off of it; I could add it to the other
objects as well, and probably a __getattr__ as well. The reason they
are specially collected is so that the values can also be transfered to
the SO* version of the classes.



--
Ian Bicking | ia...@colorstudy.com | http://blog.ianbicking.org

Kevin Dangoor

unread,
Nov 17, 2005, 11:06:00 AM11/17/05
to turbo...@googlegroups.com
On 11/16/05, Ian Bicking <ia...@colorstudy.com> wrote:
> I'd played around unsuccessfully with weird dual object/class objects,
> but I never quite figured it out. But I must know more now, because it
> wasn't too hard. Here's an example with a very brief test:
>
> http://svn.colorstudy.com/home/ianb/subclass_instance/
>
> Basically this:
>
> class MyForm(TableForm):
> foo1 = TextField()
> foo2 = TextField()
>
> Is exactly equivalent to:
>
> MyForm = type(TableForm)('MyForm', (TableForm,), {'foo1':
> TextField(), 'foo2': TextField})
>
> So if TableForm is an instance, then type(TableForm) is the class, and
> the class is called with those arguments (i.e., instantiating).
>
> It's all a little wacky, so I don't know that I'd recommend the trick.
> But it does make large keyword-based instanciation easier on the eye.

Interesting. I'll have to play around with this a bit to see what I
can do. I don't mind a little bit of wackiness in the TurboGears code
if it makes the application code nicer. (A *little* mind you... I'd
hate for TG to become so complex inside that no one else could work on
it!)

Kevin

Kevin Dangoor

unread,
Nov 17, 2005, 11:06:59 AM11/17/05
to turbo...@googlegroups.com
On 11/16/05, bon...@gmail.com <bon...@gmail.com> wrote:
> So for my CRUD requirement, I just use py:for in Kid and still control
> the order of how those fields appears. And if I later decide to
> customize the layout in Kid, the same dict can still be used for direct
> name access.

Being able to access in order or as a dictionary is a nice thing. I'll
have to keep that in mind.

Kevin

--
Kevin Dangoor
Author of the Zesty News RSS newsreader

email: k...@blazingthings.com
company: http://www.BlazingThings.com
blog: http://www.BlueSkyOnMars.com

Sean Cazzell

unread,
Nov 17, 2005, 12:02:55 PM11/17/05
to turbo...@googlegroups.com
Kevin,

The Python Cookbook has a couple of ordered dict implementations.
Here's one:

http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/438823


Sean Cazzell

Kevin Dangoor

unread,
Nov 17, 2005, 12:11:16 PM11/17/05
to turbo...@googlegroups.com
On 11/16/05, Ian Bicking <ia...@colorstudy.com> wrote:
> Basically this:
>
> class MyForm(TableForm):
> foo1 = TextField()
> foo2 = TextField()
>
> Is exactly equivalent to:
>
> MyForm = type(TableForm)('MyForm', (TableForm,), {'foo1':
> TextField(), 'foo2': TextField})

this is probably a little too wacky, it turns out. Consider this case:

class TableForm(Subclassable):
def important_behavior(self):
print "foo"

TableForm = TableForm()

class MyForm(TableForm):
def important_behavior(self):
print "bar"

type(MyForm) -> TableForm
MyForm.important_behavior() -> TypeError (takes 1 argument, 0 given)

Not being able to override behavior would be an evil side effect of it
looking like a class but not actually being a class. There's probably
a way to bind the function to the instance, is there not?

Kevin

Kevin Dangoor

unread,
Nov 17, 2005, 12:13:06 PM11/17/05
to turbo...@googlegroups.com
Yeah, I've seen those. The order is only a problem because Python
gives us the dict... Using the somewhat hacky counter technique plus
an ordered dict may do the trick.

Kevin

David Bernard

unread,
Nov 17, 2005, 3:54:41 PM11/17/05
to TurboGears
In my TG CRUD work, I generate edit form, view list and view screen
from SQLObject. I use the similar approach of Kevin : using *arg or a
list in the contrustor of a CompositeWidget. I also add an append()
method. Advantages of this solution :
* easy to create and extends a form automaticaly
...
editWidgetMap = {
'container' : widget4edit.FormWidgetsList,
'default' : widget4edit.TextLineWidget,
'SOStringCol': widget4edit.TextLineWidget,
'SOStringCol+long': widget4edit.TextWidget,
'SOUnicodeCol': widget4edit.TextLineWidget,
'SOUnicodeCol+long': widget4edit.TextWidget,
'SOBoolCol': widget4edit.CheckBoxWidget,
'SOForeignKey' : widget4edit.VocabularyWidget,
'SOEnumCol' : widget4edit.VocabularyWidget,
# 'SOIntCol':IntWidget,
# 'SODateTimeCol':DateTimeWidget
}


def buildWidgetsList(self, sqlobj, widgetmap):
"""
@param sqlobj the type (like app.model.Page) for wich create a
WidgetContainer
@param widgetmap the family of widgets to use for each
SQLObject field type
"""
back = []
columns = sqlobj.sqlmeta.columns
for col in sqlobj.sqlmeta.columnList:
name = col.origName
clazz = col.__class__.__name__
if (clazz == 'SOStringCol' or clazz == 'SOUnicodeCol') and
not(col.length):
clazz += '+long'
widget = widgetmap.get(clazz,
widgetmap['default'])(key=name)
if hasattr(widget, 'vocabulary') and (widget.vocabulary is
None):
if clazz == 'SOForeignKey':
referencedsql = findClass(col.foreignKey)
widget.vocabulary = SQLVocabulary(referencedsql)
elif clazz == 'SOEnumCol':
widget.vocabulary =
widgetsupport.Vocabulary(col.enumValues)
if hasattr(widget, 'defaultValue') and
(widget.defaultValue is None):
widget.defaultValue = col.enumValues[0]
if hasattr(widget, 'required') and (widget.required is
None):
widget.required = col.notNone
if hasattr(widget, 'validator') and (widget.validator is
None):
widget.validator = col.validator
back.append(widget)
return widgetmap['container'](*back) #IGNORE:W0142
...

* the WidgetContainer instance could be attach to a SQLObject type. In
my case after building a WidgetContainer I do :
if not(hasattr(sqlobj, 'editWidget')):
#autogeneration of the editwidget
sqlobj.editWidget = self.buildWidgetsList(sqlobj,
self.editWidgetMap)
sqlobj.editWidget.append(widget4edit.HiddenWidget('isNew',
validators.Bool(), True))
sqlobj.editWidget.append(widget4edit.HiddenWidget('id',
validators.Int(), -1))

* you could create 2 instances of the same WidgetContainer, an each one
could have it's own internal state without interference, like 2
instances of TextField... (may be my java background influence me too
much, but class state/field are share by all instance, and there is
only one class definition available in the system)

my 2 cents

Ian Bicking

unread,
Nov 17, 2005, 5:39:06 PM11/17/05
to turbo...@googlegroups.com
import new, types
for attr, value in new_attrs.values():
if isinstance(value, types.FunctionType):
setattr(self, attr, new.instancemethod(value, self, self.__class__)

These are things that I think are worthy of exploration, but you have to
be ready to back them out if they don't pan out.

Michael Schneider

unread,
Nov 18, 2005, 12:55:34 AM11/18/05
to TurboGears
Can take a STAN-like approach for building DOM fragments that we could
pass to kid??

I will try to work up an example.

Here is a nice over link of stan

http://www.kieranholland.com/prose/meet-stan/

Thanks
Mike

PS. Divmod uses formless to render forms, I have not used formless
yet, so I have not input on that system.

Ronald Jaramillo

unread,
Nov 18, 2005, 2:20:00 AM11/18/05
to turbo...@googlegroups.com
Love to se something like that =)
Cheers
Ronald

Minh Luu

unread,
Nov 20, 2005, 11:10:40 PM11/20/05
to turbo...@googlegroups.com
Hi,

I have a kid template like this <div>$myvalue</div>
and in my controller.py, I would like to set that variable to a HTML string,
something like
<span style="color:red">a &amp; b</span>

I found in the kid documentation and the mailling archive says that I can
use ${XML(myvalue)} to ouput HTML, but it does seem to work with turbogears.
When I do this
<div>${XML(myvalue)} in turbogears, I get an exception like this

===========================
File
"c:\opt\python24\lib\site-packages\kid-0.7adev_r186-py2.4.egg\kid\pull.py
", line 361, in feed
raise e
ExpatError: undefined entity: line 1, column 41
===========================

Any sugguestion?

Thanks,


Elvelind Grandin

unread,
Nov 21, 2005, 4:45:40 AM11/21/05
to turbo...@googlegroups.com
The problem is that kid 0.7.1 dosn't support xhtml entities. but the
more recent svn version does. You could try to upgrade to the svn
version of kid. Tg 0.9 will contain an updated version of kid.
--
cheers
elvelind grandin

MaxP

unread,
Nov 21, 2005, 2:38:09 PM11/21/05
to TurboGears
A temporary solution :

You can also disable output encoding in kid for some html tags .

from kid import serialization
serialization.HTMLSerializer.noescape_elements.add('div')

Then in your template you dont need to use XML() .
<div py:content="test"/>

It would be nice to have something like disable-output-encoding in xsl
(disabling output encoding localy and not for all html tags you define)
:

<div py:content="test" disable-output-encoding="yes"/>

Minh Luu

unread,
Nov 21, 2005, 4:57:24 PM11/21/05
to turbo...@googlegroups.com
Thank you very much for the tip. It works beautifully.
I think this would be useful in the FAQ!
Reply all
Reply to author
Forward
0 new messages