Browse Source

[ADD] web_context_tunnel module, the best tunnel since SSH tunnels?

pull/2/head
Raphaël Valyi 11 years ago
parent
commit
1a7c75b1cf
  1. 0
      web_context_tunnel/__init__.py
  2. 40
      web_context_tunnel/__openerp__.py
  3. 27
      web_context_tunnel/static/src/js/context_tunnel.js

0
web_context_tunnel/__init__.py

40
web_context_tunnel/__openerp__.py

@ -0,0 +1,40 @@
{
'name': 'Web Context Tunnel',
'category': 'Hidden',
'author': 'Akretion',
'license': 'AGPL-3',
'description':"""
Web Context Tunnel.
===================
The problem with OpenERP on_changes
-----------------------------------
OpenERP uses to pass on_change Ajax events arguments using positional arguments. This is annoying as modules often need to pass extra arguments that are not present in the base on_change signatures. As soon as two modules try to alter this signature to add their extra arguments, they are incompatible between them unless some extra glue module make them compatible again by taking all extra arguments into account. But this leads to a combinatorial explosion to make modules compatibles.
The solution
------------
This module provides a simple work around that will work in most of the cases. In fact it works if the base on_change is designed to pass the context argument. Else it won't work and you should go the old way. But in any case it's a bad practice if an on_change doesn't pass the context argument and you can certainly rant about these bad on_changes to the the context added in the arguments.
So for an on_change passing the context, how does this module works?
Well OpenERP already has an elegant solution for an extension module to alter an XML attributes: put an extension poi
nt in the view using position="attributes" and then redefine the attribute. That is already used at several places to replace the "context" attribute that the client will send to the server.
The idea here is to wrap the extra arguments needed by your on_change inside that context dictionary just as it were a regular Python kwargs. In the on_change override chain, the context is then propagated naturally, no matter of the module order and without any need to hack any on_change signature.
The issue with just position="attributes" and redefining the context, is that again, if two independent modules do it, they are incompatible unless a third module accounts for both of them.
But with this module, an extension point can now use position="attributes" and instead of redefining the "context" attribute, you will now just define a new "context_foo" attribute. This module modifies the web client in such a way that before sending the Ajax on_change event request to the server, all the node attributes starting with "context" are merged into a single context dictionnary, keeping the keys and values from all extensions. In the rare case a module really wants to override the value in context, then it needs to still override the original context attribute (or the other original attribute).
Ad of course, if you should call your on_change by API or webservice instead of using the web client, simply ensure y
u are wrapping the required extra arguments in the context dictionary.
""",
'version': '2.0',
'depends': ['web'],
'js': ['static/src/js/context_tunnel.js'],
'css': [],
'auto_install': False,
'web_preload': False,
}

27
web_context_tunnel/static/src/js/context_tunnel.js

@ -0,0 +1,27 @@
openerp.web_context_tunnel = function(instance) {
instance.web.form.FormWidget.prototype.build_context = function() {
var v_context = false;
var fields_values = false;
console.log(this.node.attrs);
// instead of using just the attr context, we merge any attr starting with context
for (var key in this.node.attrs) {
if (key.substring(0, 7) === "context") {
if (!v_context) {
fields_values = this.field_manager.build_eval_context();
v_context = new instance.web.CompoundContext(this.node.attrs[key]).set_eval_context(fields_values);
} else {
v_context = new instance.web.CompoundContext(this.node.attrs[key], v_context).set_eval_context(fields_values);
}
}
}
if (!v_context) {
v_context = (this.field || {}).context || {};
}
return v_context;
};
};
// vim:et fdc=0 fdl=0:
Loading…
Cancel
Save