toscawidgets / tw2.core

The core functionality for ToscaWidgets2, a web widget toolkit for Python to aid in the creation, packaging and distribution of common view elements normally used in the web.
tw2core.rtfd.org
Other
22 stars 15 forks source link

Improve resources injection management #74

Open amol- opened 11 years ago

amol- commented 11 years ago

Right now Tw2 suffers the same issues Tw1 had with resources injection. Server side resolution of dependencies has limits related to:

The only way I can think of to resolve such issue is to move resources resolution to client side, using javascript. Using something like require.js would permit to solve modules and their dependencies at client side keeping track of what is already available and injecting them even at runtime.

If a solution like require.js that involves defining modules is considered too invasive there are other solutions like head.js that rely on the script path for collision resolution and don't require any change to the scripts. This second solution would not solve issues with collisions and dependencies, but would stil improve ajax management of widgets and resources injection between multiple requests.

moschlar commented 11 years ago

Just a quick note on your first point, as I think it's not mentioned in the docs: You can already disable injection for specific resources like this: https://github.com/moschlar/SAUCE/blob/develop/sauce/lib/base.py#L42 It's "documented" in the source as a parameter https://github.com/toscawidgets/tw2.core/blob/develop/tw2/core/resources.py#L116 and in the WidgetBrowser, too: http://tw2-demos.threebean.org/module?module=tw2.core#JSLink (Parameters)

amol- commented 11 years ago

Yep, disabling resources injection is an option that can sometime solve dependencies collision like for different versions of jQuery by making possible to add them by hand to your master template. Still it doesn't solve at all the issue with ajax loading of widgets and resources tracking between different requests.

amol- commented 11 years ago

I made an experiment at using a javascript loader with module collision detection to load widgets resources. The result is really satisfying, a sample of widgets using that paradigm can be found at https://bitbucket.org/axant/axf

Resources loading is provided using the AxelWidgetMixin, which provides resources loading through the AXEL loader https://bitbucket.org/axant/axf/src/6e55b327694237250a85bc644ddabcb6ff04fb7a/axf/axel.py?at=default#cl-86

This seems to solve quite well the issue with resources collision, loading resources between requests and loading resources in a widget loaded through ajax.

moschlar commented 11 years ago

@ralphbean just mentioned http://www.fanstatic.org/en/latest/intro.html in the IRC.

ralphbean commented 11 years ago

Any thoughts on how to best integrate this with the core? I like the idea (we even implemented our own poor attempt at this years ago in Moksha). I'm just afraid of bloat in tw2.core at this point.

If it could be done in a small amount of code (which I think it can be -- we just modify our resource injector to inject AXEL statements instead of <script> tags) and if it can be turned off by default, saving legacy users from having to adapt to AXEL it could be a win.

Any reason to not go with require.js? I've not used it. Why axel?

amol- commented 11 years ago

@ralphbean requires.js is a good match, but has two side effect. First of all you need to edit your libraries to declare them all as modules, so you cannot take a library as is and use it. The other issue is that it doesn't support CSS loading.

AXEL was created to address both issues, but as I recognize that every user has his own favorite loader (and to make client side resources resolution work you need to use the loader for your own app) I think that the best way would be to provide an interface and let people provide the actual commands to load the resource. Maybe we can even provide two or three builtin examples for most common loaders.

ralphbean commented 11 years ago

:+1: - If anyone has the time/energy/desire to implement this, please do so and submit a pull request.

I'm going to spend my time cleaning and fixing any bugs introduced in #78 before getting into this one. Once that's done I'll pick it up (if no one else has yet).

amol- commented 10 years ago

I created an experimental tw2.asyncresources package that aims at solving this issue. It provides support for multiple JS loaders and permits to add more, I'm not sure that it is the best way to achieve this, but it works also for already existing widgets implemented by third parties.

https://github.com/amol-/tw2.asyncresources

It would be great if anyone can provide feedbacks on the proposed implementation, keep in mind that the provided Calendar example only works if tw2.forms@develop is used, as previous versions wrote the javascript directly inside the widget template instead of using add_call.