Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve resources injection management #74

Open
amol- opened this issue Jan 17, 2013 · 8 comments
Open

Improve resources injection management #74

amol- opened this issue Jan 17, 2013 · 8 comments

Comments

@amol-
Copy link
Contributor

amol- commented Jan 17, 2013

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

  • Collision with resources injected manually by the user or by other frameworks (suppose your website uses jQuery and your widgets requires jQuery, you will end up with two jquery injected with different versions ad plugins enabled)
  • Ajax loading of widgets, suppose you load your widget through ajax your loaded partial will need to have a body and head section just to permit to tw2 to inject the resources there. You would end up with an head tag loaded inside your current body, relying on browser to resolve such issue
  • Resources injected multiple times if the widgets requires them between two different requests (again this happens when loading widgets inside an existing page) because tw doesn't know that the resources are already there due to a previous request.

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
Copy link
Member

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-
Copy link
Contributor Author

amol- commented Jan 17, 2013

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-
Copy link
Contributor Author

amol- commented Mar 12, 2013

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
Copy link
Member

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

@ralphbean
Copy link
Contributor

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-
Copy link
Contributor Author

amol- commented Mar 27, 2013

@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
Copy link
Contributor

👍 - 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-
Copy link
Contributor Author

amol- commented May 8, 2014

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants