[Twisted-web] maxlength input with formless

Andrea Arcangeli andrea at cpushare.com
Tue Dec 7 18:16:17 MST 2004


Hello,

This was very helpful thanks! I had to modify it a little to make it
work. I inlined the code at the end. Should I modify the
annotate/webform library instead of writing my own code to get these
features? There's a bit of duplication (though some duplication would be
still required due point 1 below).

1) I believe there's a limitation in the stan module that prevents to
introduce conditionals inside the stan source. For example I would
really like to write:

	input(...,	
	if maxlenth>= 0:
		maxlength=maxlength,
	...)

I understand this is not parseable and unfixable without some major
modification (I doubt you could still use the getattr trick accessing the
hash lookup function to implement the stan protocol with 'if' support).
At least the generators works fine, I already used generators to convert
a text string into html text by replacing all '\n' with <br />. So I've
only one copy of the long text and it gets parsed and htmlized when the
server start (and rendered dynamically from an xml page).

2) I don't understand how the iformless interface stuff works
internally. Note I don't need to understad it to use it, but I like to
have full control on the thing. I understand the API, that I have to
register and that context is carrying internally various objects
accessible with a sort of casting (I find the right way to use it it in
the below code, despite the one you posted didn't work). I read in some
sparse docs this is metaclass stuff, but I don't know anything about
metaclasses and the i*.py and compy.py are quite unreadable to my eyes.
The whole thing about metaclasses and interfaces looks quite confusing.
I'm using it just fine (inevow.ISession gives me the void * that allows
me to move from a context structure to a session structure, it's like
doing context->session C, except it seems the pointer is external to the
object so any object can be linked to any other object and it gets
automatically resolved as well, without having to preallocate the
"session" pointer in the "context" structure in C terms), but I don't
understand how it works internally exactly. So while I can use the
feature just fine when implemented in the current framework, I probably
wouldn't be using it myself in new code.

I believe it's fundamental to understand how stuff works internally to
write correct code (i.e. no memleaks and no wasted ram).

3) I'm curious to know if the interface stuff and the __implements__
stuff is handled natively by python, or if it's provided by the
librarians. I tend to think it's being implemented by the librarians.
The syntax sure has nothing new.  Is there anything related to the
interface code (i.e. iformless) that requires python language support?
(this is partly a repetition of question 2 ;)

4) what is the difference between @classmethod, @staticmethod? I see
classmethod being used in url.py. And what is __new__ doing? These three
bits are sure python native and not library features. I tried reading
some doc but I'm still quite confused about these new language features.
If you've some simple introduction pointer it's welcome.

I guess question 4 is way offtopic so feel free to redirect me to some
python-newby list instead ;).

class MaxlengthString(annotate.String):
	def __init__(self, *args, **kwargs):
		if 'maxlength' in kwargs:
			self.maxlength = kwargs['maxlength']
			del kwargs['maxlength']
		else:
			self.maxlength = 10
		super(MaxlengthString, self).__init__(*args, **kwargs)

	def coerce(self, val, configurable):
		r = super(MaxlengthString, self).coerce(val, configurable)
		if len(r) > self.maxlength:
			raise annotate.InputError, "%r is too long, maximum is %d." % (val, self.maxlength)
		return r

class MaxlengthStringRenderer(webform.StringRenderer):
	def input(self, context, slot, data, name, value):
		if data.typedValue.getAttribute('hidden'):
			T='hidden'
		else:
			T='text'
		return slot[
			tags.input(id=formutils.keyToXMLID(context.key), type=T, name=name,
				   value=value, maxlength=data.typedValue.maxlength,
				   _class="freeform-input-%s" % T)]

class MaxlengthPassword(MaxlengthString):
	requiredFailMessage = 'Please enter a password.'

class MaxlengthPasswordRenderer(webform.PasswordRenderer):
	def input(self, context, slot, data, name, value):
		return [
			tags.input(id=formutils.keyToXMLID(context.key), name=name,
				   type="password", _class="freeform-input-password",
				   maxlength=data.typedValue.maxlength),
			" Again ",
			tags.input(name="%s____2" % name, type="password",
				   _class="freeform-input-password",
				   maxlength=data.typedValue.maxlength),
			]

compy.registerAdapter(MaxlengthStringRenderer, MaxlengthString, iformless.ITypedRenderer)
compy.registerAdapter(MaxlengthPasswordRenderer, MaxlengthPassword, iformless.ITypedRenderer)

I did the same trick to make a text readonly.



More information about the Twisted-web mailing list