I'll take note of this for a tutorial/doc. I've seen some non-optimal
usage of this in the wild (no-one's fault but mine for lack of docs!) so I
guess it's about time to properly document it.
> I'll ask some help to someone more experienced.
> What I wanted to do was to automate dojo.require calls for instanced
> widgets.
This is doable with a pattern similar to how js calls are injected in the
page. Basically add_call [1] appends the JS string to a
RequestLocalDescriptor [2] (a descriptor that stores it's attribute in
request-local storage so its lieftime is bound to the duration of a
request) which is later picked up by a JSSource subclass [3] that renders
them.
I can take a chip at implementing it and help out with tw.dojo in general
since I'll most probably be using it for my SoC project :)
Alberto
[1] http://beta.toscawidgets.org/trac/tw/browser/tw/core/base.py#L453
[2] http://beta.toscawidgets.org/trac/tw/browser/tw/core/base.py#L177
[3] http://beta.toscawidgets.org/trac/tw/browser/tw/core/resources.py#L371
I was thinking of implementing something similar to the add_call()
mechanism to insert the dojo.require calls at <head> but your question
gave me a better idea. add_call could grow a "location" parameter to
specify where in the page the code should be injected. This will be more
useful since it won't be limited to tw.dojo. I've opened a ticket [1]
for it.
BTW, I just imported tw.dojo's SVN repository into toscawidgets.org and
opened up a Trac as we talked about. If you don't have an account
already please create one and send me your username so I can give you
"push" access to the repository and admin rights on the Trac. Is there
anyone else who needs "push" access to this repo?
Alberto
Michele, add_call() supports a location parameter since 0.9. To add a
dojo.require call at the head you can do:
def update_params(self, d):
super(...).update_params(d)
dojo_require = js_function('dojo.require')
require = ['dojo.foo', 'dojo.mojo']
for r in require:
self.add_call(dojo.require(r), 'head')
BTW. The class attribute "include_dynamic_js_calls" is no longer needed.
Alberto
If you're not careful then yes.
> If I place add_call() in __init__() does it work?
>
Yes, but you'll have the same duplicated dojo.require calls if the
widget is instantiated multiple times and each instance displayed.
I'll recommend for this case to jave just one DojoRequireCalls singleton
which has a "require" attribute with a RequestLocalDescriptor which
keeps attributes in request-local storage so they can be changed
dynamically. Something like this (simplified)
from tw.api import RequestLocalDescriptor, JSDynamicFunctionCalls
class DojoRequireCalls(JSDynamicFunctionCalls):
location = "head"
javascript = [dojo_base]
# This is an attribute which can hold requirements in a request-local
# set. anything added here will only be visible in the current request
_require = RequestLocalDescriptoror("dojo_require_calls", default=set)
def call_getter(self):
# return dojo.require calls. This is called by the superclass
return map(js_function('dojo.require'), self._require)
def require(self, requirement):
# Called by dojo widgets which want to inject a requirement
self._require.add(requirement)
# Inject ourselves into the page fisrt time we're called (we can
inject
# ourselves many times but only will get rendered once
self.inject()
# instatniate ourselves as a module-level singleton
dojo_require = DojoRequire("dojo_require")
Now, any widget that wants to append a 'dojo.require' call can do:
def update_params(self, d):
super(....)...
# note that you have to do this on every request, ie, in update_params
dojo_require.require("dojo.dixit.fooo")
If you take a look at the code in resources.py which handles add_call
injections you'll notice that this is more or less the same pattern...
> Thank you for the good job,
> Michele.
> P.S.: Yesterday I corrected a bug spotted by dakila and committed to
> both google code svn and toscawidgets mercurial.
> Is the idea to move the all tw.tools to mercurial at
> beta.toscawidgets.org? Should I continue to commit on both
> repositories?
>
No please, else we'll go nuts ;). Just tw.org.
Alberto