I wrote this about a week ago, and emailed some people asking for feedback, overall it was good so I'm posting it to tg-trunk list to get more feedback. Maybe I can turn this into something useful in this weekend's sprint. A little note, I'm now like 50/50 on sharing the config file, maybe having widgets.py and widgets.js be valid python and javascript respectively is a better approach.
ok lets see where to start, I had an idea and I went ahead and coded it. And I'm writing here to see if it's worth working more on it. A couple of things to get you on the mood. 1- Data is code, code is data 2- I was watching this http://video.yahoo.com/watch/630959/2974197, not sure how that's related. 3- ever since embraced WSGI, every problem starts looking like a dict The basic idea is to have on file to rule them all. So you will have a widgets.py and a widgets.js didn't you said one file? yes it's the same file, it's just that python doesn't likes imports that don't end with .py and this will scare me away <script type="text/javascript" src="js1.py"> for example this: (you can ignore the last one that was just a test for empty values) my_widget = { 'js' : ['js1','js2'], 'css' : ['css1','css2'], 'jsource' : ['console.log("my_widget");'], 'body' : '<h1>Hello</h1>', } my_widget2 = { 'js' : ['js1','js4'], 'css' : ['css4','css2'], 'body' : '<h1>Hello</h1>', } my_widget3 = { } The first thing to note is that the above file is valid python,valid javascript, valid json and even valid yaml (some people say) The second is that js and css are supposed to be paths, while jsource and body "code". Third, the first 3 are supposed to be added to the <head> while the last one should also be a list, actually a dict, and should be somewhat analogous to tmpl_context, in fact in a real implementation this should be added as pylons.c.something and is what the template author will use to display the widget in his layout. At this moment it has two implementations, server and client side. The server is the sane implementation, it basically parses widgets.py and passes the results to string.Template which splits out main-py.html which is browser rendable. The client is more a "let me see if this is possible" than a real proposal it starts with main-js.html which includes a single main.js, which is basically an implementation of dynamic JS includes (that's scary :p) Now keep in mind I kind of hate JS and it hates me back, or in other words I suck at JS and it sucks right back at me. Oh and this only works on FF but it's pure JS. It has several bugs like adding the same file twice and doing the wrong thing with body but as I said this is a toy. Alberto pointed out dojo does something like this and we could look into it. So as you can see both api implementations are the less common denominator, and they have around 100LOC each, minus comments, and whitespace this is really just 3-4 functions. Ideally the python part should be ported to a mako function as well as a genshi function and for the JS we should have jquery,dojo,etc. and then have something like wsgiref to make sure they are all api compatible. What's the big win? let me start with the WHY? First of all Toscawidget is great, I really enjoy it but I don't think it's the hammer for all problems. it excels at the forms part, tw.forms is total awesomeness, specially with changes of requirements (by clients), not to mention how great rum is. but it fails at the "JS wrappers" part. it fails because of several things 1- having to wrap things, I really don't see the point of getting a python value into a class, then into an instance, then to the template, then to JS code, so the client can pick it from the page and send it again into JS 2- it tries to hide you the JS, which is a mistake for some cases, no offense but what's the point of tw.jquery it's even more code to do it in python than just go to /templates and write it. 3- if you are going to use a wrapper, then lets do it in the same language js_function WTF???, which is exactly what all JS libraries are, wrappers! 4- a ton of files for a simple function, this morning I wrote (or tried to write) a toscawidget for wymeditor (code on hg, release ann on tw list) only the basic widget is 40 lines of code, yes most of that are comments but the original is 5 lines, plus 2-3 for imports[1] is much less and more readable, more importantly adding a configuration is just one loc[2] while in TW that will be one for the default, another for the updated value, a check in the init, and a doc .... as for the files I know most of them are bolierplate to make everything integrate nicely but to a newbie that's scary, and to a maintainer is boring. 5- no one understands the one global instances and render time scopes, it's a great feature and clever design. But people just don't get it and try to set values to it on the controller and just call it as ${widget()} on the template. I have answered that question a lot on IRC and the mailing list 6- the bungle is bad. The most recent example of this is the drop of the JS wrappers from webhelpers, everytime a new version of the JS library is release someone has to go over the python version and add/remove the values mentioned in point 4, this is busy work and totally annoying which results in what webhelpers did, also if you take a look at [3] you will see most of the wrappers are either outdated or have had little activity since the first time they where wrote. 7- TW are hard to debug, there is just way too much magic going on, so reading someone elses code is not nice, this contributes to 6. and I'll stop now because I'm starting to talk about things that aren't really solved by this tool. Bottom line TW is great for forms and static traditional html stuff. but it breaks with the "new wave" of single page apps and intensive xhr usage, in which case some of us, at least I do just ditch it all together and go back to the plain old 3 public/javascript, public/css and /templates. so back to the solution. - we'll have one file or many that will define widgets. in a namespaced way, (the current implementation uses both python and javascript global space, for simplicity rather than design), I'm inclined to use JS "namespaces" which in python will be a dict with all the widgets with proper keys, again think WSGI, this will be lazy loader and cached for performance. And will be the source of the tmpl_context objects I talked about before, so in essence it will be key='myproject.widgets.something' or 'jquery.something' value=python dict, usable by the templating engine. - we'll reuse or reimplement the JS/CSS injection from toscawidgets, that's a great tool. - all paths will be from the public directory unless they are absolute, of course this will be configured variable for usage outside tg2 - no packages, no setuptools, no .js inside egg, a widget will be simply one dict, - we should add a dependencies parameter so for example if widget 'b' uses widget 'a' then it will be something like b = {'body' = '${a}', 'depends' = ['a']} and of course we'll need to code all the possible edge cases, if done right this could be delegate to __import__, no clue on the JS implementation. - the preferred html generator will be webhelpers HTML package from 0.6, it's just too easy and very pythonic, much better than any templating language IMO, and keep in mind the widget is something build by programmers, there is a bottom comment on this. - (this one is still in flux) the "body" of a widget could be a string, a list, a generator, a node or a dict. the first 3 will be interpreted as raw output and will be wrapped in webhelper's literal() and send as one big string to the template engine. a node will be in case of xml templates to be inserted in the tree, and if it's a dict it will behave like TurboGears, but in a different namespace to prevent overwriting the users variables. perhaps pylons.c.newwidgets :) - As I said above widgets.py/.js is valid python/js/json/yaml, ideally this should stay that way if things get complicated then I think we should keep it as json if it becomes a config file on it's own then yaml. or have a format key in the dict. - the system will only load the widgets the user wants, that is no auto discovery or other magic, you should explicitly ask for all widgets you want in a call to widgets_to_page (horrible name, must be changed), which should be called in tg2 at the root of root.py and it should be read only. - Like widgets today, they can accept parameters but have no defaults. if you want defaults you should overwrite/extend it. - all references to external files should depend on their type. if they are to be included in urls (js/css files) path notation, if they are REAL python files should use dot notation. - defining an external template file should be a special case, in which case I vote for path notation starting from /templates (again configurable for non-tg2 environments) - if done right the same widget should be able to be rendered either client or server side, or have both a client and serverside component, which at the moment I don't see the usecase. - I haven't though of overwriting/extending a widget. maybe you could clone the dict and overwrite the proper values or just copy it over to your project and modify it. - neither of having more than one instance in a page and ids crashing. I think that's it, attached is a compresses mercurial repo.Which isn't available anywhere else for now. Sorry for the long email, let me know what you think. Regarding webhelpers.html, I'm not sure how well it does on performance but the api is really nice, and it is a lot better than "hand coded" html in templates stored somewhere, deep inside site-packages. it lack a "pretty print" option so it's generated code is rather ugly, Mike Orr suggested to me a while back that using something like beautiful soup on the output will be the best, which is fine for final pages but I think a solution could be contributed, even if it's only turned on for debugging. we should work on it. [1] http://trac.wymeditor.org/trac/wiki/0.5/Integration [2] http://trac.wymeditor.org/trac/wiki/0.5/Customization [3] http://toscawidgets.org/hg --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "TurboGears Trunk" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/turbogears-trunk?hl=en -~----------~----~----~----~------~----~------~--~---
widgets3.tar.gz
Description: GNU Zip compressed data
