- The beginning of darkness...
I have started down the path to evil... Mr Bailey made a small dtml object that let us input dates and to call the dtml while passing in the names we wanted on the objects we went: <!--#with "_.namespace(varname='start')"--> <!--#var date_input--> <!--#/with--> This returns us start_year, start_month and start_day. This was very good. The requirement of using the #with tag was very bad. It looks ugly and messy. What I _wanted_ was to type: <!--#var date_input varname='start'--> and then later on add default values: <!--#var date_input varname='start' year="1999"--> With any further keywords being passed into the namespace so the DTML can find them. This looks neat and makes DTML components useable more like functions. There is namespace contamination in that you can't use anything your tag would normally (so don't expect "fmt" to be anything other than the format command of dtml!) but I think it's safe enough. So I started to delve into the not so hidden, but not so looked at code of DocumentTemplate with the aim of implementing a var2 tag as a test. I copied DT_Var.py to DT_Var2.py, had DT_Strings.py import it, no problem. Looking through DT_Var2 I noticed that the main problem is parse_params from DT_Utils.py which raises errors on non-valid keywords. I changed it to, instead, collect and return the invalid keywords if there are any. If not it returns the normal result. This shouldn't break anything unless someone was relying on the failure mode. It doesn't work. <!--#var2 date_input--> returns an "Invalid Attribute Name" error on date_input itself. I put some debug info in to test it, but just kept getting the same error and not my modified error message, even though I stopped and started the server. It was as if it was using the old parse_params even though var2 was being noticed as a valid tag and var2 doesn't even _import_ parse_params and was calling parse_params2. Very strange. So, anyone have any ideas why? Smile. It's been fun messing around in the guts of it all... -------------------------- def parse_params2(text, result=None, otherparams=None, tag='', unparmre=regex.compile( '\([\0- ]*\([^\0- =\"]+\)\)'), qunparmre=regex.compile( '\([\0- ]*\("[^"]*"\)\)'), parmre=regex.compile( '\([\0- ]*\([^\0- =\"]+\)=\([^\0- =\"]+\)\)'), qparmre=regex.compile( '\([\0- ]*\([^\0- =\"]+\)="\([^"]*\)\"\)'), **parms): result=result or {} otherparams=otherparams or {} if parmre.match(text) >= 0: name=lower(parmre.group(2)) value=parmre.group(3) l=len(parmre.group(1)) elif qparmre.match(text) >= 0: name=lower(qparmre.group(2)) value=qparmre.group(3) l=len(qparmre.group(1)) elif unparmre.match(text) >= 0: name=unparmre.group(2) l=len(unparmre.group(1)) if result: if parms.has_key(name): if parms[name] is None: raise ParseError, ( 'Attribute %s requires a value' % name, tag) result[name]=parms[name] else: raise ParseError, ( 'Invalid attribute name, "%s" result:%s' % (name,`result`) , tag) else: result['']=name return apply(parse_params,(text[l:],result),parms) elif qunparmre.match(text) >= 0: name=qunparmre.group(2) l=len(qunparmre.group(1)) if result: raise ParseError, ( 'Invalid attribute name, "%s" result:%s' % (name,`result`) , tag) else: result['']=name return apply(parse_params,(text[l:],result),parms) else: if not text or not strip(text): return result raise ParseError, ('invalid parameter: "%s"' % text, tag) if result.has_key(name): p=parms[name] if type(p) is not ListType or p: raise ParseError, ( 'Duplicate values for attribute "%s"' % name, tag) if not parms.has_key(name): otherparams[name]=value #raise ParseError, ( # 'Invalid attribute name, "%s"' % name, tag) else: result[name]=value text=strip(text[l:]) if text: return apply(parse_params,(text,result,otherparams),parms) else: if otherparams: return (result,otherparams) else: return result -------------------------- And these are the changes to class Var in DT_Var to make it Var2: def __init__(self, args, fmt='s'): args = parse_params2(args, name='', lower=1, upper=1, expr='', capitalize=1, spacify=1, null='', fmt='s', size=0, etc='...', thousands_commas=1, html_quote=1, url_quote=1, sql_quote=1, newline_to_br=1) self.newnamespace = {} if type(args) == type(()) and length(args) == 2: self.newnamespace = args[1] args = args[0] self.args=args self.modifiers=tuple( map(lambda t: t[1], filter(lambda m, args=args, used=args.has_key: used(m[0]) and args[m[0]], modifiers))) name, expr = name_param(args,'var',1) self.__name__, self.expr = name, expr self.fmt = fmt if len(args)==1 and fmt=='s': if expr is None: expr=name else: expr=expr.eval self.simple_form=expr, def render(self, md): md.update(self.newnamespace) { and then the rest of the old render... } -- Evan ~ThunderFoot~ Gibson ~ nihil mutatem, omni deletum ~ May the machines watch over you with loving grace.
Wouldn't it be easier to create an external product to do what you want? Then you could call it, as <!--#var expr="input_date(start='1',year='1999')"--> At least, I think you'd be able to do it this way, since that's what I'm just about to try myself.. (though not with dates) However I also need to define a variable that could be used in the same dhtml document "after" the above expr "call". I think that I may have a problem defining a variable in the correct scope... Brad Clements, bkc@murkworks.com (315)268-1000 http://www.murkworks.com (315)268-9812 Fax netmeeting: ils://ils.murkworks.com ICQ: 14856937 We must come down from our heights, and leave our straight paths, for the byways and low places of life, if we would learn truths by strong contrasts; and in hovels, in forecastles, and among our own outcasts in foreign lands, see what has been wrought upon our fellow-creatures by accident, hardship, or vice. - Richard Henry Dana, Jr. 1836
participants (2)
-
Brad Clements -
Evan Gibson