[FIX] non-instance should all be declared with 'var'
[odoo/odoo.git] / doc / source / project.rst
1 The OpenERP Web open-source project
2 ===================================
3
4 Getting involved
5 ----------------
6
7 Translations
8 ++++++++++++
9
10 Bug reporting
11 +++++++++++++
12
13 Source code repository
14 ++++++++++++++++++++++
15
16 Merge proposals
17 +++++++++++++++
18
19 Coding issues and coding conventions
20 ++++++++++++++++++++++++++++++++++++
21
22 Javascript coding
23 ~~~~~~~~~~~~~~~~~
24
25 Use ``var`` for *all* declarations
26 **********************************
27
28 In javascript (as opposed to Python), assigning to a variable which does not
29 already exist and is not explicitly declared (via ``var``) will implicitly
30 create a global variable. This is bad for a number of reasons:
31
32 * It leaks information outside function scopes
33 * It keeps memory of previous run, with potentially buggy behaviors
34 * It may conflict with other functions with the same issue
35 * It makes code harder to statically check (via e.g. IDE inspectors)
36
37 .. note::
38     It is perfectly possible to use ``var`` in ``for`` loops:
39
40     .. code-block:: javascript
41
42         for (var i = 0; i < some_array.length; ++i) {
43             // code here
44         }
45
46     this is not an issue
47
48 All local *and global* variables should be declared via ``var``.
49
50 .. note:: generally speaking, you should not need globals in OpenERP Web: you
51           can just declare a variable local to your top-level function. This
52           way, if your widget/addon is instantiated several times on the same
53           page (because it's used in embedded mode) each instance will have its
54           own internal but global-to-its-objects data.
55
56 Writing documentation
57 +++++++++++++++++++++
58
59 The OpenERP Web project documentation uses Sphinx_ for the literate
60 documentation (this document for instance), the development guides
61 (for Python and Javascript alike) and the Python API documentation
62 (via autodoc_).
63
64 For the Javascript API, documentation should be written using the
65 `JsDoc Toolkit`_.
66
67 Guides and main documentation
68 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
69
70 The meat and most important part of all documentation. Should be
71 written in plain English, using reStructuredText_ and taking advantage
72 of `Sphinx's extensions`_, especially `cross-references`_.
73
74 Python API Documentation
75 ~~~~~~~~~~~~~~~~~~~~~~~~
76
77 All public objects in Python code should have a docstring written in
78 RST, using Sphinx's `Python domain`_ [#]_:
79
80 * Functions and methods documentation should be in their own
81   docstring, using Sphinx's `info fields`_
82
83   For parameters types, built-in and stdlib types should be using the
84   combined syntax::
85
86       :param dict foo: what the purpose of foo is
87
88   unless a more extensive explanation needs to be given (e.g. the
89   specification that the input should be a list of 3-tuple needs to
90   use ``:type:`` even though all types involved are built-ins). Any
91   other type should be specified in full using the ``:type:`` field::
92
93       :param foo: what the purpose of foo is
94       :type foo: some.addon.Class
95
96   Mentions of other methods (including within the same class), modules
97   or types in descriptions (of anything, including parameters) should
98   be cross-referenced.
99
100 * Classes should likewise be documented using their own docstring, and
101   should include the documentation of their construction (``__init__``
102   and ``__new__``), using the `info fields`_  as well.
103
104 * Attributes (class and instance) should be documented in their
105   class's docstring via the ``.. attribute::`` directive, following
106   the class's own documentation.
107
108 * The relation between modules and module-level attributes is similar:
109   modules should be documented in their own docstring, public module
110   attributes should be documented in the module's docstring using the
111   ``.. data::`` directive.
112
113 Javascript API documentation
114 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
115
116 Javascript API documentation uses JsDoc_, a javascript documentation
117 toolkit with a syntax similar to (and inspired by) JavaDoc's.
118
119 Due to limitations of JsDoc, the coding patterns in OpenERP Web and
120 the Sphinx integration, there are a few peculiarities to be aware of
121 when writing javascript API documentation:
122
123 * Namespaces and classes *must* be explicitly marked up even if they
124   are not documented, or JsDoc will not understand what they are and
125   will not generate documentation for their content.
126
127   As a result, the bare minimum for a namespace is::
128
129       /** @namespace */
130       foo.bar.baz = {};
131
132   while for a class it is::
133
134       /** @class */
135       foo.bar.baz.Qux = [...]
136
137 * Because the OpenERP Web project uses `John Resig's Class
138   implementation`_ instead of direct prototypal inheritance [#]_,
139   JsDoc fails to infer class scopes (and constructors or super
140   classes, for that matter) and has to be told explicitly.
141
142   See :ref:`js-class-doc` for the complete rundown.
143
144 * Much like the JavaDoc, JsDoc does not include a full markup
145   language. Instead, comments are simply marked up in HTML.
146
147   This has a number of inconvenients:
148
149   * Complex documentation comments become nigh-unreadable to read in
150     text editors (as opposed to IDEs, which may handle rendering
151     documentation comments on the fly)
152
153   * Though cross-references are supported by JsDoc (via ``@link`` and
154     ``@see``), they only work within the JsDoc
155
156   * More general impossibility to integrate correctly with Sphinx, and
157     e.g. reference JavaScript objects from a tutorial, or have all the
158     documentation live at the same place.
159
160   As a result, JsDoc comments should be marked up using RST, not
161   HTML. They may use Sphinx's cross-references as well.
162
163 .. _js-class-doc:
164
165 Documenting a Class
166 *******************
167
168 The first task when documenting a class using JsDoc is to *mark* that
169 class, so JsDoc knows it can be used to instantiate objects (and, more
170 importantly as far as it's concerned, should be documented with
171 methods and attributes and stuff).
172
173 This is generally done through the ``@class`` tag, but this tag has a
174 significant limitation: it "believes" the constructor and the class
175 are one and the same [#]_. This will work for constructor-less
176 classes, but because OpenERP Web uses Resig's class the constructor is
177 not the class itself but its ``init()`` method.
178
179 Because this pattern is common in modern javascript code bases, JsDoc
180 supports it: it is possible to mark an arbitrary instance method as
181 the *class specification* by using the ``@constructs`` tag.
182
183 .. warning:: ``@constructs`` is a class specification in and of
184     itself, it *completely replaces* the class documentation.
185
186     Using both a class documentation (even without ``@class`` itself)
187     and a constructor documentation is an *error* in JsDoc and will
188     result in incorrect behavior and broken documentation.
189
190 The second issue is that Resig's class uses an object literal to
191 specify instance methods, and because JsDoc does not know anything
192 about Resig's class, it does not know about the role of the object
193 literal.
194
195 As with constructors, though, JsDoc provides a pluggable way to tell
196 it about methods: the ``@lends`` tag. It specifies that the object
197 literal "lends" its properties to the class being built.
198
199 ``@lends`` must be specified right before the opening brace of the
200 object literal (between the opening paren of the ``#extend`` call and
201 the brace), and takes the full qualified name of the class being
202 created as a parameter, followed by the character ``#`` or by
203 ``.prototype``. This latter part tells JsDoc these are instance
204 methods, not class (static) methods..
205
206 Finally, specifying a class's superclass is done through the
207 ``@extends`` tag, which takes a fully qualified class name as a
208 parameter.
209
210 Here are a class without a constructor, and a class with one, so that
211 everything is clear (these are straight from the OpenERP Web source,
212 with the descriptions and irrelevant atttributes stripped):
213
214 .. code-block:: javascript
215
216     /**
217      * <Insert description here, not below>
218      *
219      * @class
220      * @extends openerp.base.search.Field
221      */
222     openerp.base.search.CharField = openerp.base.search.Field.extend(
223         /** @lends openerp.base.search.CharField# */ {
224             // methods here
225     });
226
227 .. code-block:: javascript
228
229
230     openerp.base.search.Widget = openerp.base.Controller.extend(
231         /** @lends openerp.base.search.Widget# */{
232         /**
233          * <Insert description here, not below>
234          *
235          * @constructs
236          * @extends openerp.base.Controller
237          *
238          * @param view the ancestor view of this widget
239          */
240         init: function (view) {
241             // construction of the instance
242         },
243         // bunch of other methods
244     });
245
246 OpenERP Web over time
247 ---------------------
248
249 Release process
250 +++++++++++++++
251
252 OpenSUSE packaging: http://blog.lowkster.com/2011/04/packaging-python-packages-in-opensuse.html
253
254 Roadmap
255 +++++++
256
257 Release notes
258 +++++++++++++
259
260 .. [#] Because Python is the default domain, the ``py:`` markup prefix
261        is optional and should be left out.
262
263 .. [#] Resig's Class still uses prototypes under the hood, it doesn't
264        reimplement its own object system although it does add several
265        helpers such as the ``_super()`` instance method.
266
267 .. [#] Which is the case in normal Javascript semantics. Likewise, the
268        ``.prototype`` / ``#`` pattern we will see later on is due to
269        JsDoc defaulting to the only behavior it can rely on: "normal"
270        Javascript prototype-based type creation.
271
272 .. _reStructuredText:
273     http://docutils.sourceforge.net/rst.html
274 .. _Sphinx:
275     http://sphinx.pocoo.org/index.html
276 .. _Sphinx's extensions:
277     http://sphinx.pocoo.org/markup/index.html
278 .. _Python domain:
279     http://sphinx.pocoo.org/domains.html#the-python-domain
280 .. _info fields:
281     http://sphinx.pocoo.org/domains.html#info-field-lists
282 .. _autodoc:
283     http://sphinx.pocoo.org/ext/autodoc.html
284         ?highlight=autodoc#sphinx.ext.autodoc
285 .. _cross-references:
286     http://sphinx.pocoo.org/markup/inline.html#xref-syntax
287 .. _JsDoc:
288 .. _JsDoc Toolkit:
289     http://code.google.com/p/jsdoc-toolkit/
290 .. _John Resig's Class implementation:
291     http://ejohn.org/blog/simple-javascript-inheritance/