[Checkins]
SVN: z3c.formjs/branches/pcardune-client-notify-r87806/src/z3c/formjs/jsfunction.
redo the way functions are rendered so we can support nested
namespaces.
Paul Carduner
paulcarduner at gmail.com
Fri Jul 11 23:32:33 EDT 2008
Log message for revision 88274:
redo the way functions are rendered so we can support nested namespaces.
Changed:
U z3c.formjs/branches/pcardune-client-notify-r87806/src/z3c/formjs/jsfunction.py
U z3c.formjs/branches/pcardune-client-notify-r87806/src/z3c/formjs/jsfunction.txt
-=-
Modified: z3c.formjs/branches/pcardune-client-notify-r87806/src/z3c/formjs/jsfunction.py
===================================================================
--- z3c.formjs/branches/pcardune-client-notify-r87806/src/z3c/formjs/jsfunction.py 2008-07-12 01:48:39 UTC (rev 88273)
+++ z3c.formjs/branches/pcardune-client-notify-r87806/src/z3c/formjs/jsfunction.py 2008-07-12 03:32:31 UTC (rev 88274)
@@ -77,34 +77,43 @@
self._functions = {}
def add(self, jsFunction, namespace=''):
- ns = self._functions.setdefault(namespace, [])
- ns.append(jsFunction)
+ ns = self._functions.setdefault(namespace, {})
+ ns[jsFunction.name] = jsFunction
return jsFunction
def render(self):
result = ''
# Render non-namespaced functions
- for func in self._functions.get('', []):
+ for func in self._functions.get('', {}).values():
args = func.arguments
- result += 'function %s(%s) {\n' %(
+ result += 'var %s = function (%s) {\n' %(
func.name, ', '.join(args) )
code = func.render()
result += ' ' + code.replace('\n', '\n ') + '\n'
result += '}\n'
- # Render namespaced functions
+
+ # initialize namespaces
+ rendered = []
+ for nsIndex, ns in enumerate(sorted(self._functions.keys())):
+ if ns and nsIndex == 0:
+ result += 'var '
+ parts = ns.split('.')
+ for index in xrange(len(ns)):
+ path = '.'.join(parts[:index+1])
+ if path not in rendered:
+ result += '%s = {};\n' % path
+ rendered.append(path)
+
for ns, funcs in self._functions.items():
if ns == '':
continue
- result += 'var %s = {\n' %ns
- for func in funcs:
+ for func in funcs.values():
args = func.arguments
- result += ' %s: function(%s) {\n' %(
- func.name, ', '.join(args) )
+ result += '%s.%s = function(%s) {\n' %(
+ ns, func.name, ', '.join(args) )
code = func.render()
- result += ' ' + code.replace('\n', '\n ') + '\n'
- result += ' },\n'
- result = result[:-2] + '\n'
- result += '}\n'
+ result += ' ' + code.replace('\n', '\n ') + '\n'
+ result += '};\n'
return result
def __repr__(self):
Modified: z3c.formjs/branches/pcardune-client-notify-r87806/src/z3c/formjs/jsfunction.txt
===================================================================
--- z3c.formjs/branches/pcardune-client-notify-r87806/src/z3c/formjs/jsfunction.txt 2008-07-12 01:48:39 UTC (rev 88273)
+++ z3c.formjs/branches/pcardune-client-notify-r87806/src/z3c/formjs/jsfunction.txt 2008-07-12 03:32:31 UTC (rev 88274)
@@ -25,17 +25,74 @@
>>> View.jsFunctions
<JSFunctions
- {'hw': [<JSFunction showHelloWorldMessage>]}>
+ {'hw': {'showHelloWorldMessage': <JSFunction showHelloWorldMessage>}}>
The functions can be rendered directly:
>>> print View.jsFunctions.render()
- var hw = {
- showHelloWorldMessage: function() {
- alert('Hello World!');
- }
- }
+ var hw = {};
+ hw.showHelloWorldMessage = function() {
+ alert('Hello World!');
+ };
+We can also give a dotted path for the namespace, which will in turn
+be reflect in javascript:
+
+ >>> class View(object):
+ ...
+ ... @jsfunction.function('z3c.formjs.hw')
+ ... def showHelloWorldMessage(self):
+ ... return u"alert('Hello World!');"
+
+ >>> View.jsFunctions
+ <JSFunctions {'z3c.formjs.hw':
+ {'showHelloWorldMessage': <JSFunction showHelloWorldMessage>}}>
+
+ >>> print View.jsFunctions.render()
+ var z3c = {};
+ z3c.formjs = {};
+ z3c.formjs.hw = {};
+ z3c.formjs.hw.showHelloWorldMessage = function() {
+ alert('Hello World!');
+ };
+
+We can also do mixed level namespacing:
+
+ >>> class View(object):
+ ...
+ ... @jsfunction.function('z3c.formjs.hw')
+ ... def foo(self):
+ ... return u"alert('Foo');"
+ ...
+ ... @jsfunction.function('z3c.formjs')
+ ... def bar(self):
+ ... return u"alert('Bar');"
+ ...
+ ... @jsfunction.function('z3c.formjs.hw')
+ ... def baz(self):
+ ... return u"alert('Baz');"
+
+ >>> View.jsFunctions
+ <JSFunctions {'z3c.formjs.hw': {'foo': <JSFunction foo>,
+ 'baz': <JSFunction baz>},
+ 'z3c.formjs': {'bar': <JSFunction bar>}}>
+
+ >>> print View.jsFunctions.render()
+ var z3c = {};
+ z3c.formjs = {};
+ z3c.formjs.hw = {};
+ z3c.formjs.hw.foo = function() {
+ alert('Foo');
+ };
+ z3c.formjs.hw.baz = function() {
+ alert('Baz');
+ };
+ z3c.formjs.bar = function() {
+ alert('Bar');
+ };
+
+
+
Similarly to Javascript subscriptions, a JavaScript viewlet exists for
any view containing JavaScript functions that provides the following
output:
@@ -45,13 +102,23 @@
>>> viewlet.update()
>>> print viewlet.render()
<script type="text/javascript">
- var hw = {
- showHelloWorldMessage: function() {
- alert('Hello World!');
- }
- }
+ var z3c = {};
+ z3c.formjs = {};
+ z3c.formjs.hw = {};
+ z3c.formjs.hw.foo = function() {
+ alert('Foo');
+ };
+ z3c.formjs.hw.baz = function() {
+ alert('Baz');
+ };
+ z3c.formjs.bar = function() {
+ alert('Bar');
+ };
</script>
+!Note! a form must implement IHaveJSFunctions for the viewlet to be
+rendered.
+
Let's now have a closer look at the decorator. As mentioned before,
the namespace is optional. So what happens if the namespace is not
specified? Then the function should be declared normally:
@@ -63,7 +130,7 @@
... return u"alert('Hello World!');"
>>> print View.jsFunctions.render()
- function showHelloWorldMessage() {
+ var showHelloWorldMessage = function () {
alert('Hello World!');
}
@@ -84,17 +151,16 @@
... return u"alert('Hello World!');"
>>> print View.jsFunctions.render()
- function show1() {
+ var show1 = function () {
alert('Hello World!');
}
- var ns1 = {
- show1: function() {
- alert('Hello World!');
- },
- show2: function() {
- alert('Hello World!');
- }
- }
+ ns1 = {};
+ ns1.show1 = function() {
+ alert('Hello World!');
+ };
+ ns1.show2 = function() {
+ alert('Hello World!');
+ };
What about arguments? The arguments are directly extracted into the
code. Currently, keyword arguments, and variable positional and keyword
@@ -107,13 +173,12 @@
... return u"alert('Title' + title);"
>>> print View.jsFunctions.render()
- var ns = {
- show: function(title) {
- alert('Title' + title);
- }
- }
+ var ns = {};
+ ns.show = function(title) {
+ alert('Title' + title);
+ };
-And that is realy everything that there is to it.
+And that is really everything that there is to it.
Calling JSFunctions from Python
@@ -134,7 +199,7 @@
>>> View.show.call(True)
'ns.show(true);'
-Unsupported data types are just rendered as stritree/ngs.
+Unsupported data types are just rendered as strings.
>>> View.show.call(object())
"ns.show('<object object at ...>');"
More information about the Checkins
mailing list