1 The OpenERP Web open-source project
2 ===================================
13 Source code repository
14 ++++++++++++++++++++++
19 Coding issues and coding conventions
20 ++++++++++++++++++++++++++++++++++++
25 Use ``var`` for *all* declarations
26 **********************************
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:
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)
38 It is perfectly possible to use ``var`` in ``for`` loops:
40 .. code-block:: javascript
42 for (var i = 0; i < some_array.length; ++i) {
48 All local *and global* variables should be declared via ``var``.
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.
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
64 For the Javascript API, documentation should be written using the
67 Guides and main documentation
68 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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`_.
74 Python API Documentation
75 ~~~~~~~~~~~~~~~~~~~~~~~~
77 All public objects in Python code should have a docstring written in
78 RST, using Sphinx's `Python domain`_ [#]_:
80 * Functions and methods documentation should be in their own
81 docstring, using Sphinx's `info fields`_
83 For parameters types, built-in and stdlib types should be using the
86 :param dict foo: what the purpose of foo is
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::
93 :param foo: what the purpose of foo is
94 :type foo: some.addon.Class
96 Mentions of other methods (including within the same class), modules
97 or types in descriptions (of anything, including parameters) should
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.
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.
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.
113 Javascript API documentation
114 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
116 Javascript API documentation uses JsDoc_, a javascript documentation
117 toolkit with a syntax similar to (and inspired by) JavaDoc's.
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:
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.
127 As a result, the bare minimum for a namespace is::
132 while for a class it is::
135 foo.bar.baz.Qux = [...]
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.
142 See :ref:`js-class-doc` for the complete rundown.
144 * Much like the JavaDoc, JsDoc does not include a full markup
145 language. Instead, comments are simply marked up in HTML.
147 This has a number of inconvenients:
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)
153 * Though cross-references are supported by JsDoc (via ``@link`` and
154 ``@see``), they only work within the JsDoc
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.
160 As a result, JsDoc comments should be marked up using RST, not
161 HTML. They may use Sphinx's cross-references as well.
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).
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.
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.
183 .. warning:: ``@constructs`` is a class specification in and of
184 itself, it *completely replaces* the class documentation.
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.
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
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.
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..
206 Finally, specifying a class's superclass is done through the
207 ``@extends`` tag, which takes a fully qualified class name as a
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):
214 .. code-block:: javascript
217 * <Insert description here, not below>
220 * @extends openerp.base.search.Field
222 openerp.base.search.CharField = openerp.base.search.Field.extend(
223 /** @lends openerp.base.search.CharField# */ {
227 .. code-block:: javascript
230 openerp.base.search.Widget = openerp.base.Controller.extend(
231 /** @lends openerp.base.search.Widget# */{
233 * <Insert description here, not below>
236 * @extends openerp.base.Controller
238 * @param view the ancestor view of this widget
240 init: function (view) {
241 // construction of the instance
243 // bunch of other methods
246 OpenERP Web over time
247 ---------------------
252 OpenSUSE packaging: http://blog.lowkster.com/2011/04/packaging-python-packages-in-opensuse.html
260 .. [#] Because Python is the default domain, the ``py:`` markup prefix
261 is optional and should be left out.
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.
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.
272 .. _reStructuredText:
273 http://docutils.sourceforge.net/rst.html
275 http://sphinx.pocoo.org/index.html
276 .. _Sphinx's extensions:
277 http://sphinx.pocoo.org/markup/index.html
279 http://sphinx.pocoo.org/domains.html#the-python-domain
281 http://sphinx.pocoo.org/domains.html#info-field-lists
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
289 http://code.google.com/p/jsdoc-toolkit/
290 .. _John Resig's Class implementation:
291 http://ejohn.org/blog/simple-javascript-inheritance/