preferred strategy for creating own widget

4 views
Skip to first unread message

Chris Curvey

unread,
Nov 17, 2007, 10:30:29 PM11/17/07
to ToscaWidgets-discuss
I think I'm far enough along the learning curve here to start creating
my own widgets. I started by trying to take the code that I had
sprinkled throughout my pages and controllers and write my own, then I
got the bright idea to just subclass the DataGrid widget.
Unfortunately, I can't figure out how to get TG to understand that my
JS and CSS is not under /toscawidgets/resources.

I found this blog post with instructions on creating a new widget at
http://blog.wyattbaldwin.com/2007/3/22/creating-a-google-maps-toscawidget

Is the preferred way to create a widget to just use "paster" and
create the widget as a separate project from whatever you are working
on?

Alberto Valverde

unread,
Nov 18, 2007, 5:59:49 PM11/18/07
to toscawidge...@googlegroups.com
Chris Curvey wrote:
> I think I'm far enough along the learning curve here to start creating
> my own widgets. I started by trying to take the code that I had
> sprinkled throughout my pages and controllers and write my own, then I
> got the bright idea to just subclass the DataGrid widget.
> Unfortunately, I can't figure out how to get TG to understand that my
> JS and CSS is not under /toscawidgets/resources.

If you want TW to take care of serving your css and js you need to
create JSLink and CSSLink objects that you can add to the widget's "css"
and "javascript" lists.

Example:

Say your application is in a package called "myapp" and the js file
lives inside a directory called "static/javascript" and is called "myjs.js":

myjs = JSLink(
modname = "myapp",
filename = "static/javascript")

Then append this to your grid subclass:

class MyGrid(DataGrid):
javascript = [myjs]

If TW takes care of serving them then the /toscawidgets/resources url
prefix is mandatory (although configurable, there was a thread not long
ago where I explained how to) so TW's middleware knows that it should
intercept the requst.

If you don't want toscawidgets to handle the static resources and their
dependencies you can just include the <script> and <link> tags yourself
in every page that renders them.


>
> I found this blog post with instructions on creating a new widget at
> http://blog.wyattbaldwin.com/2007/3/22/creating-a-google-maps-toscawidget
>
> Is the preferred way to create a widget to just use "paster" and
> create the widget as a separate project from whatever you are working
> on?

Depends if you want to distibute or easily reuse the widget in other
applications. I personally always implement custom widgets inside the
application I'm working on and after they work, get polished and well
tested decouple them, if ever, for reuse.

Alberto

Chris Curvey

unread,
Nov 18, 2007, 10:26:08 PM11/18/07
to ToscaWidgets-discuss
> >http://blog.wyattbaldwin.com/2007/3/22/creating-a-google-maps-toscawi...
>
> > Is the preferred way to create a widget to just use "paster" and
> > create the widget as a separate project from whatever you are working
> > on?
>
> Depends if you want to distibute or easily reuse the widget in other
> applications. I personally always implement custom widgets inside the
> application I'm working on and after they work, get polished and well
> tested decouple them, if ever, for reuse.
>
> Alberto

Clearly there's something that I'm still not getting. Here's my
custom widget code:

from toscawidgets.api import CSSLink, JSLink
from toscawidgets.widgets.forms import DataGrid

js = JSLink(modname="turbotown", filename="static/javascript/
sortable_tables.js")
css = CSSLink(modname="turbotown", filename="static/css/
sortable_tables.css")

class PostList(DataGrid):
css = [css]
javascript = [js]
template = 'turbotown.templates.postGrid'
engine_name = 'genshi'
fields = []
params = ['fields']

this is now failing with a stack trace ending in:

File "/usr/lib/python2.5/site-packages/Genshi-0.4.4-py2.5.egg/genshi/
core.py", line 212, in _ensure
for event in stream:
File "/usr/lib/python2.5/site-packages/Genshi-0.4.4-py2.5.egg/genshi/
input.py", line 42, in ET
tag_name = QName(element.tag.lstrip('{'))
AttributeError: 'Stream' object has no attribute 'tag'

So I put in a "print" statement in genshi/input.py (just before the
line that causes the stack trace), and that tells me that "element"
is:

*** element = <script type="text/javascript" src="/toscawidgets/
resources/turbotown/static/javascript/sortable_tables.js"/>, type =
<class 'genshi.core.Stream'>

So I'm baffled. Is the problem that /toscawidgets/resources/..../
sortable_tables.js can't be found? (That would make sense -- that
file does not exist.)

what am I not doing to prevent /toscawidgets/resources from being
prepended to the front of my javascript location?

Alberto Valverde

unread,
Nov 19, 2007, 4:06:40 AM11/19/07
to toscawidge...@googlegroups.com

The genshi master template you're using is wrapping resources with
Genshi's ET when rendering them because it expects them to be TG
widgets' with kid templates. However, they're producing genshi Stream
objects since TW already does the conversion so the ET in the template
can't re-convert it. Remove the ET wrapping and that should do it.

This has already happened to enough people that a TW and TG short howto
at docs.turbogears.org is badly needed... my fault :( Though I wouldn't
mind help in this area... :)

FYI, this problem will go away in TG 1.1 since TG widgets will
automatically wrap their output if needed so they can be displayed in
Genshi with no ET-wrapping in the templates.

Alberto

Chris Curvey

unread,
Nov 19, 2007, 10:20:44 AM11/19/07
to ToscaWidgets-discuss
Got that working. But I'm still having trouble getting TW to serve my
JS and CSS files. In an earlier part of this thread, Alberto said...

[quote]
If TW takes care of serving them then the /toscawidgets/resources url
prefix is mandatory (although configurable, there was a thread not
long
ago where I explained how to) so TW's middleware knows that it should
intercept the requst.
[/quote]

I'm either having trouble understanding that paragraph (or
understanding it perfectly and not wanting to believe it). Does that
paragraph imply that

js = JSLink(modname="turbotown", filename="static/javascript/
sortable_tables.js")

class MyWidget(DataGrid):
javascript = [js]

will create a URL of /toscawidgets/resources/turbotown/static/
javascript/sortable_tables.js?

(or to ask the question another way, how can I get TW to generate a
url of /static/javascript/sortable_tables.js ?)
Reply all
Reply to author
Forward
0 new messages