Groups keyboard shortcuts have been updated
Dismiss
See shortcuts

Trying to inject Dojo resources with ToscaWidgets

26 views
Skip to first unread message

ob1.data

unread,
Jul 8, 2009, 2:24:43 AM7/8/09
to TurboGears
Hello People,


I'm trying to inject JS resources (Dojo testUpdatingChart script) on
the way out from the ObjectDispatchController. I've subclassed
TableForm in a Widget to attach the javascript to. Ultimately, I want
to animate visualisations of generated data coming out of the DB. But
first I wanted to see some Dojo bells and whistles tacked on for wow
factor.


I get the following error:

"TypeError: pic() takes exactly 3 arguments (1 given)"

I guess this kind of error might be as common as ImportError, so may I
present some context. Working from "front to back"...


In /templates I have...
================
<h1>The Plot</h1>
<br/>
<div id="testUpdating" style="width: 300px; height: 300px;">
This text will be replaced by a chart, I hope...
</div>
<!-- Or maybe something like this'll work...-->
<div py:replace="tmpl_context.form(
child_args=dict( fig = dict(id=1,
title='Test Plot',
fig='wijdrgpi4thaerhgoq34itwie'
)
)">Input Form</div>
<!-- Or maybe I've lost The Plot -->


In /widgets I have...
===============
class TestPic(TableForm):
template = "pkg.templates.chart.html"
js = [JSLink(link=url('/public/js/chart.js'))]

class fields(WidgetsList):
id = TextField()
title = TextField()
fig = TextArea()

create_test_pic = TestPic("create_test_pic")


In my controller method in root.py I have ...
================================
@expose("pkg.templates.pic")
def pic(self, title, fig):
tmpl_context.form = create_test_pic
pic = DBSession.query(Pic).filter_by(title=title).one()
pic.fig = fig
return dict(wikipage=pic)


If you hadn't guessed my model has in it...
=================================
class Pic(DeclarativeBase):
__tablename__ = 'pic'

id = Column(Integer, primary_key=True)
title = Column(Text, unique=True)
fig = Column(Text) #gav Column(BLOB) #Ins img here eg. gif, jpg or
png

def __init__(self, title, fig):
self.title = title
self.fig = fig


So the constructor takes 3 args. OK, fine but how do they get passed
in from the front end? Presumably the template <div... fields are
sent in a Pylons/WebOb.request environ thingumajig and ultimately to
my controller. Or do I have to put it in the DB first? If I do, I
get the same kind of error on __init__. I seem to be going in circles
here. Is there some simple, key point about the way TG passes params
that I'm missing? The WebError Traceback seems unhelpful in this
instance but I'll attach it at the end in case it's useful.


URL: http://127.0.0.1:8080/pic
File 'c:\\tg-env\\lib\\site-packages\\weberror-0.10.1-py2.5.egg\
\weberror\\evalexception.py', line 431 in respond
app_iter = self.application(environ, detect_start_response)
File 'c:\\tg-env\\lib\\site-packages\\turbogears2-2.0-py2.5.egg\\tg\
\configuration.py', line 643 in wrapper
return app(environ, start_response)
File 'c:\\tg-env\\lib\\site-packages\\turbogears2-2.0-py2.5.egg\\tg\
\configuration.py', line 543 in remover
return app(environ, start_response)
File 'c:\\tg-env\\lib\\site-packages\\repoze.tm2-1.0a4-py2.5.egg\
\repoze\\tm\\__init__.py', line 19 in __call__
result = self.application(environ, save_status_and_headers)
File 'c:\\tg-env\\lib\\site-packages\\repoze.who-1.0.10-py2.5.egg\
\repoze\\who\\middleware.py', line 107 in __call__
app_iter = app(environ, wrapper.wrap_start_response)
File 'c:\\tg-env\\lib\\site-packages\\toscawidgets-0.9.4-py2.5.egg\\tw\
\core\\middleware.py', line 36 in __call__
return self.wsgi_app(environ, start_response)
File 'c:\\tg-env\\lib\\site-packages\\toscawidgets-0.9.4-py2.5.egg\\tw\
\core\\middleware.py', line 59 in wsgi_app
resp = req.get_response(self.application)
File 'build\\bdist.win32\\egg\\webob\\__init__.py', line 1325 in
get_response
File 'build\\bdist.win32\\egg\\webob\\__init__.py', line 1293 in
call_application
File 'c:\\tg-env\\lib\\site-packages\\toscawidgets-0.9.4-py2.5.egg\\tw\
\core\\resource_injector.py', line 67 in _injector
resp = req.get_response(app)
File 'build\\bdist.win32\\egg\\webob\\__init__.py', line 1325 in
get_response
File 'build\\bdist.win32\\egg\\webob\\__init__.py', line 1293 in
call_application
File 'c:\\tg-env\\lib\\site-packages\\beaker-1.3-py2.5.egg\\beaker\
\middleware.py', line 81 in __call__
return self.app(environ, start_response)
File 'c:\\tg-env\\lib\\site-packages\\beaker-1.3-py2.5.egg\\beaker\
\middleware.py', line 160 in __call__
return self.wrap_app(environ, session_start_response)
File 'c:\\tg-env\\lib\\site-packages\\routes-1.10.3-py2.5.egg\\routes\
\middleware.py', line 130 in __call__
response = self.app(environ, start_response)
File 'c:\\tg-env\\lib\\site-packages\\pylons-0.9.7-py2.5.egg\\pylons\
\wsgiapp.py', line 125 in __call__
response = self.dispatch(controller, environ, start_response)
File 'c:\\tg-env\\lib\\site-packages\\pylons-0.9.7-py2.5.egg\\pylons\
\wsgiapp.py', line 324 in dispatch
return controller(environ, start_response)
File 'C:\\tg-env\\Proj\\pkg\\lib\\base.py', line 32 in __call__
return TGController.__call__(self, environ, start_response)
File 'c:\\tg-env\\lib\\site-packages\\pylons-0.9.7-py2.5.egg\\pylons\
\controllers\\core.py', line 221 in __call__
response = self._dispatch_call()
File 'c:\\tg-env\\lib\\site-packages\\pylons-0.9.7-py2.5.egg\\pylons\
\controllers\\core.py', line 172 in _dispatch_call
response = self._inspect_call(func)
File 'c:\\tg-env\\lib\\site-packages\\pylons-0.9.7-py2.5.egg\\pylons\
\controllers\\core.py', line 107 in _inspect_call
result = self._perform_call(func, args)
File 'c:\\tg-env\\lib\\site-packages\\turbogears2-2.0-py2.5.egg\\tg\
\controllers.py', line 806 in _perform_call
self, controller, params, remainder=remainder)
File 'c:\\tg-env\\lib\\site-packages\\turbogears2-2.0-py2.5.egg\\tg\
\controllers.py', line 172 in _perform_call
output = controller(*remainder, **dict(params))
TypeError: pic() takes exactly 3 arguments (1 given)

Diez B. Roggisch

unread,
Jul 8, 2009, 3:06:21 AM7/8/09
to turbo...@googlegroups.com
ob1.data schrieb:

This has nothing todo with TG/Pylons/TW. It's solely about your model,
which you gave a constructor that's requiring a Pic-object being
constructed without always passing arguments - thus preventing a
Pic-object from being instantiated *if it already exists* and is only
supposed to be filled with DB-data.

Remove that constructor, and see how things work out.

Diez

Diez B. Roggisch

unread,
Jul 8, 2009, 3:10:01 AM7/8/09
to turbo...@googlegroups.com

> This has nothing todo with TG/Pylons/TW. It's solely about your model,
> which you gave a constructor that's requiring a Pic-object being
> constructed without always passing arguments - thus preventing a

Obviously, I meant "with" here instead of "without".


Diez

ob1.data

unread,
Jul 13, 2009, 1:19:20 AM7/13/09
to TurboGears
OK, so I numptied the constructor but ultimately I do want to fill
from the DB. Anyway, I've removed the __init__ and fixed some minor
HTML syntax and then the next error did look like it was about Tosca
Widgets.
"WidgetLocked:...It's unthread-safe to alter it's attributes after
initialisation."

I read somewhere that widgets are stateless and can be shared between
threads and I might well be wanting to do that. So I put the inject
call in the __init__ of my form. I'd had test_pic.title="The Plot" in
my controller, so clearly I'd lost the plot ;-)

Reading the address book example, I see that we no longer have to
return a dict but can just go 'pylons.c.something = something' and my
form will be available in my template as 'templ_context.something'.
Well and good, it seems that a consensus _may_ be emerging on 'passing
tw forms to templates' --see
http://groups.google.com/group/turbogears-trunk/browse_thread/thread/fdff4064fdf809b1

But where does this magical templ_context come from? I gather it's a
TG thing and is the same as pylons.c but what's the "one-- and
preferably only one --obvious way" to inject JS resources? Am I close
to having done it correctly yet?


In /templates I now have...
===========================
<h1>The Plot</h1>
<br/>
<div id="testUpdating" style="width: 300px; height: 300px;">
This text will be replaced by a chart, I hope...
</div>
<p>${templ_context.test_pic()}</p>


In /widgets I have...
=====================
class TestPic(TableForm):
template = "pkg.templates.pic.html"
#js = [JSLink(link=url('/public/js/chart.js'))]
#gav Hmmm, not so sure where to do this
class fields(WidgetsList):
id = TextField()
title = TextField()
fig = TextArea()

def __init__(self, template):
JSLink(link=url('/public/js/chart.js')).inject()
#gav But how do these two lines join up?
inject_resources(template)


In my controller method in root.py I have ...
=============================================
@expose("pkg.templates.pic")
def pic(self, **kwargs):
"""
This is where we attach the form to pylons.c.something and
whatever
you attach will be available in the template as
tmpl_context.something
"""
pylons.c.test_pic = test_pic
return dict(wikipage='pic')


But templ_context.test_pic is not available. :-(

"UndefinedError: "templ_context" not defined"
...
Module genshi.template.base:520 in _eval view
Module genshi.template.base:286 in _eval_expr view
Module genshi.template.eval:180 in evaluate view
Module ?:25 in <Expression u'templ_context.test_pic()'> view
<< --><!-- OK, addressbook way - I have a form called
test_pic...-->
<p>${templ_context.test_pic()}</p>
</body>
</html>
>> <p>${templ_context.test_pic()}</p>
Module genshi.template.eval:306 in lookup_name view
Module genshi.template.eval:405 in undefined view
UndefinedError: "templ_context" not defined

I've tried importing both templ_context and pylons.c in root.py and in
the widget module. Where should it be imported as what?

ob1.data

unread,
Jul 13, 2009, 2:33:22 AM7/13/09
to TurboGears
Ok, so now in answer to my own question... It's 'tmpl_context' not
'templ_context'
Duh.
But structurally, is this the right way to go about it. I'll let
y'all know if it works soon ( I hope ;)

Diez B. Roggisch

unread,
Jul 13, 2009, 5:12:50 AM7/13/09
to turbo...@googlegroups.com

This is not correct. The method to do such stuff is "update_params", precisely
because of the statelessness of widgets - the constructor is only called once
per process (or at least supposed to, and things might break otherwise), and
as the injection has to take place on each request, you need to use
update_params.

Diez

ob1.data

unread,
Jul 15, 2009, 2:44:05 AM7/15/09
to TurboGears
Ok, thanks Diez.

I renamed class TestPic(TableForm) to PicForm
and now it goes a little something like this:

===================================================
class PicForm(TableForm):
#js = [JSLink(link=url('/public/js/chart.js'))]
#gav Hmmm, not too sure where to do this.
params = ["template", "js"]
template = "pkg.templates.pic.html"
js = [JSLink(link=url('/public/js/chart.js'))]

class fields(WidgetsList):
id = TextField()
title = TextField()
fig = TextArea()

#After init, widget is shared so mods not thread-safe
#def __init__(self, template):
#JSLink(link=url('/public/js/chart.js')).inject()
#inject_resources(template) #The new way tw does it

#If you need to fetch data from external sources, do it here
#http://toscawidgets.org/documentation/ToscaWidgets/modules/
api.html
def update_params(self, d): #d is a dict with all args stuffed in
it.
super(PicForm, self).update_params(d) #Must do this
explicitly
d.js = JSLink(link=url('/public/js/chart.js')).inject()
d.template = "pkg.templates.pic.html"
#inject_resources(template) #gav But no params allowed
here!
#Now create an instance of this form
pic_form = PicForm("pic_form") #gav What is this parameter for?
===============================================================

I thought TG was supposed to make the front end dev easy. Ye olde PL/
SQL
with all HTML inside "..." would be easier to follow. Hopefully the
power
and beauty of the MVC structure of all this stuff is going to kick in
any day now. Am I the only newbie struggling with this kind of
stuff?
Maybe not, as I see there was some fairly extensive discussion on tg-
trunk
re. this update_params stuff.

Now I get another ImportError. Is it because I haven't injected
because
no params are allowed in update_params? If so, where/how can I put
the call
to inject_resources?

======================================================
Module ?:27 in <Expression u'tmpl_context.pic_form()'> view
<< pic_form with template = "pkg.templates.pic.html"
This seems to want a 'pic' module. I have one in /
model -->
<p>${tmpl_context.pic_form()}</p>
<!-- :-( ImportError on module pic ...?! -->

Module tw.core.base:535 in __call__ view
<< def __call__(self, value=None, **kw):
return self.display(value, **kw)

def get_default(self):
Module tw.core.base:532 in display view
<< kw = self.prepare_dict(value, kw)
self.register_resources()
return super(Widget, self).display(**kw)

def __call__(self, value=None, **kw):
Module tw.core.view:217 in display view
>> return tw.framework.engines.display(self, **kw)
Module tw.core.view:33 in _renderer view
>> template = self.load_template(template, origin)
Module tw.core.view:133 in load_template view
<< elif isinstance(template, basestring):
# Assume template path
output = self[engine_name].load_template(template)
else:
# Assume compiled template
Module genshi.template.plugin:95 in load_template view
Module pkg_resources:840 in resource_filename view
<< def resource_filename(self, package_or_requirement,
resource_name):
"""Return a true filesystem path for specified
resource"""
return get_provider
(package_or_requirement).get_resource_filename(
self, resource_name
)
Module pkg_resources:160 in get_provider view
>> __import__(moduleOrReq)
ImportError: No module named pic
======================================================

This import error seems to be caused by tmpl_context.pic_form auto-
generating some expectation for a module named pic although how and
where this occurs is not clear to me. I've still not developed an
intuition re. the stack trace and I'm stuck again. I already have a
pic.py module in my model folder and this defines a simple table [id,
title, img] which has otherwise worked fine before. Apologies in
advance if this post is a little long... :-{

Diez B. Roggisch

unread,
Jul 15, 2009, 3:09:58 AM7/15/09
to turbo...@googlegroups.com
ob1.data schrieb:


Well, I'm not sure, but you seem to take a rather strange approach of
working with TG (or TW, in this case). It appears as if you formed an
idea of how things should work by some snippets of documentation, and
then start building wildly on them.

Take the above: you somehow are aware that there is a possibility to
declare JS-dependencies, and that there is injection. And you mix that
together to something that is looking awful, and not working ...

This is not meant to be offensive - it's just something I've noted. And
so far, I haven't seen anybody else doing this. But then, I've certainly
not seen all newbie code.

So for the above:

- the classlevel-attribute "js" is not known to TW. It's called
"javascript"
- the template is not defined inside update_params.
- update_params is not a general replacement for the constructor -
it's just for the *dynamic* parts of a widget, and to prepare stuff for
the template namespace.
- templates are given without their extension.


So with what I can grasp from the above, I'd say what you want looks
like this:

class PicForm(TableForm):

engine_name = "genshi" # sometimes this is needed for me, maybe you
can get aloning without it


template = "pkg.templates.pic" # no need for html here, causes the
error you see

javascript = [JSLink(link=url('/public/js/chart.js'))]

class fields(WidgetsList):
id = TextField()
title = TextField()
fig = TextArea()

And yes, I think that's rather beautiful compared to PL/SQL mixed with HTML.


> Maybe not, as I see there was some fairly extensive discussion on tg-
> trunk
> re. this update_params stuff.
>
> Now I get another ImportError. Is it because I haven't injected
> because
> no params are allowed in update_params? If so, where/how can I put
> the call
> to inject_resources?


You usually don't do that. TW does that for you, **if** you declare them
properly.

Resource injection is only needed if you want something inside the page
that isn't a dependency of some other wiget that gets called it's
display()-method.

>
> ======================================================
> Module ?:27 in <Expression u'tmpl_context.pic_form()'> view
> << pic_form with template = "pkg.templates.pic.html"
> This seems to want a 'pic' module. I have one in /
> model -->
> <p>${tmpl_context.pic_form()}</p>
> <!-- :-( ImportError on module pic ...?! -->


You have a pic-subpackage by declaring a template
"pkg.templates.pic.html" because the html is superflous, and assumed to
be actually a file called "html.html" inside a module called pic.


HTH,

Diez

ob1.data

unread,
Jul 21, 2009, 1:34:48 AM7/21/09
to TurboGears
On Jul 15, 5:09 pm, "Diez B. Roggisch" <de...@web.de> wrote:
>Well, I'm not sure, but you seem to take a rather strange approach of
>working with TG (or TW, in this case). It appears as if you formed an
>idea of how things should work by some snippets of documentation, and
>then start building wildly on them.

Uhh, yeah. You got me. That's exactly what I've done. Is this so
wrong?
This is after all what abstraction is supposed to be about isn't it?

>Take the above: you somehow are aware that there is a possibility to
>declare JS-dependencies, and that there is injection. And you mix that
>together to something that is looking awful, and not working ...

Ok, so it's a bit mangled but the test first idea is agile/pythonic
is it not? To me the javascript side of things seemed the most
likely part to be messy and/or tricky.

>This is not meant to be offensive - it's just something I've noted.

That's Ok, none taken.

>And yes, I think that's rather beautiful compared to PL/SQL mixed
>with HTML.

For this I am deeply sorry Diez. It was a completely unjustifed
comment. Of course TG is more elegant than ASP, PHP etc. That's
why I'm here. I was just trying to provoke a response which I
suppose my request was indeed met with ;-)

>Resource injection is only needed if you want something inside
>the page that isn't a dependency of some other wiget that gets
>called it's display()-method.

Huh? Ok, I'm guessing I normally wouldn't need to do this.

=======================================================
What I am trying to do is very similar to this example:
http://www.turbogears.org/2.0/docs/main/ToscaWidgets/Cookbook/JSUnit.html

If I could test some Dojo inside a ToscaWidget and see it onscreen,
I'd be happy. I would then immediately be converted and become a
true believer in TG2.0 albeit still a newbie ;)

The above it _still_ not working for me.
Given up on "tg undefined" error
Trying another tack (based on JSUnit)
===========================================
#Can I subst my own JS that I want to test?
#from tw.extjs.test import ItemSelectorTest

#controllers"/root.py
#...
runner = Runner(testpage='/widgettest') #Why have '/' here?
testwidget = TestWidget() # (??='testUpdating')
# I want this to go looking for <div id="testUpdating"
#...
@expose('pkg.templates.widgettest')
def widgettest(self, **kw):
pylons.c.widgettest = testwidget
return dict()

#widgets/testWidget.py
#...
test_js = JSLink(modname=__name__, filename='public/js/chart.js')
class TestWidget(JSUnit):
def __init(self, *args, **kw):
super(TestWidget, self).__init__(*args, **kw)
#self.javascript.append(all);
self.javascript.append(test_js);
def update_params(self, d):
super(TestWidget, self).upadate_params(d)

#templates/widgettest.html
#...
${tmpl_context.testwidget(value=value)}
===========================================
! UndefinedError: "value" not defined
Where am I supposed to get this value from?

Can I just ditch the param? No.
! TypeError: 'str' object is not callable

Should it be testwidget(page='widgettest')? No.
! TypeError: 'str' object is not callable

Any chance I could get some more tips?
Apologies in advance for long posts.

Diez B. Roggisch

unread,
Jul 21, 2009, 3:17:32 AM7/21/09
to turbo...@googlegroups.com

> class TestWidget(JSUnit):
> def __init(self, *args, **kw):
> super(TestWidget, self).__init__(*args, **kw)
> #self.javascript.append(all);
> self.javascript.append(test_js);

The constructor is still odd. Whoever created that example didn't use tw
idiomatic. And it in general seems to be a rather bad example, see below.

Use

class TestWidget(JUnit):
javascript = [test_js]

instead, if you must use JUnit.


> def update_params(self, d):
> super(TestWidget, self).upadate_params(d)

Superflous, can go.


>
> #templates/widgettest.html
> #...
> ${tmpl_context.testwidget(value=value)}
> ===========================================
> ! UndefinedError: "value" not defined
> Where am I supposed to get this value from?


The value is supposed to be passed via returnvalue from the controller.
I don't know what it is supposed to be for the JSUnit-widget, because
the whole page doesn't care to mention this.

So, do yourself a favor, and ditch that whole thing. It is official
docs, so it's sad that you stumbled over it. But it unfortunatly sucks.


Instead, try this:


class MyWidet(tw.api.Widget):


javascript = [JSLink(__modname__, "myscript.js")] # make sure that
the js is really under __modname__/myscript.js


template = "<div>Hello world!</div>"
engine_name = "genshi"


my_widget = MyWidget("test")


@expose("the.template")
def action(self, ...):
c.my_widget = my_widget
return dict


And in "the.template.html", do


${c.my_widget.display()}


This should work, render a jslink into the source, and the "hello
world". From there on, try to expand, by e.g. using add_call inside
"update_params" to render a piece of js that invokes code from myscript.js.

Diez

ob1.data

unread,
Aug 4, 2009, 2:01:59 AM8/4/09
to TurboGears
<body>
${tmpl_context.testwidget.display()}
gives me UndefinedError: '' has no member named "display"


class TestWidget(Widget):
javascript = [ JSLink(link=url('/js/chart.js')) ]
template = "pkg.templates.widgettest"
engine_name = "genshi"

def __init__(self, name):
super(TestWidget, self).__init__(self)

def update_params(self, d):
super(TestWidget, self).upadate_params(d)
#I read that this must be done explicitly
self.add_call(javascript)
#Invoke javascript from myscript.js here?
#But won't this re-inject the JS for
#every rendering? I thought I read TG's
#smart enough to do it just once if I ...?

testwidget = TestWidget("TestTW")


@expose('pkg.templates.widgettest')
def widgettest(self, **kw):
pylons.c.widgettest = testwidget
return dict(form=testwidget) #, action=blah, value=blah)


<body>
<p py:content="form.display(submit_text='Yes')">
Widget Form</p>
gave me UndefinedError: "tg" not defined


The above code works in the sense that there
are no errors thrown. Clicking on the link
for my controller method 'widgettest' renders
the page with title and the text in the div
that is supposed to be replaced. But no JS
action occurs onscreen. :{


PS.
There is nothing in the rendered page's
source <head> section resulting.

Putting the code below into the template works
in so far as it appears if I View Page Source.
However, nothing happens, the JS does not
appear to run.
<script type="text/javascript" src="${tg.url('/js/chart.js')}"></
script>
</head>

Diez B. Roggisch

unread,
Aug 4, 2009, 3:01:04 AM8/4/09
to turbo...@googlegroups.com
ob1.data schrieb:

> <body>
> ${tmpl_context.testwidget.display()}
> gives me UndefinedError: '' has no member named "display"
>
>
> class TestWidget(Widget):
> javascript = [ JSLink(link=url('/js/chart.js')) ]


Don't do this, use the modname/filename variant. The reason is that
tg.url can't work on module-import-time, as it needs access to the
environment to really work, and that's only available in a request.

And even if tg.url would work, overall it's not working because
"/js/chart.js" is a relative path to something the system doesn't
recognize - unless you have a js-named controller on your root, and a
chart_js-action on that. Which you don't have I presume.

BTW, in my example I used the modname/filenam-variant. Why did you
change it? And did it work for you?

> template = "pkg.templates.widgettest"
> engine_name = "genshi"
>
> def __init__(self, name):
> super(TestWidget, self).__init__(self)
>
> def update_params(self, d):
> super(TestWidget, self).upadate_params(d)
> #I read that this must be done explicitly
> self.add_call(javascript)
> #Invoke javascript from myscript.js here?
> #But won't this re-inject the JS for
> #every rendering? I thought I read TG's
> #smart enough to do it just once if I ...?

Again this seems to be some exercise in genetic programming. Yes, TW
*is* smart enough to inject the resoure.

It is also smart enough to insert the add_call, but that's supposed to
contain a string that will be rendered like a JSSource-widget, and it
should contain some widget-specific code, such as

self.add_jall("""$(document).ready(function() {
$("#%s").do_something();
})""" % d.id)

And where does the "javascript" come from?

> testwidget = TestWidget("TestTW")
>
>
> @expose('pkg.templates.widgettest')
> def widgettest(self, **kw):
> pylons.c.widgettest = testwidget
> return dict(form=testwidget) #, action=blah, value=blah)


Both the widget and the controller share the same template? How's that
supposed to work? Either you are not rendering a full HTML-page, then
the resource injection of course can't work (it needs
html/head/body-tags), or you rendering those *twice*

>
> <body>
> <p py:content="form.display(submit_text='Yes')">
> Widget Form</p>
> gave me UndefinedError: "tg" not defined
>
>
> The above code works in the sense that there
> are no errors thrown. Clicking on the link
> for my controller method 'widgettest' renders
> the page with title and the text in the div
> that is supposed to be replaced. But no JS
> action occurs onscreen. :{

As you don't show us the template, I can't comment on that.


>
> PS.
> There is nothing in the rendered page's
> source <head> section resulting.
>
> Putting the code below into the template works
> in so far as it appears if I View Page Source.
> However, nothing happens, the JS does not
> appear to run.
> <script type="text/javascript" src="${tg.url('/js/chart.js')}"></
> script>

IT does not do something for the reasons explained above - /js/chart.js
isn't delivered by the system.

Diez

ob1.data

unread,
Aug 5, 2009, 3:04:11 AM8/5/09
to TurboGears
widgettest.html
===============
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:py="http://genshi.edgewall.org/"
xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="master.html" />
<head>
<meta content="text/html; charset=UTF-8" http-equiv="content-type"
py:replace="''"/>
<title>Widget Test</title>
</head>
<body>
<h1>Test A Dojo Chart Widget</h1>
<br/>
<!--
<p py:content="form.display(submit_text='Yes')">Widget Form</p>
UndefinedError: "tg" not defined
-->
<!--${tmpl_context.testwidget} here or inside div, no joy -->
<div id="testUpdating" style="width: 300px; height: 300px;">
This text will be replaced by a chart, I hope...
${tmpl_context.testwidget}
</div>
</body>
</html>
=======
If I try this (in <head> or in <body>):

<title>Widget Test</title>
<script type="text/javascript">
${tmpl_context.testwidget.javascript}
</script>
</head>
I get:

Module genshi.template.eval:321 in lookup_attr
__traceback_hide__ True
cls <class 'genshi.template.eval.StrictLookup'>
key 'javascript'
owner ''
view
UndefinedError: '' has no member named "javascript"

The same error occurs if I go ${tmpl_context.testwidget.display()}
Why is Genshi looking for member "javascript" in '' (ie. the empty
string?) Obviously '' has no members but surely my testwidget should?

>BTW, in my example I used the modname/filenam-variant. Why did you
>change it? And did it work for you?
Yes, as with ${tmpl_context.testwidget} or ${pylons.c.testwidget},
they seem to be interchangeable. Neither threw an error so I reverted
to the simpler looking relative path, presuming that the default
location of index.html is myproj/mypkg/public.
#javascript = [ JSLink(link=url('/js/chart.js')) ]
javascript = [ JSLink(modname=__name__, filename='public/js/
chart.js') ]

>Again this seems to be some exercise in genetic programming.
Mine is indeed a genetic algorithms project. How you've twigged to
this already, I'm not quite sure :-}

>self.add_jall("""$(document).ready(function() {
> $("#%s").do_something();
>
>})""" % d.id)
As one might guess from my moniker, I'm more comfortable with the
database side of things than the front end. In my case however the
Dojo chart.js script links methinks to <div id="testUpdating" and
the do_something() is a function in chart.js but what's $(document)?

>And where does the "javascript" come from?
I thought this was a class attribute of tw.api.widget
"javascript
A list of tw.api.JSLink or tw.api.JSSource instances that the
widget should register for injection in the page whenever it is
displayed"

>Both the widget and the controller share the same template?
Ah, ha! How else is it supposed to work? I thought using the same
name, ie. "pkg.templates.widgettest", was a necessary link between
two otherwise disparate pieces of code. There's no HTML associated
with my widget per se. The Dojo is all just functions. So do I need
a dummy form to set an action on where action="do_something()"?

> - unless you have a js-named controller on your root, and a
> chart_js-action on that
Or maybe, this is what I need to do. What's a js-named controller?
What's a chart_js-action?
Reply all
Reply to author
Forward
0 new messages