← Back to team overview

openerp-dev-web team mailing list archive

lp:~openerp-dev/openobject-client-web/trunk-proto61-great-addons-cleanup-of-2011-xmo into lp:~openerp-dev/openobject-client-web/trunk-proto61

 

Xavier (Open ERP) has proposed merging lp:~openerp-dev/openobject-client-web/trunk-proto61-great-addons-cleanup-of-2011-xmo into lp:~openerp-dev/openobject-client-web/trunk-proto61.

Requested reviews:
  OpenERP SA's Web Client R&D (openerp-dev-web)

For more details, see:
https://code.launchpad.net/~openerp-dev/openobject-client-web/trunk-proto61-great-addons-cleanup-of-2011-xmo/+merge/57680

Fixed loading of addons, including basic loading of CSS files whern loading addons

Also fixed content type of AjaxIM poll method.
-- 
https://code.launchpad.net/~openerp-dev/openobject-client-web/trunk-proto61-great-addons-cleanup-of-2011-xmo/+merge/57680
Your team OpenERP R&D Team is subscribed to branch lp:~openerp-dev/openobject-client-web/trunk-proto61.
=== modified file 'addons/base/controllers/main.py'
--- addons/base/controllers/main.py	2011-04-12 13:21:20 +0000
+++ addons/base/controllers/main.py	2011-04-14 13:43:22 +0000
@@ -58,13 +58,17 @@
 class Session(openerpweb.Controller):
     _cp_path = "/base/session"
 
-    def manifest_glob(self, modlist, key):
+    def manifest_glob(self, addons, key):
         files = []
-        for i in modlist:
-            globlist = openerpweb.addons_manifest.get(i, {}).get(key, [])
-            for j in globlist:
-                for k in glob.glob(os.path.join(openerpweb.path_addons, i, j)):
-                    files.append(k[len(openerpweb.path_addons):])
+        for addon in addons:
+            globlist = openerpweb.addons_manifest.get(addon, {}).get(key, [])
+
+            files.extend([
+                resource_path[len(openerpweb.path_addons):]
+                for pattern in globlist
+                for resource_path in glob.glob(os.path.join(
+                    openerpweb.path_addons, addon, pattern))
+            ])
         return files
 
     def concat_files(self, file_list):
@@ -96,14 +100,16 @@
 
     @openerpweb.jsonrequest
     def modules(self, req):
-        return {"modules": ["base", "base_hello", "base_calendar", "base_gantt"]}
+        return {"modules": [name
+            for name, manifest in openerpweb.addons_manifest.iteritems()
+            if manifest.get('active', True)]}
 
     @openerpweb.jsonrequest
-    def csslist(self, req, mods='base,base_hello'):
+    def csslist(self, req, mods='base'):
         return {'files': self.manifest_glob(mods.split(','), 'css')}
 
     @openerpweb.jsonrequest
-    def jslist(self, req, mods='base,base_hello'):
+    def jslist(self, req, mods='base'):
         return {'files': self.manifest_glob(mods.split(','), 'js')}
 
     def css(self, req, mods='base,base_hello'):

=== modified file 'addons/base/static/src/base.html'
--- addons/base/static/src/base.html	2011-04-13 05:26:33 +0000
+++ addons/base/static/src/base.html	2011-04-14 13:43:22 +0000
@@ -23,33 +23,11 @@
     <script type="text/javascript" src="/base/static/src/js/list.js"></script>
     <script type="text/javascript" src="/base/static/src/js/search.js"></script>
     <script type="text/javascript" src="/base/static/src/js/views.js"></script>
-	
-	<script type="text/javascript" src="/base_diagram/static/src/js/diagram.js"></script>
-	<script type="text/javascript" src="/base_diagram/static/lib/js/raphael-min.js"></script>
-	<script type="text/javascript" src="/base_diagram/static/lib/js/dracula_graffle.js"></script>
-	<script type="text/javascript" src="/base_diagram/static/lib/js/dracula_graph.js"></script>
-	
-
-    <script type="text/javascript" src="/base_gantt/static/lib/dhtmlxGantt/codebase/dhtmlxcommon.js"></script>
-
-    <script type="text/javascript" src="/base_gantt/static/lib/dhtmlxGantt/codebase/dhtmlxgantt.js"></script>
-    <script type="text/javascript" src="/base_gantt/static/src/gantt.js"></script>
-
-    <script type="text/javascript" src="/base_calendar/static/lib/dhtmlxScheduler/codebase/dhtmlxscheduler.js"></script>
-    <script type="text/javascript" src="/base_calendar/static/src/js/calendar.js"></script>
-
-	<script type="text/javascript" src="/web_chat/static/lib/AjaxIM/js/jquery.jsonp-1.1.0.js"></script>
-	<script type="text/javascript" src="/web_chat/static/lib/AjaxIM/js/jquery.jstore-all-min.js"></script>
-	<script type="text/javascript" src="/web_chat/static/lib/AjaxIM/js/jquery.md5.js"></script>
-	<script type="text/javascript" src="/web_chat/static/lib/AjaxIM/js/im.js"></script>
 
     <link rel="stylesheet" type="text/css" media="screen" href="/base/static/lib/jquery.ui/css/smoothness/jquery-ui-1.8.9.custom.css" />
     <link rel="stylesheet" type="text/css" media="screen" href="/base/static/lib/jquery.ui.notify/css/ui.notify.css" />
     <link rel="stylesheet" type="text/css" href="/base/static/lib/jquery.superfish/css/superfish.css" media="screen">
 
-    <link rel="stylesheet" type="text/css" media="screen" href="/base_gantt/static/lib/dhtmlxGantt/codebase/dhtmlxgantt.css" />
-    <link rel="stylesheet" type="text/css" media="screen" href="/base_calendar/static/lib/dhtmlxScheduler/codebase/dhtmlxscheduler.css">
-
     <link rel="stylesheet" href="/base/static/src/css/base.css" type="text/css"/>
 
     <script type="text/javascript">
@@ -58,18 +36,6 @@
             oe.base.webclient("oe");
         });
     </script>
-
-    <script>
-    var AjaxIM, AjaxIMLoadedFunction;
-    $(function() {
-       AjaxIM.init({
-           pollServer: '/web_chat/pollserver',
-           theme: '/web_chat/static/lib/AjaxIM/themes/default',
-           flashStorage: '/web_chat/static/lib/AjaxIM/js/jStore.Flash.html'
-       });
-       AjaxIM.client.login();
-    });
-    </script>
 </head>
 <body id="oe" class="openerp">
 </body>

=== modified file 'addons/base/static/src/js/base.js'
--- addons/base/static/src/js/base.js	2011-04-13 02:01:50 +0000
+++ addons/base/static/src/js/base.js	2011-04-14 13:43:22 +0000
@@ -126,9 +126,6 @@
     openerp.base.search(instance);
     openerp.base.list(instance);
     openerp.base.form(instance);
-    openerp.base.calendar(instance);
-    openerp.base.gantt(instance);
-	openerp.base.diagram(instance);
 };
 
 // vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax:

=== modified file 'addons/base/static/src/js/chrome.js'
--- addons/base/static/src/js/chrome.js	2011-04-12 14:07:01 +0000
+++ addons/base/static/src/js/chrome.js	2011-04-14 13:43:22 +0000
@@ -450,10 +450,21 @@
         var self = this;
         this.rpc('/base/session/modules', {}, function(result) {
             self.module_list = result['modules'];
-            self.rpc('/base/session/jslist', {"mods": self.module_list.join(',')}, self.debug ? self.do_load_modules_debug : self.do_load_modules_prod);
+            var modules = self.module_list.join(',');
+            self.rpc('/base/session/csslist', {mods: modules}, self.do_load_css);
+            self.rpc('/base/session/jslist', {"mods": modules}, self.debug ? self.do_load_modules_debug : self.do_load_modules_prod);
             openerp._modules_loaded = true;
         });
     },
+    do_load_css: function (result) {
+        _.each(result.files, function (file) {
+            $('head').append($('<link>', {
+                'href': file,
+                'rel': 'stylesheet',
+                'type': 'text/css'
+            }));
+        });
+    },
     do_load_modules_debug: function(result) {
         $LAB.setOptions({AlwaysPreserveOrder: true})
             .script(result.files)
@@ -466,16 +477,15 @@
         // use $.getScript(‘your_3rd_party-script.js’); ? i want to keep lineno !
     },
     on_modules_loaded: function() {
-        var self = this;
-        for(var j=0; j<self.module_list.length; j++) {
-            var mod = self.module_list[j];
-            if(self.module_loaded[mod])
+        for(var j=0; j<this.module_list.length; j++) {
+            var mod = this.module_list[j];
+            if(this.module_loaded[mod])
                 continue;
             openerp[mod] = {};
             // init module mod
             if(openerp._openerp[mod] != undefined) {
                 openerp._openerp[mod](openerp);
-                self.module_loaded[mod] = true;
+                this.module_loaded[mod] = true;
             }
         }
     }
@@ -491,7 +501,7 @@
     controller_manifest: {
         register: null,
         template: "",
-        element_post_prefix: false,
+        element_post_prefix: false
     },
     /**
      * Controller registry, 
@@ -702,7 +712,7 @@
 
 openerp.base.Loading =  openerp.base.Controller.extend({
     controller_manifest: {
-        register: ["Loading"],
+        register: ["Loading"]
     },
     init: function(session, element_id) {
         this._super(session, element_id);

=== modified file 'addons/base/static/src/xml/base.xml'
--- addons/base/static/src/xml/base.xml	2011-04-13 02:01:50 +0000
+++ addons/base/static/src/xml/base.xml	2011-04-14 13:43:22 +0000
@@ -231,10 +231,6 @@
         <button type="button" name="delete">â™»</button>
     </td>
 </tr>
-<t t-name="DiagramView">
-	<h2 class="oe_view_title"><t t-esc="fields_view.arch.attrs.string"/></h2>
-	<div id="dia-canvas" style="overflow: auto;"></div>
-</t>
 <t t-name="FormView">
     <h2 class="oe_view_title"><t t-esc="view.fields_view.arch.attrs.string"/></h2>
     <div class="oe_form_header" t-att-id="view.element_id + '_header'">
@@ -574,48 +570,4 @@
         </p>
     </div>
 </t>
-<t t-name="CalendarView">
-	<h3 class="title"><t t-esc="view.fields_view.arch.attrs.string"/></h3>
-	<table class="calendar-view" width="100%" height="100%" cellspacing="0" cellpadding="0">
-		<tr>
-			<td>
-				<div style="height: 1000px;width: 100%;">
-					<div id="calendar-sidebar">
-					</div>
-				</div>
-			</td>
-			<td style="width:85%;" align="left">
-				<div id="openerp_scheduler" class="dhx_cal_container" style="height: 1000px;width: 100%;">
-					<div class="dhx_cal_navline">
-						<div class="dhx_cal_prev_button"></div>
-						<div class="dhx_cal_next_button"></div>
-						<div class="dhx_cal_today_button"></div>
-						<div class="dhx_cal_date"></div>
-						<div class="dhx_minical_icon" id="dhx_minical_icon"></div>
-						<div class="dhx_cal_tab" name="day_tab" style="right:204px;"></div>
-						<div class="dhx_cal_tab" name="week_tab" style="right:140px;"></div>
-						<div class="dhx_cal_tab" name="month_tab" style="right:76px;"></div>
-					</div>
-					<div class="dhx_cal_header">
-					</div>
-					<div class="dhx_cal_data">
-					</div>		
-				</div>
-			</td>
-		</tr>
-	</table>
-</t>
-<t t-name="GanttView">
-	<h3 class="title"><t t-esc="view.fields_view.arch.attrs.string"/></h3>
-	<table class="gantt-view" width="100%" height="100%" cellspacing="0" cellpadding="0">
-		<tr>
-			<td style="width:85%">
-				<div style="width:100%;height:300px;position:relative" id="GanttDiv"></div>
-			</td>
-			<td valign = "top">
-				<div id="gantt-sidebar"></div>
-			</td>
-		</tr>
-	</table>
-</t>
 </templates>

=== modified file 'addons/base_calendar/__openerp__.py'
--- addons/base_calendar/__openerp__.py	2011-03-17 14:53:21 +0000
+++ addons/base_calendar/__openerp__.py	2011-04-14 13:43:22 +0000
@@ -1,7 +1,11 @@
 {
-    "name": "Hello",
+    "name": "Base calendar",
     "version": "2.0",
-    "depends": [],
-    "js": ["static/*/js/*.js"],
-    "css": [],
+    "depends": ['base'],
+    "js": [
+        'static/lib/dhtmlxScheduler/codebase/dhtmlxscheduler.js',
+        'static/src/js/calendar.js'
+    ],
+    "css": ['static/lib/dhtmlxScheduler/codebase/dhtmlxscheduler.css'],
+    'active': True
 }

=== modified file 'addons/base_calendar/static/src/js/calendar.js'
--- addons/base_calendar/static/src/js/calendar.js	2011-04-07 16:41:06 +0000
+++ addons/base_calendar/static/src/js/calendar.js	2011-04-14 13:43:22 +0000
@@ -2,10 +2,10 @@
  * OpenERP base_calendar
  *---------------------------------------------------------*/
 
-openerp.base.calendar = function(openerp) {
-	
-openerp.base.views.add('calendar', 'openerp.base.CalendarView');
-openerp.base.CalendarView = openerp.base.Controller.extend({
+openerp.base_calendar = function(openerp) {
+QWeb.add_template('/base_calendar/static/src/xml/base_calendar.xml');
+openerp.base.views.add('calendar', 'openerp.base_calendar.CalendarView');
+openerp.base_calendar.CalendarView = openerp.base.Controller.extend({
 // Dhtmlx scheduler ?
 	init: function(view_manager, session, element_id, dataset, view_id){
 		this._super(session, element_id);
@@ -201,7 +201,7 @@
 	
     do_hide: function () {
         this.$element.hide();
-    },
+    }
 });
 
 //openerp.base.Action = openerp.base.Action.extend({

=== added directory 'addons/base_calendar/static/src/xml'
=== added file 'addons/base_calendar/static/src/xml/base_calendar.xml'
--- addons/base_calendar/static/src/xml/base_calendar.xml	1970-01-01 00:00:00 +0000
+++ addons/base_calendar/static/src/xml/base_calendar.xml	2011-04-14 13:43:22 +0000
@@ -0,0 +1,33 @@
+<template>
+  <t t-name="CalendarView">
+    <h3 class="title"><t t-esc="view.fields_view.arch.attrs.string"/></h3>
+    <table class="calendar-view" width="100%" height="100%" cellspacing="0" cellpadding="0">
+      <tr>
+        <td>
+          <div style="height: 1000px;width: 100%;">
+            <div id="calendar-sidebar">
+            </div>
+          </div>
+        </td>
+        <td style="width:85%;" align="left">
+          <div id="openerp_scheduler" class="dhx_cal_container" style="height: 1000px;width: 100%;">
+            <div class="dhx_cal_navline">
+              <div class="dhx_cal_prev_button"/>
+              <div class="dhx_cal_next_button"/>
+              <div class="dhx_cal_today_button"/>
+              <div class="dhx_cal_date"/>
+              <div class="dhx_minical_icon" id="dhx_minical_icon"/>
+              <div class="dhx_cal_tab" name="day_tab" style="right:204px;"/>
+              <div class="dhx_cal_tab" name="week_tab" style="right:140px;"/>
+              <div class="dhx_cal_tab" name="month_tab" style="right:76px;"/>
+            </div>
+            <div class="dhx_cal_header">
+            </div>
+            <div class="dhx_cal_data">
+            </div>
+          </div>
+        </td>
+      </tr>
+    </table>
+  </t>
+</template>

=== modified file 'addons/base_diagram/__openerp__.py'
--- addons/base_diagram/__openerp__.py	2011-04-07 11:18:18 +0000
+++ addons/base_diagram/__openerp__.py	2011-04-14 13:43:22 +0000
@@ -2,5 +2,5 @@
     "name" : "OpenERP Web base Diagram",
     "version" : "2.0",
     "depends" : [],
-    'active': True,
+    'active': False,
 }

=== modified file 'addons/base_gantt/__openerp__.py'
--- addons/base_gantt/__openerp__.py	2011-04-07 12:13:31 +0000
+++ addons/base_gantt/__openerp__.py	2011-04-14 13:43:22 +0000
@@ -1,7 +1,12 @@
 {
     "name": "Base Gantt",
     "version": "2.0",
-    "depends": [],
-    "js": ["static/*/js/*.js"],
-    "css": [],
+    "depends": ['base'],
+    "js": [
+        'static/lib/dhtmlxGantt/codebase/dhtmlxcommon.js',
+        'static/lib/dhtmlxGantt/codebase/dhtmlxgantt.js',
+        'static/src/js/gantt.js'
+    ],
+    "css": ['static/lib/dhtmlxGantt/codebase/dhtmlxgantt.css'],
+    'active': True
 }

=== added directory 'addons/base_gantt/static/src/js'
=== renamed file 'addons/base_gantt/static/src/gantt.js' => 'addons/base_gantt/static/src/js/gantt.js'
--- addons/base_gantt/static/src/gantt.js	2011-04-07 12:13:31 +0000
+++ addons/base_gantt/static/src/js/gantt.js	2011-04-14 13:43:22 +0000
@@ -2,9 +2,10 @@
  * OpenERP base_gantt
  *---------------------------------------------------------*/
 
-openerp.base.gantt = function (openerp) {
-openerp.base.views.add('gantt', 'openerp.base.GanttView');
-openerp.base.GanttView = openerp.base.Controller.extend({
+openerp.base_gantt = function (openerp) {
+QWeb.add_template('/base_gantt/static/src/xml/base_gantt.xml');
+openerp.base.views.add('gantt', 'openerp.base_gantt.GanttView');
+openerp.base_gantt.GanttView = openerp.base.Controller.extend({
 
     init: function(view_manager, session, element_id, dataset, view_id) {
         this._super(session, element_id);
@@ -216,7 +217,7 @@
                 },
                 function(result) {
                 })
-    },
+    }
 
 });
 

=== added directory 'addons/base_gantt/static/src/xml'
=== added file 'addons/base_gantt/static/src/xml/base_gantt.xml'
--- addons/base_gantt/static/src/xml/base_gantt.xml	1970-01-01 00:00:00 +0000
+++ addons/base_gantt/static/src/xml/base_gantt.xml	2011-04-14 13:43:22 +0000
@@ -0,0 +1,15 @@
+<template>
+  <t t-name="GanttView">
+    <h3 class="title"><t t-esc="view.fields_view.arch.attrs.string"/></h3>
+    <table class="gantt-view" width="100%" height="100%" cellspacing="0" cellpadding="0">
+      <tr>
+        <td style="width:85%">
+          <div style="width:100%;height:300px;position:relative" id="GanttDiv"/>
+        </td>
+        <td valign = "top">
+          <div id="gantt-sidebar"/>
+        </td>
+      </tr>
+    </table>
+  </t>
+</template>

=== modified file 'addons/web_chat/__openerp__.py'
--- addons/web_chat/__openerp__.py	2011-04-13 13:17:56 +0000
+++ addons/web_chat/__openerp__.py	2011-04-14 13:43:22 +0000
@@ -1,8 +1,19 @@
 {
     "name": "Web Chat",
     "version": "2.0",
+<<<<<<< TREE
     "depends": [],
     "js": [],
+=======
+    "depends": ['base'],
+    "js": [
+        'static/lib/AjaxIM/js/jquery.jsonp-1.1.0.js',
+        'static/lib/AjaxIM/js/jquery.jstore-all-min.js',
+        'static/lib/AjaxIM/js/jquery.md5.js',
+        'static/lib/AjaxIM/js/im.js',
+        'static/src/js/web_chat.js'
+    ],
+>>>>>>> MERGE-SOURCE
     "css": [],
     'active': True,
 }

=== modified file 'addons/web_chat/controllers/main.py'
--- addons/web_chat/controllers/main.py	2011-04-13 05:26:33 +0000
+++ addons/web_chat/controllers/main.py	2011-04-14 13:43:22 +0000
@@ -1,5 +1,6 @@
 # -*- coding: utf-8 -*-
 import sys, time
+import cherrypy
 
 import simplejson
 import random
@@ -102,11 +103,6 @@
 
     @openerpweb.httprequest
     def poll(self, req, **kw):
-        
-        mq = req.applicationsession.setdefault("web_chat", PollServerMessageQueue())
-        
-        # Method: Long Poll
-        
         """
         --> GET http://im.ajaxim.com/poll?callback=jsonp1302138663582&_1302138663582=
         <-- 200 OK
@@ -129,8 +125,14 @@
             echo '<script type="text/javascript">parent.AjaxIM.incoming('. json_encode($this->_pollParseMessages($messages)) .  ');</script>'
 
         """
+        mq = req.applicationsession.setdefault("web_chat", PollServerMessageQueue())
+        
+        # Method: Long Poll
+
         
         msg = '[]'
+
+        cherrypy.response.headers['content-type'] = 'application/javascript';
         
         for i in range(5):
             received_msg = mq.read('Guest1', i)
@@ -145,12 +147,6 @@
         
     @openerpweb.httprequest
     def send(self, req, **kw):
-        
-        to = kw.get('to')
-        message = kw.get('message')
-        
-        mq = req.applicationsession.setdefault("web_chat", PollServerMessageQueue())
-        
         """
         --> GET http://im.ajaxim.com/send?callback=jsonp1302139980022&to=Guest130205108745.47&message=test&_1302139980022=
             callback: jsonp1302139980022
@@ -168,6 +164,12 @@
 
         """
         
+        to = kw.get('to')
+        message = kw.get('message')
+        
+        mq = req.applicationsession.setdefault("web_chat", PollServerMessageQueue())
+
+        
         if not req.applicationsession['current_user']:
             return dict(r='error', e='no session found')
         
@@ -182,8 +184,6 @@
 
     @openerpweb.httprequest
     def status(self, req, **kw):
-        mq = req.applicationsession.setdefault("web_chat", PollServerMessageQueue())
-        
         """
         --> GET status call
            const Offline = 0;
@@ -198,6 +198,8 @@
             return array('r' => 'error', 'e' => 'no session found');
             return array('r' => 'error', 'e' => 'status error');
         """
+        mq = req.applicationsession.setdefault("web_chat", PollServerMessageQueue())
+
         print "======== chat status ========",kw
         # mq.write()
         return {"action": ""}

=== added directory 'addons/web_chat/static/src/js'
=== added file 'addons/web_chat/static/src/js/web_chat.js'
--- addons/web_chat/static/src/js/web_chat.js	1970-01-01 00:00:00 +0000
+++ addons/web_chat/static/src/js/web_chat.js	2011-04-14 13:43:22 +0000
@@ -0,0 +1,10 @@
+openerp.web_chat = function (openerp) {
+    openerp.web_chat = {};
+    openerp.web_chat.im = new AjaxIM({
+       storageMethod: 'local',
+       pollServer: '/web_chat/pollserver',
+       theme: '/web_chat/static/lib/AjaxIM/themes/default',
+       flashStorage: '/web_chat/static/lib/AjaxIM/js/jStore.Flash.html'
+    });
+    openerp.web_chat.im.login();
+};

=== removed file 'addons/web_chat/static/src/web_chat.html'
--- addons/web_chat/static/src/web_chat.html	2011-04-11 11:48:10 +0000
+++ addons/web_chat/static/src/web_chat.html	1970-01-01 00:00:00 +0000
@@ -1,24 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script type="text/javascript" src="/web_chat/static/lib/AjaxIM/js/jquery-1.3.2.js"></script>
-<script type="text/javascript" src="/web_chat/static/lib/AjaxIM/js/jquery.jsonp-1.1.0.js"></script>
-<script type="text/javascript" src="/web_chat/static/lib/AjaxIM/js/jquery.jstore-all-min.js"></script>
-<script type="text/javascript" src="/web_chat/static/lib/AjaxIM/js/jquery.md5.js"></script>
-<script type="text/javascript" src="/web_chat/static/lib/AjaxIM/js/im.js"></script>
-</head>
-<body>
-<script>
-var AjaxIM, AjaxIMLoadedFunction;
-$(function() {
-    AjaxIM.init({
-        pollServer: '/web_chat/pollserver',
-        theme: '/web_chat/static/lib/AjaxIM/themes/default',
-        flashStorage: '/web_chat/static/lib/AjaxIM/js/jStore.Flash.html'
-    });
-    AjaxIM.client.login();
-});
-</script>
-</body>
-</html>
-

=== modified file 'doc/source/addons.rst'
--- doc/source/addons.rst	2011-03-30 13:56:19 +0000
+++ doc/source/addons.rst	2011-04-14 13:43:22 +0000
@@ -1,6 +1,10 @@
 Developing OpenERP Web Addons
 =============================
 
+An OpenERP Web addon is simply a Python package with an openerp
+descriptor (a ``__openerp__.py`` file) which follows a few structural
+and namespacing rules.
+
 Structure
 ---------
 
@@ -50,6 +54,79 @@
 ``test/``
   The directories in which all tests for the addon are located.
 
+Some of these are guidelines (and not enforced by code), but it's
+suggested that these be followed. Code which does not fit into these
+categories can go wherever deemed suitable.
+
+Namespacing
+-----------
+
+Python
+++++++
+
+Because addons are also Python packages, they're inherently namespaced
+and nothing special needs to be done on that front.
+
+JavaScript
+++++++++++
+
+The JavaScript side of an addon has to live in the namespace
+``openerp.$addon_name``. For instance, everything created by the addon
+``base`` lives in ``openerp.base``.
+
+The root namespace of the addon is a function which takes a single
+parameter ``openerp``, which is an OpenERP client instance. Objects
+(as well as functions, registry instances, etc...) should be added on
+the correct namespace on that object.
+
+The root function will be called by the OpenERP Web client when
+initializing the addon.
+
+.. code-block:: javascript
+
+    // root namespace of the openerp.example addon
+    /** @namespace */
+    openerp.example = function (openerp) {
+        // basic initialization code (e.g. templates loading)
+        openerp.example.SomeClass = Class.extend(
+            /** @lends openerp.example.SomeClass# */{
+            /**
+             * Description for SomeClass's constructor here
+             *
+             * @constructs
+             */
+            init: function () {
+                // SomeClass initialization code
+            }
+            // rest of SomeClass
+        });
+
+        // access an object in an other addon namespace to replace it
+        openerp.base.SearchView = openerp.base.SearchView.extend({
+            init: function () {
+                this._super.apply(this, arguments);
+                console.log('Search view initialized');
+            }
+        });
+    }
+
+Utility behaviors
+-----------------
+
+JavaScript
+++++++++++
+
+* All javascript objects inheriting from
+  :js:class:`openerp.base.BasicConroller` will have all methods
+  starting with ``on_`` or ``do_`` bound to their ``this``. This means
+  they don't have to be manually bound (via ``_.bind`` or ``$.proxy``)
+  in order to be useable as bound event handlers (event handlers
+  keeping their object as ``this`` rather than taking whatever
+  ``this`` object they were called with).
+
+  Beware that this is only valid for methods starting with ``do_`` and
+  ``on_``, any other method will have to be bound manually.
+
 .. _addons-testing:
 
 Testing


Follow ups