summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rw-r--r--doc/_themes/odoodoc/layout.html1
-rw-r--r--doc/_themes/odoodoc/static/app.js85
-rw-r--r--doc/_themes/odoodoc/static/style.css68
-rw-r--r--doc/_themes/odoodoc/static/style.less94
-rw-r--r--doc/_themes/odoodoc/static/zeroclipboard-2.1.6/ZeroClipboard.min.js9
-rw-r--r--doc/_themes/odoodoc/static/zeroclipboard-2.1.6/ZeroClipboard.swfbin4036 -> 0 bytes
-rw-r--r--doc/api_integration.rst6
-rw-r--r--doc/howtos/backend.rst40
-rw-r--r--doc/howtos/backend/exercise-creation4
-rw-r--r--doc/howtos/backend/exercise-dashboard3
-rw-r--r--doc/howtos/backend/exercise-model-inheritance6
-rw-r--r--doc/howtos/backend/exercise-wizard8
-rw-r--r--doc/howtos/themes.rst67
-rw-r--r--doc/reference/actions.rst2
-rw-r--r--doc/reference/cmdline.rst29
-rw-r--r--doc/reference/module.rst21
-rw-r--r--doc/reference/qweb.rst2
-rw-r--r--doc/reference/testing.rst18
-rw-r--r--doc/setup/install.rst317
19 files changed, 421 insertions, 359 deletions
diff --git a/doc/_themes/odoodoc/layout.html b/doc/_themes/odoodoc/layout.html
index b01eaf05216..af62f44bbb4 100644
--- a/doc/_themes/odoodoc/layout.html
+++ b/doc/_themes/odoodoc/layout.html
@@ -6,7 +6,6 @@
'_static/bootstrap/js/tooltip.js',
'_static/bootstrap/js/collapse.js',
'_static/bootstrap/js/dropdown.js',
- '_static/zeroclipboard-2.1.6/ZeroClipboard.min.js',
'_static/app.js'
] %}
diff --git a/doc/_themes/odoodoc/static/app.js b/doc/_themes/odoodoc/static/app.js
index a0d7376530a..208a29dcf42 100644
--- a/doc/_themes/odoodoc/static/app.js
+++ b/doc/_themes/odoodoc/static/app.js
@@ -25,40 +25,6 @@ $(function () {
});
}, 100);
- /*
- for clipboard:
- * add per-language setup code to document, hidden
- * adds button to each switchable language block except when they're setup
- stuff because fuck'em
- * per-language, add clipboard hook to prefix with setup bit on-copy
- * setup bit is... ?
- * actually not all blocks because we don't want to add the setup bits to
- the setup bits, so that's kinda shit
- */
-
- document.addEventListener('copy', copyCode);
-
- ZeroClipboard.config({
- swfPath: '../_static/zeroclipboard-2.1.6/ZeroClipboard.swf',
- flashLoadTimeout: 3e3,
- });
- var zc = new ZeroClipboard();
- zc.on('ready', function () {
- var $highlighted = $('.switchable:not(.setup) .highlight').addClass('with-btn-clipboard');
- var $clipboard_buttons =
- $('<button type="button" class="btn-clipboard">Copy</button>')
- .on('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd', function () {
- $(this).removeClass('active');
- })
- .prependTo($highlighted);
- zc.clip($clipboard_buttons);
- });
- zc.on('copy', function (e) {
- // yellow flash
- $(e.target).addClass('active');
- copyCode(e);
- });
-
// stripe page stuff
if ($('div.document-super').hasClass('stripe')) { (function () {
// iterate on highlighted PL blocks (but not results because that'd
@@ -95,38 +61,31 @@ $(function () {
sheet.insertRule(sel + '{' + content + '}', lastIndex);
});
$switcher.affix();
- })(); }
+ $('<button type="button" class="btn-show-setup">Toggle Setup Code</button>')
+ .prependTo('.switchable:not(.setup) .highlight');
+ $(document).on('click', '.btn-show-setup', function (e) {
+ var $target = $(e.target);
+ var target = $target.closest('.switchable:not(.setup)').get(0);
+ // not in a switchable (???)
+ if (!target) { return; }
+ var lang = getHighlightLanguage(target);
+ if (!lang) {
+ // switchable without highlight (e.g. language-specific notes),
+ // don't munge
+ return;
+ }
- function copyCode(e) {
- // works for both C-c and "Copy" button if copy button is injected
- // inside highlighted code section
- var target = $(e.target).closest('.switchable:not(.setup)').get(0);
- // not in a switchable
- if (!target) { return; }
- var lang = getHighlightLanguage(target);
- if (!lang) {
- // switchable without highlight (e.g. language-specific notes),
- // don't munge
- return;
- }
-
- // get generic setup code
- var setup_selector = '.setupcode.highlight-' + lang + ' pre';
- var setup = document.querySelector(setup_selector).textContent;
-
- // prepend setup code to current snippet, get all of current snippet
- // in case only part of it was selected. Ensure we don't get e.g.
- // button text around snippet itself
- var data = setup + '\n' + target.querySelector('pre').textContent;
- // sane browsers & ZeroClipboard
- e.clipboardData.setData('text/plain', data);
- // MSIE
- e.clipboardData.setData('Text', data);
+ var $setup_code = $target.prev();
+ if ($setup_code.length) {
+ // remove existing setup code
+ $setup_code.remove();
+ } else {
+ $('.setupcode.highlight-' + lang + ' pre').clone().insertBefore($target);
+ }
+ });
+ })(); }
- // no preventDefault on ZC event
- e.preventDefault && e.preventDefault();
- }
/**
* @param {Node} node highlight node to get the language of
* @returns {String|null} either the highlight language or null
diff --git a/doc/_themes/odoodoc/static/style.css b/doc/_themes/odoodoc/static/style.css
index 12ffb135f6f..7fc2d3dcb95 100644
--- a/doc/_themes/odoodoc/static/style.css
+++ b/doc/_themes/odoodoc/static/style.css
@@ -4076,7 +4076,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
}
}
.navbar-default {
- background-color: #ffffff;
+ background-color: white;
border-color: 0;
}
.navbar-default .navbar-brand {
@@ -6663,49 +6663,43 @@ div.section > h2 {
.admonition.exercise > .admonition-title {
color: #555555;
}
-/*
- * Code snippets
- *
- * Generated via Pygments
- */
+.highlight {
+ position: relative;
+ color: #333333;
+ background: #eeeeee none !important;
+ border: 1px solid #777777;
+ border-radius: 4px 0 4px 4px;
+ margin: 10px 0;
+}
.highlight pre {
- padding: 4px;
+ padding: 0;
+ margin: 10px;
font-size: 75%;
word-break: normal;
word-wrap: normal;
+ background: none;
+ border: none;
}
-.switchable .highlight.with-btn-clipboard pre {
- padding-right: 50px;
-}
-/*
- * ZeroClipboard styles
- */
-.highlight {
- position: relative;
+.highlight:hover .btn-show-setup {
+ display: block;
}
-.btn-clipboard {
+.highlight .btn-show-setup {
+ display: none;
position: absolute;
- top: 0;
+ bottom: 100%;
right: 0;
z-index: 3;
- display: block;
padding: 5px 8px;
font-size: 12px;
- color: #777;
+ color: #777777;
cursor: pointer;
- background-color: #fff;
- border: 1px solid #e1e1e8;
- border-radius: 0 4px 0 4px;
+ border: 1px solid #777777;
+ border-radius: 4px 4px 0 0;
+ background: inherit;
}
-.btn-clipboard:focus {
+.highlight .btn-show-setup:focus {
outline: none;
}
-.btn-clipboard.active {
- background-color: #ffffad;
- -webkit-transition: background-color 0.5s linear;
- -o-transition: background-color 0.5s linear;
- transition: background-color 0.5s linear;
-}
img.align-center {
display: block;
margin: 0 auto;
@@ -6843,20 +6837,14 @@ td.field-body > ul {
border-bottom-color: #777777;
border-right-color: #777777;
}
- .stripe .section > .force-right pre,
- .stripe .section > [class*=highlight] pre {
- padding: 0;
- margin: 10px;
- background: none;
- border: none;
- }
.stripe .section > .force-right .highlight,
.stripe .section > [class*=highlight] .highlight {
border-color: #555555;
border-style: solid;
border-width: 1px 0;
+ border-radius: 0;
color: #cccccc;
- background: none;
+ background: none !important;
/* Line Numbers */
/* Comment */
/* Error */
@@ -7243,14 +7231,12 @@ td.field-body > ul {
.stripe .highlight pre {
white-space: pre-wrap;
}
- .stripe .btn-clipboard {
+ .stripe .btn-show-setup {
background-color: transparent;
color: #eeeeee;
border-color: #777777;
- border-top: none;
- border-top-right-radius: 0;
}
- .stripe .btn-clipboard.active {
+ .stripe .btn-show-setup.active {
background-color: #555555;
-webkit-transition: background-color 0.5s linear;
-o-transition: background-color 0.5s linear;
diff --git a/doc/_themes/odoodoc/static/style.less b/doc/_themes/odoodoc/static/style.less
index d3703999414..480e43c5cb8 100644
--- a/doc/_themes/odoodoc/static/style.less
+++ b/doc/_themes/odoodoc/static/style.less
@@ -465,50 +465,50 @@ div.section > h2 {
}
}
-/*
- * Code snippets
- *
- * Generated via Pygments
- */
-.highlight pre {
- padding: 4px;
- font-size: 75%;
- // don't break lines within words
- word-break: normal;
- word-wrap: normal;
-}
-.switchable .highlight.with-btn-clipboard pre {
- // avoid copy button overlapping with even long lines
- padding-right: 50px;
-}
-
-/*
- * ZeroClipboard styles
- */
.highlight {
position: relative;
-}
-.btn-clipboard {
- position: absolute;
- top: 0;
- right: 0;
- z-index: 3;
- display: block;
- padding: 5px 8px;
- font-size: 12px;
- color: #777;
- cursor: pointer;
- background-color: #fff;
- border: 1px solid #e1e1e8;
- border-radius: 0 4px 0 4px;
- &:focus {
- outline: none;
+ // move styling from pre to highlight so can have multiple pre elements in
+ // a single "code block" for ease of adding and removing setup code &al
+ color: @gray-dark;
+ // force override of pygments yellow background background
+ background: @gray-lighter none !important;
+ border: 1px solid @gray-light;
+ border-radius: @border-radius-base 0 @border-radius-base @border-radius-base;
+ margin: 10px 0;
+
+ pre {
+ padding: 0;
+ margin: 10px;
+ font-size: 75%;
+ // don't break lines within words
+ word-break: normal;
+ word-wrap: normal;
+
+ background: none;
+ border: none;
}
- &.active {
- background-color: #ffffad;
- .transition(background-color .5s linear);
+ &:hover .btn-show-setup {
+ display: block;
+ }
+ .btn-show-setup {
+ display: none;
+ position: absolute;
+ bottom: 100%;
+ right: 0;
+ z-index: 3;
+ padding: 5px 8px;
+ font-size: 12px;
+ color: @gray-light;
+ cursor: pointer;
+ border: 1px solid @gray-light;
+ border-radius: @border-radius-base @border-radius-base 0 0;
+ background: inherit;
+
+ &:focus {
+ outline: none;
+ }
}
}
@@ -638,22 +638,14 @@ td.field-body {
border-bottom-color: @separator-right;
border-right-color: @separator-right;
}
- pre {
- // padding leads to overflow scrollbar in safari for no reason I understand,
- // margin does not have that issue
- padding: 0;
- margin: 10px;
-
- background: none;
- border: none;
- }
.highlight {
border-color: @gray;
border-style: solid;
border-width: 1px 0;
+ border-radius: 0;
// solarized-ish from https://gist.github.com/qguv/7936275
color: @color-right-code;
- background: none;
+ background: none !important;
.lineno { color: #586e75 } /* Line Numbers */
.c { color: #586e75 } /* Comment */
.err { color: @color-right-code } /* Error */
@@ -761,12 +753,10 @@ td.field-body {
white-space: pre-wrap;
}
- .btn-clipboard {
+ .btn-show-setup {
background-color: transparent;
color: @color-right;
border-color: @separator-right;
- border-top: none;
- border-top-right-radius: 0;
&.active {
background-color: @gray;
diff --git a/doc/_themes/odoodoc/static/zeroclipboard-2.1.6/ZeroClipboard.min.js b/doc/_themes/odoodoc/static/zeroclipboard-2.1.6/ZeroClipboard.min.js
deleted file mode 100644
index 365737f559a..00000000000
--- a/doc/_themes/odoodoc/static/zeroclipboard-2.1.6/ZeroClipboard.min.js
+++ /dev/null
@@ -1,9 +0,0 @@
-/*!
- * ZeroClipboard
- * The ZeroClipboard library provides an easy way to copy text to the clipboard using an invisible Adobe Flash movie and a JavaScript interface.
- * Copyright (c) 2014 Jon Rohan, James M. Greene
- * Licensed MIT
- * http://zeroclipboard.org/
- * v2.1.6
- */
-!function(a,b){"use strict";var c,d,e=a,f=e.document,g=e.navigator,h=e.setTimeout,i=e.encodeURIComponent,j=e.ActiveXObject,k=e.Error,l=e.Number.parseInt||e.parseInt,m=e.Number.parseFloat||e.parseFloat,n=e.Number.isNaN||e.isNaN,o=e.Math.round,p=e.Date.now,q=e.Object.keys,r=e.Object.defineProperty,s=e.Object.prototype.hasOwnProperty,t=e.Array.prototype.slice,u=function(){var a=function(a){return a};if("function"==typeof e.wrap&&"function"==typeof e.unwrap)try{var b=f.createElement("div"),c=e.unwrap(b);1===b.nodeType&&c&&1===c.nodeType&&(a=e.unwrap)}catch(d){}return a}(),v=function(a){return t.call(a,0)},w=function(){var a,c,d,e,f,g,h=v(arguments),i=h[0]||{};for(a=1,c=h.length;c>a;a++)if(null!=(d=h[a]))for(e in d)s.call(d,e)&&(f=i[e],g=d[e],i!==g&&g!==b&&(i[e]=g));return i},x=function(a){var b,c,d,e;if("object"!=typeof a||null==a)b=a;else if("number"==typeof a.length)for(b=[],c=0,d=a.length;d>c;c++)s.call(a,c)&&(b[c]=x(a[c]));else{b={};for(e in a)s.call(a,e)&&(b[e]=x(a[e]))}return b},y=function(a,b){for(var c={},d=0,e=b.length;e>d;d++)b[d]in a&&(c[b[d]]=a[b[d]]);return c},z=function(a,b){var c={};for(var d in a)-1===b.indexOf(d)&&(c[d]=a[d]);return c},A=function(a){if(a)for(var b in a)s.call(a,b)&&delete a[b];return a},B=function(a,b){if(a&&1===a.nodeType&&a.ownerDocument&&b&&(1===b.nodeType&&b.ownerDocument&&b.ownerDocument===a.ownerDocument||9===b.nodeType&&!b.ownerDocument&&b===a.ownerDocument))do{if(a===b)return!0;a=a.parentNode}while(a);return!1},C=function(a){var b;return"string"==typeof a&&a&&(b=a.split("#")[0].split("?")[0],b=a.slice(0,a.lastIndexOf("/")+1)),b},D=function(a){var b,c;return"string"==typeof a&&a&&(c=a.match(/^(?:|[^:@]*@|.+\)@(?=http[s]?|file)|.+?\s+(?: at |@)(?:[^:\(]+ )*[\(]?)((?:http[s]?|file):\/\/[\/]?.+?\/[^:\)]*?)(?::\d+)(?::\d+)?/),c&&c[1]?b=c[1]:(c=a.match(/\)@((?:http[s]?|file):\/\/[\/]?.+?\/[^:\)]*?)(?::\d+)(?::\d+)?/),c&&c[1]&&(b=c[1]))),b},E=function(){var a,b;try{throw new k}catch(c){b=c}return b&&(a=b.sourceURL||b.fileName||D(b.stack)),a},F=function(){var a,c,d;if(f.currentScript&&(a=f.currentScript.src))return a;if(c=f.getElementsByTagName("script"),1===c.length)return c[0].src||b;if("readyState"in c[0])for(d=c.length;d--;)if("interactive"===c[d].readyState&&(a=c[d].src))return a;return"loading"===f.readyState&&(a=c[c.length-1].src)?a:(a=E())?a:b},G=function(){var a,c,d,e=f.getElementsByTagName("script");for(a=e.length;a--;){if(!(d=e[a].src)){c=null;break}if(d=C(d),null==c)c=d;else if(c!==d){c=null;break}}return c||b},H=function(){var a=C(F())||G()||"";return a+"ZeroClipboard.swf"},I={bridge:null,version:"0.0.0",pluginType:"unknown",disabled:null,outdated:null,unavailable:null,deactivated:null,overdue:null,ready:null},J="11.0.0",K={},L={},M=null,N={ready:"Flash communication is established",error:{"flash-disabled":"Flash is disabled or not installed","flash-outdated":"Flash is too outdated to support ZeroClipboard","flash-unavailable":"Flash is unable to communicate bidirectionally with JavaScript","flash-deactivated":"Flash is too outdated for your browser and/or is configured as click-to-activate","flash-overdue":"Flash communication was established but NOT within the acceptable time limit"}},O={swfPath:H(),trustedDomains:a.location.host?[a.location.host]:[],cacheBust:!0,forceEnhancedClipboard:!1,flashLoadTimeout:3e4,autoActivate:!0,bubbleEvents:!0,containerId:"global-zeroclipboard-html-bridge",containerClass:"global-zeroclipboard-container",swfObjectId:"global-zeroclipboard-flash-bridge",hoverClass:"zeroclipboard-is-hover",activeClass:"zeroclipboard-is-active",forceHandCursor:!1,title:null,zIndex:999999999},P=function(a){if("object"==typeof a&&null!==a)for(var b in a)if(s.call(a,b))if(/^(?:forceHandCursor|title|zIndex|bubbleEvents)$/.test(b))O[b]=a[b];else if(null==I.bridge)if("containerId"===b||"swfObjectId"===b){if(!cb(a[b]))throw new Error("The specified `"+b+"` value is not valid as an HTML4 Element ID");O[b]=a[b]}else O[b]=a[b];{if("string"!=typeof a||!a)return x(O);if(s.call(O,a))return O[a]}},Q=function(){return{browser:y(g,["userAgent","platform","appName"]),flash:z(I,["bridge"]),zeroclipboard:{version:Fb.version,config:Fb.config()}}},R=function(){return!!(I.disabled||I.outdated||I.unavailable||I.deactivated)},S=function(a,b){var c,d,e,f={};if("string"==typeof a&&a)e=a.toLowerCase().split(/\s+/);else if("object"==typeof a&&a&&"undefined"==typeof b)for(c in a)s.call(a,c)&&"string"==typeof c&&c&&"function"==typeof a[c]&&Fb.on(c,a[c]);if(e&&e.length){for(c=0,d=e.length;d>c;c++)a=e[c].replace(/^on/,""),f[a]=!0,K[a]||(K[a]=[]),K[a].push(b);if(f.ready&&I.ready&&Fb.emit({type:"ready"}),f.error){var g=["disabled","outdated","unavailable","deactivated","overdue"];for(c=0,d=g.length;d>c;c++)if(I[g[c]]===!0){Fb.emit({type:"error",name:"flash-"+g[c]});break}}}return Fb},T=function(a,b){var c,d,e,f,g;if(0===arguments.length)f=q(K);else if("string"==typeof a&&a)f=a.split(/\s+/);else if("object"==typeof a&&a&&"undefined"==typeof b)for(c in a)s.call(a,c)&&"string"==typeof c&&c&&"function"==typeof a[c]&&Fb.off(c,a[c]);if(f&&f.length)for(c=0,d=f.length;d>c;c++)if(a=f[c].toLowerCase().replace(/^on/,""),g=K[a],g&&g.length)if(b)for(e=g.indexOf(b);-1!==e;)g.splice(e,1),e=g.indexOf(b,e);else g.length=0;return Fb},U=function(a){var b;return b="string"==typeof a&&a?x(K[a])||null:x(K)},V=function(a){var b,c,d;return a=db(a),a&&!jb(a)?"ready"===a.type&&I.overdue===!0?Fb.emit({type:"error",name:"flash-overdue"}):(b=w({},a),ib.call(this,b),"copy"===a.type&&(d=pb(L),c=d.data,M=d.formatMap),c):void 0},W=function(){if("boolean"!=typeof I.ready&&(I.ready=!1),!Fb.isFlashUnusable()&&null===I.bridge){var a=O.flashLoadTimeout;"number"==typeof a&&a>=0&&h(function(){"boolean"!=typeof I.deactivated&&(I.deactivated=!0),I.deactivated===!0&&Fb.emit({type:"error",name:"flash-deactivated"})},a),I.overdue=!1,nb()}},X=function(){Fb.clearData(),Fb.blur(),Fb.emit("destroy"),ob(),Fb.off()},Y=function(a,b){var c;if("object"==typeof a&&a&&"undefined"==typeof b)c=a,Fb.clearData();else{if("string"!=typeof a||!a)return;c={},c[a]=b}for(var d in c)"string"==typeof d&&d&&s.call(c,d)&&"string"==typeof c[d]&&c[d]&&(L[d]=c[d])},Z=function(a){"undefined"==typeof a?(A(L),M=null):"string"==typeof a&&s.call(L,a)&&delete L[a]},$=function(a){return"undefined"==typeof a?x(L):"string"==typeof a&&s.call(L,a)?L[a]:void 0},_=function(a){if(a&&1===a.nodeType){c&&(xb(c,O.activeClass),c!==a&&xb(c,O.hoverClass)),c=a,wb(a,O.hoverClass);var b=a.getAttribute("title")||O.title;if("string"==typeof b&&b){var d=mb(I.bridge);d&&d.setAttribute("title",b)}var e=O.forceHandCursor===!0||"pointer"===yb(a,"cursor");Cb(e),Bb()}},ab=function(){var a=mb(I.bridge);a&&(a.removeAttribute("title"),a.style.left="0px",a.style.top="-9999px",a.style.width="1px",a.style.top="1px"),c&&(xb(c,O.hoverClass),xb(c,O.activeClass),c=null)},bb=function(){return c||null},cb=function(a){return"string"==typeof a&&a&&/^[A-Za-z][A-Za-z0-9_:\-\.]*$/.test(a)},db=function(a){var b;if("string"==typeof a&&a?(b=a,a={}):"object"==typeof a&&a&&"string"==typeof a.type&&a.type&&(b=a.type),b){!a.target&&/^(copy|aftercopy|_click)$/.test(b.toLowerCase())&&(a.target=d),w(a,{type:b.toLowerCase(),target:a.target||c||null,relatedTarget:a.relatedTarget||null,currentTarget:I&&I.bridge||null,timeStamp:a.timeStamp||p()||null});var e=N[a.type];return"error"===a.type&&a.name&&e&&(e=e[a.name]),e&&(a.message=e),"ready"===a.type&&w(a,{target:null,version:I.version}),"error"===a.type&&(/^flash-(disabled|outdated|unavailable|deactivated|overdue)$/.test(a.name)&&w(a,{target:null,minimumVersion:J}),/^flash-(outdated|unavailable|deactivated|overdue)$/.test(a.name)&&w(a,{version:I.version})),"copy"===a.type&&(a.clipboardData={setData:Fb.setData,clearData:Fb.clearData}),"aftercopy"===a.type&&(a=qb(a,M)),a.target&&!a.relatedTarget&&(a.relatedTarget=eb(a.target)),a=fb(a)}},eb=function(a){var b=a&&a.getAttribute&&a.getAttribute("data-clipboard-target");return b?f.getElementById(b):null},fb=function(a){if(a&&/^_(?:click|mouse(?:over|out|down|up|move))$/.test(a.type)){var c=a.target,d="_mouseover"===a.type&&a.relatedTarget?a.relatedTarget:b,g="_mouseout"===a.type&&a.relatedTarget?a.relatedTarget:b,h=Ab(c),i=e.screenLeft||e.screenX||0,j=e.screenTop||e.screenY||0,k=f.body.scrollLeft+f.documentElement.scrollLeft,l=f.body.scrollTop+f.documentElement.scrollTop,m=h.left+("number"==typeof a._stageX?a._stageX:0),n=h.top+("number"==typeof a._stageY?a._stageY:0),o=m-k,p=n-l,q=i+o,r=j+p,s="number"==typeof a.movementX?a.movementX:0,t="number"==typeof a.movementY?a.movementY:0;delete a._stageX,delete a._stageY,w(a,{srcElement:c,fromElement:d,toElement:g,screenX:q,screenY:r,pageX:m,pageY:n,clientX:o,clientY:p,x:o,y:p,movementX:s,movementY:t,offsetX:0,offsetY:0,layerX:0,layerY:0})}return a},gb=function(a){var b=a&&"string"==typeof a.type&&a.type||"";return!/^(?:(?:before)?copy|destroy)$/.test(b)},hb=function(a,b,c,d){d?h(function(){a.apply(b,c)},0):a.apply(b,c)},ib=function(a){if("object"==typeof a&&a&&a.type){var b=gb(a),c=K["*"]||[],d=K[a.type]||[],f=c.concat(d);if(f&&f.length){var g,h,i,j,k,l=this;for(g=0,h=f.length;h>g;g++)i=f[g],j=l,"string"==typeof i&&"function"==typeof e[i]&&(i=e[i]),"object"==typeof i&&i&&"function"==typeof i.handleEvent&&(j=i,i=i.handleEvent),"function"==typeof i&&(k=w({},a),hb(i,j,[k],b))}return this}},jb=function(a){var b=a.target||c||null,e="swf"===a._source;delete a._source;var f=["flash-disabled","flash-outdated","flash-unavailable","flash-deactivated","flash-overdue"];switch(a.type){case"error":-1!==f.indexOf(a.name)&&w(I,{disabled:"flash-disabled"===a.name,outdated:"flash-outdated"===a.name,unavailable:"flash-unavailable"===a.name,deactivated:"flash-deactivated"===a.name,overdue:"flash-overdue"===a.name,ready:!1});break;case"ready":var g=I.deactivated===!0;w(I,{disabled:!1,outdated:!1,unavailable:!1,deactivated:!1,overdue:g,ready:!g});break;case"beforecopy":d=b;break;case"copy":var h,i,j=a.relatedTarget;!L["text/html"]&&!L["text/plain"]&&j&&(i=j.value||j.outerHTML||j.innerHTML)&&(h=j.value||j.textContent||j.innerText)?(a.clipboardData.clearData(),a.clipboardData.setData("text/plain",h),i!==h&&a.clipboardData.setData("text/html",i)):!L["text/plain"]&&a.target&&(h=a.target.getAttribute("data-clipboard-text"))&&(a.clipboardData.clearData(),a.clipboardData.setData("text/plain",h));break;case"aftercopy":Fb.clearData(),b&&b!==vb()&&b.focus&&b.focus();break;case"_mouseover":Fb.focus(b),O.bubbleEvents===!0&&e&&(b&&b!==a.relatedTarget&&!B(a.relatedTarget,b)&&kb(w({},a,{type:"mouseenter",bubbles:!1,cancelable:!1})),kb(w({},a,{type:"mouseover"})));break;case"_mouseout":Fb.blur(),O.bubbleEvents===!0&&e&&(b&&b!==a.relatedTarget&&!B(a.relatedTarget,b)&&kb(w({},a,{type:"mouseleave",bubbles:!1,cancelable:!1})),kb(w({},a,{type:"mouseout"})));break;case"_mousedown":wb(b,O.activeClass),O.bubbleEvents===!0&&e&&kb(w({},a,{type:a.type.slice(1)}));break;case"_mouseup":xb(b,O.activeClass),O.bubbleEvents===!0&&e&&kb(w({},a,{type:a.type.slice(1)}));break;case"_click":d=null,O.bubbleEvents===!0&&e&&kb(w({},a,{type:a.type.slice(1)}));break;case"_mousemove":O.bubbleEvents===!0&&e&&kb(w({},a,{type:a.type.slice(1)}))}return/^_(?:click|mouse(?:over|out|down|up|move))$/.test(a.type)?!0:void 0},kb=function(a){if(a&&"string"==typeof a.type&&a){var b,c=a.target||null,d=c&&c.ownerDocument||f,g={view:d.defaultView||e,canBubble:!0,cancelable:!0,detail:"click"===a.type?1:0,button:"number"==typeof a.which?a.which-1:"number"==typeof a.button?a.button:d.createEvent?0:1},h=w(g,a);c&&d.createEvent&&c.dispatchEvent&&(h=[h.type,h.canBubble,h.cancelable,h.view,h.detail,h.screenX,h.screenY,h.clientX,h.clientY,h.ctrlKey,h.altKey,h.shiftKey,h.metaKey,h.button,h.relatedTarget],b=d.createEvent("MouseEvents"),b.initMouseEvent&&(b.initMouseEvent.apply(b,h),b._source="js",c.dispatchEvent(b)))}},lb=function(){var a=f.createElement("div");return a.id=O.containerId,a.className=O.containerClass,a.style.position="absolute",a.style.left="0px",a.style.top="-9999px",a.style.width="1px",a.style.height="1px",a.style.zIndex=""+Db(O.zIndex),a},mb=function(a){for(var b=a&&a.parentNode;b&&"OBJECT"===b.nodeName&&b.parentNode;)b=b.parentNode;return b||null},nb=function(){var a,b=I.bridge,c=mb(b);if(!b){var d=ub(e.location.host,O),g="never"===d?"none":"all",h=sb(O),i=O.swfPath+rb(O.swfPath,O);c=lb();var j=f.createElement("div");c.appendChild(j),f.body.appendChild(c);var k=f.createElement("div"),l="activex"===I.pluginType;k.innerHTML='<object id="'+O.swfObjectId+'" name="'+O.swfObjectId+'" width="100%" height="100%" '+(l?'classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"':'type="application/x-shockwave-flash" data="'+i+'"')+">"+(l?'<param name="movie" value="'+i+'"/>':"")+'<param name="allowScriptAccess" value="'+d+'"/><param name="allowNetworking" value="'+g+'"/><param name="menu" value="false"/><param name="wmode" value="transparent"/><param name="flashvars" value="'+h+'"/></object>',b=k.firstChild,k=null,u(b).ZeroClipboard=Fb,c.replaceChild(b,j)}return b||(b=f[O.swfObjectId],b&&(a=b.length)&&(b=b[a-1]),!b&&c&&(b=c.firstChild)),I.bridge=b||null,b},ob=function(){var a=I.bridge;if(a){var b=mb(a);b&&("activex"===I.pluginType&&"readyState"in a?(a.style.display="none",function c(){if(4===a.readyState){for(var d in a)"function"==typeof a[d]&&(a[d]=null);a.parentNode&&a.parentNode.removeChild(a),b.parentNode&&b.parentNode.removeChild(b)}else h(c,10)}()):(a.parentNode&&a.parentNode.removeChild(a),b.parentNode&&b.parentNode.removeChild(b))),I.ready=null,I.bridge=null,I.deactivated=null}},pb=function(a){var b={},c={};if("object"==typeof a&&a){for(var d in a)if(d&&s.call(a,d)&&"string"==typeof a[d]&&a[d])switch(d.toLowerCase()){case"text/plain":case"text":case"air:text":case"flash:text":b.text=a[d],c.text=d;break;case"text/html":case"html":case"air:html":case"flash:html":b.html=a[d],c.html=d;break;case"application/rtf":case"text/rtf":case"rtf":case"richtext":case"air:rtf":case"flash:rtf":b.rtf=a[d],c.rtf=d}return{data:b,formatMap:c}}},qb=function(a,b){if("object"!=typeof a||!a||"object"!=typeof b||!b)return a;var c={};for(var d in a)if(s.call(a,d)){if("success"!==d&&"data"!==d){c[d]=a[d];continue}c[d]={};var e=a[d];for(var f in e)f&&s.call(e,f)&&s.call(b,f)&&(c[d][b[f]]=e[f])}return c},rb=function(a,b){var c=null==b||b&&b.cacheBust===!0;return c?(-1===a.indexOf("?")?"?":"&")+"noCache="+p():""},sb=function(a){var b,c,d,f,g="",h=[];if(a.trustedDomains&&("string"==typeof a.trustedDomains?f=[a.trustedDomains]:"object"==typeof a.trustedDomains&&"length"in a.trustedDomains&&(f=a.trustedDomains)),f&&f.length)for(b=0,c=f.length;c>b;b++)if(s.call(f,b)&&f[b]&&"string"==typeof f[b]){if(d=tb(f[b]),!d)continue;if("*"===d){h.length=0,h.push(d);break}h.push.apply(h,[d,"//"+d,e.location.protocol+"//"+d])}return h.length&&(g+="trustedOrigins="+i(h.join(","))),a.forceEnhancedClipboard===!0&&(g+=(g?"&":"")+"forceEnhancedClipboard=true"),"string"==typeof a.swfObjectId&&a.swfObjectId&&(g+=(g?"&":"")+"swfObjectId="+i(a.swfObjectId)),g},tb=function(a){if(null==a||""===a)return null;if(a=a.replace(/^\s+|\s+$/g,""),""===a)return null;var b=a.indexOf("//");a=-1===b?a:a.slice(b+2);var c=a.indexOf("/");return a=-1===c?a:-1===b||0===c?null:a.slice(0,c),a&&".swf"===a.slice(-4).toLowerCase()?null:a||null},ub=function(){var a=function(a){var b,c,d,e=[];if("string"==typeof a&&(a=[a]),"object"!=typeof a||!a||"number"!=typeof a.length)return e;for(b=0,c=a.length;c>b;b++)if(s.call(a,b)&&(d=tb(a[b]))){if("*"===d){e.length=0,e.push("*");break}-1===e.indexOf(d)&&e.push(d)}return e};return function(b,c){var d=tb(c.swfPath);null===d&&(d=b);var e=a(c.trustedDomains),f=e.length;if(f>0){if(1===f&&"*"===e[0])return"always";if(-1!==e.indexOf(b))return 1===f&&b===d?"sameDomain":"always"}return"never"}}(),vb=function(){try{return f.activeElement}catch(a){return null}},wb=function(a,b){if(!a||1!==a.nodeType)return a;if(a.classList)return a.classList.contains(b)||a.classList.add(b),a;if(b&&"string"==typeof b){var c=(b||"").split(/\s+/);if(1===a.nodeType)if(a.className){for(var d=" "+a.className+" ",e=a.className,f=0,g=c.length;g>f;f++)d.indexOf(" "+c[f]+" ")<0&&(e+=" "+c[f]);a.className=e.replace(/^\s+|\s+$/g,"")}else a.className=b}return a},xb=function(a,b){if(!a||1!==a.nodeType)return a;if(a.classList)return a.classList.contains(b)&&a.classList.remove(b),a;if("string"==typeof b&&b){var c=b.split(/\s+/);if(1===a.nodeType&&a.className){for(var d=(" "+a.className+" ").replace(/[\n\t]/g," "),e=0,f=c.length;f>e;e++)d=d.replace(" "+c[e]+" "," ");a.className=d.replace(/^\s+|\s+$/g,"")}}return a},yb=function(a,b){var c=e.getComputedStyle(a,null).getPropertyValue(b);return"cursor"!==b||c&&"auto"!==c||"A"!==a.nodeName?c:"pointer"},zb=function(){var a,b,c,d=1;return"function"==typeof f.body.getBoundingClientRect&&(a=f.body.getBoundingClientRect(),b=a.right-a.left,c=f.body.offsetWidth,d=o(b/c*100)/100),d},Ab=function(a){var b={left:0,top:0,width:0,height:0};if(a.getBoundingClientRect){var c,d,g,h=a.getBoundingClientRect();"pageXOffset"in e&&"pageYOffset"in e?(c=e.pageXOffset,d=e.pageYOffset):(g=zb(),c=o(f.documentElement.scrollLeft/g),d=o(f.documentElement.scrollTop/g));var i=f.documentElement.clientLeft||0,j=f.documentElement.clientTop||0;b.left=h.left+c-i,b.top=h.top+d-j,b.width="width"in h?h.width:h.right-h.left,b.height="height"in h?h.height:h.bottom-h.top}return b},Bb=function(){var a;if(c&&(a=mb(I.bridge))){var b=Ab(c);w(a.style,{width:b.width+"px",height:b.height+"px",top:b.top+"px",left:b.left+"px",zIndex:""+Db(O.zIndex)})}},Cb=function(a){I.ready===!0&&(I.bridge&&"function"==typeof I.bridge.setHandCursor?I.bridge.setHandCursor(a):I.ready=!1)},Db=function(a){if(/^(?:auto|inherit)$/.test(a))return a;var b;return"number"!=typeof a||n(a)?"string"==typeof a&&(b=Db(l(a,10))):b=a,"number"==typeof b?b:"auto"},Eb=function(a){function b(a){var b=a.match(/[\d]+/g);return b.length=3,b.join(".")}function c(a){return!!a&&(a=a.toLowerCase())&&(/^(pepflashplayer\.dll|libpepflashplayer\.so|pepperflashplayer\.plugin)$/.test(a)||"chrome.plugin"===a.slice(-13))}function d(a){a&&(i=!0,a.version&&(l=b(a.version)),!l&&a.description&&(l=b(a.description)),a.filename&&(k=c(a.filename)))}var e,f,h,i=!1,j=!1,k=!1,l="";if(g.plugins&&g.plugins.length)e=g.plugins["Shockwave Flash"],d(e),g.plugins["Shockwave Flash 2.0"]&&(i=!0,l="2.0.0.11");else if(g.mimeTypes&&g.mimeTypes.length)h=g.mimeTypes["application/x-shockwave-flash"],e=h&&h.enabledPlugin,d(e);else if("undefined"!=typeof a){j=!0;try{f=new a("ShockwaveFlash.ShockwaveFlash.7"),i=!0,l=b(f.GetVariable("$version"))}catch(n){try{f=new a("ShockwaveFlash.ShockwaveFlash.6"),i=!0,l="6.0.21"}catch(o){try{f=new a("ShockwaveFlash.ShockwaveFlash"),i=!0,l=b(f.GetVariable("$version"))}catch(p){j=!1}}}}I.disabled=i!==!0,I.outdated=l&&m(l)<m(J),I.version=l||"0.0.0",I.pluginType=k?"pepper":j?"activex":i?"netscape":"unknown"};Eb(j);var Fb=function(){return this instanceof Fb?void("function"==typeof Fb._createClient&&Fb._createClient.apply(this,v(arguments))):new Fb};r(Fb,"version",{value:"2.1.6",writable:!1,configurable:!0,enumerable:!0}),Fb.config=function(){return P.apply(this,v(arguments))},Fb.state=function(){return Q.apply(this,v(arguments))},Fb.isFlashUnusable=function(){return R.apply(this,v(arguments))},Fb.on=function(){return S.apply(this,v(arguments))},Fb.off=function(){return T.apply(this,v(arguments))},Fb.handlers=function(){return U.apply(this,v(arguments))},Fb.emit=function(){return V.apply(this,v(arguments))},Fb.create=function(){return W.apply(this,v(arguments))},Fb.destroy=function(){return X.apply(this,v(arguments))},Fb.setData=function(){return Y.apply(this,v(arguments))},Fb.clearData=function(){return Z.apply(this,v(arguments))},Fb.getData=function(){return $.apply(this,v(arguments))},Fb.focus=Fb.activate=function(){return _.apply(this,v(arguments))},Fb.blur=Fb.deactivate=function(){return ab.apply(this,v(arguments))},Fb.activeElement=function(){return bb.apply(this,v(arguments))};var Gb=0,Hb={},Ib=0,Jb={},Kb={};w(O,{autoActivate:!0});var Lb=function(a){var b=this;b.id=""+Gb++,Hb[b.id]={instance:b,elements:[],handlers:{}},a&&b.clip(a),Fb.on("*",function(a){return b.emit(a)}),Fb.on("destroy",function(){b.destroy()}),Fb.create()},Mb=function(a,b){var c,d,e,f={},g=Hb[this.id]&&Hb[this.id].handlers;if("string"==typeof a&&a)e=a.toLowerCase().split(/\s+/);else if("object"==typeof a&&a&&"undefined"==typeof b)for(c in a)s.call(a,c)&&"string"==typeof c&&c&&"function"==typeof a[c]&&this.on(c,a[c]);if(e&&e.length){for(c=0,d=e.length;d>c;c++)a=e[c].replace(/^on/,""),f[a]=!0,g[a]||(g[a]=[]),g[a].push(b);if(f.ready&&I.ready&&this.emit({type:"ready",client:this}),f.error){var h=["disabled","outdated","unavailable","deactivated","overdue"];for(c=0,d=h.length;d>c;c++)if(I[h[c]]){this.emit({type:"error",name:"flash-"+h[c],client:this});break}}}return this},Nb=function(a,b){var c,d,e,f,g,h=Hb[this.id]&&Hb[this.id].handlers;if(0===arguments.length)f=q(h);else if("string"==typeof a&&a)f=a.split(/\s+/);else if("object"==typeof a&&a&&"undefined"==typeof b)for(c in a)s.call(a,c)&&"string"==typeof c&&c&&"function"==typeof a[c]&&this.off(c,a[c]);if(f&&f.length)for(c=0,d=f.length;d>c;c++)if(a=f[c].toLowerCase().replace(/^on/,""),g=h[a],g&&g.length)if(b)for(e=g.indexOf(b);-1!==e;)g.splice(e,1),e=g.indexOf(b,e);else g.length=0;return this},Ob=function(a){var b=null,c=Hb[this.id]&&Hb[this.id].handlers;return c&&(b="string"==typeof a&&a?c[a]?c[a].slice(0):[]:x(c)),b},Pb=function(a){if(Ub.call(this,a)){"object"==typeof a&&a&&"string"==typeof a.type&&a.type&&(a=w({},a));var b=w({},db(a),{client:this});Vb.call(this,b)}return this},Qb=function(a){a=Wb(a);for(var b=0;b<a.length;b++)if(s.call(a,b)&&a[b]&&1===a[b].nodeType){a[b].zcClippingId?-1===Jb[a[b].zcClippingId].indexOf(this.id)&&Jb[a[b].zcClippingId].push(this.id):(a[b].zcClippingId="zcClippingId_"+Ib++,Jb[a[b].zcClippingId]=[this.id],O.autoActivate===!0&&Xb(a[b]));var c=Hb[this.id]&&Hb[this.id].elements;-1===c.indexOf(a[b])&&c.push(a[b])}return this},Rb=function(a){var b=Hb[this.id];if(!b)return this;var c,d=b.elements;a="undefined"==typeof a?d.slice(0):Wb(a);for(var e=a.length;e--;)if(s.call(a,e)&&a[e]&&1===a[e].nodeType){for(c=0;-1!==(c=d.indexOf(a[e],c));)d.splice(c,1);var f=Jb[a[e].zcClippingId];if(f){for(c=0;-1!==(c=f.indexOf(this.id,c));)f.splice(c,1);0===f.length&&(O.autoActivate===!0&&Yb(a[e]),delete a[e].zcClippingId)}}return this},Sb=function(){var a=Hb[this.id];return a&&a.elements?a.elements.slice(0):[]},Tb=function(){this.unclip(),this.off(),delete Hb[this.id]},Ub=function(a){if(!a||!a.type)return!1;if(a.client&&a.client!==this)return!1;var b=Hb[this.id]&&Hb[this.id].elements,c=!!b&&b.length>0,d=!a.target||c&&-1!==b.indexOf(a.target),e=a.relatedTarget&&c&&-1!==b.indexOf(a.relatedTarget),f=a.client&&a.client===this;return d||e||f?!0:!1},Vb=function(a){if("object"==typeof a&&a&&a.type){var b=gb(a),c=Hb[this.id]&&Hb[this.id].handlers["*"]||[],d=Hb[this.id]&&Hb[this.id].handlers[a.type]||[],f=c.concat(d);if(f&&f.length){var g,h,i,j,k,l=this;for(g=0,h=f.length;h>g;g++)i=f[g],j=l,"string"==typeof i&&"function"==typeof e[i]&&(i=e[i]),"object"==typeof i&&i&&"function"==typeof i.handleEvent&&(j=i,i=i.handleEvent),"function"==typeof i&&(k=w({},a),hb(i,j,[k],b))}return this}},Wb=function(a){return"string"==typeof a&&(a=[]),"number"!=typeof a.length?[a]:a},Xb=function(a){if(a&&1===a.nodeType){var b=function(a){(a||(a=e.event))&&("js"!==a._source&&(a.stopImmediatePropagation(),a.preventDefault()),delete a._source)},c=function(c){(c||(c=e.event))&&(b(c),Fb.focus(a))};a.addEventListener("mouseover",c,!1),a.addEventListener("mouseout",b,!1),a.addEventListener("mouseenter",b,!1),a.addEventListener("mouseleave",b,!1),a.addEventListener("mousemove",b,!1),Kb[a.zcClippingId]={mouseover:c,mouseout:b,mouseenter:b,mouseleave:b,mousemove:b}}},Yb=function(a){if(a&&1===a.nodeType){var b=Kb[a.zcClippingId];if("object"==typeof b&&b){for(var c,d,e=["move","leave","enter","out","over"],f=0,g=e.length;g>f;f++)c="mouse"+e[f],d=b[c],"function"==typeof d&&a.removeEventListener(c,d,!1);delete Kb[a.zcClippingId]}}};Fb._createClient=function(){Lb.apply(this,v(arguments))},Fb.prototype.on=function(){return Mb.apply(this,v(arguments))},Fb.prototype.off=function(){return Nb.apply(this,v(arguments))},Fb.prototype.handlers=function(){return Ob.apply(this,v(arguments))},Fb.prototype.emit=function(){return Pb.apply(this,v(arguments))},Fb.prototype.clip=function(){return Qb.apply(this,v(arguments))},Fb.prototype.unclip=function(){return Rb.apply(this,v(arguments))},Fb.prototype.elements=function(){return Sb.apply(this,v(arguments))},Fb.prototype.destroy=function(){return Tb.apply(this,v(arguments))},Fb.prototype.setText=function(a){return Fb.setData("text/plain",a),this},Fb.prototype.setHtml=function(a){return Fb.setData("text/html",a),this},Fb.prototype.setRichText=function(a){return Fb.setData("application/rtf",a),this},Fb.prototype.setData=function(){return Fb.setData.apply(this,v(arguments)),this},Fb.prototype.clearData=function(){return Fb.clearData.apply(this,v(arguments)),this},Fb.prototype.getData=function(){return Fb.getData.apply(this,v(arguments))},"function"==typeof define&&define.amd?define(function(){return Fb}):"object"==typeof module&&module&&"object"==typeof module.exports&&module.exports?module.exports=Fb:a.ZeroClipboard=Fb}(function(){return this||window}());
diff --git a/doc/_themes/odoodoc/static/zeroclipboard-2.1.6/ZeroClipboard.swf b/doc/_themes/odoodoc/static/zeroclipboard-2.1.6/ZeroClipboard.swf
deleted file mode 100644
index d4e2561b366..00000000000
--- a/doc/_themes/odoodoc/static/zeroclipboard-2.1.6/ZeroClipboard.swf
+++ /dev/null
Binary files differ
diff --git a/doc/api_integration.rst b/doc/api_integration.rst
index 6ee6871ff9f..ffcf3f9a029 100644
--- a/doc/api_integration.rst
+++ b/doc/api_integration.rst
@@ -1,8 +1,8 @@
:classes: stripe
-===========
-Web Service
-===========
+===============
+Web Service API
+===============
Odoo is mostly extended internally via modules, but much of its features and
all of its data is also available from the outside for external analysis or
diff --git a/doc/howtos/backend.rst b/doc/howtos/backend.rst
index fcbc10e3721..0ac7ab8060d 100644
--- a/doc/howtos/backend.rst
+++ b/doc/howtos/backend.rst
@@ -74,31 +74,9 @@ option.
most command-line options can also be set using :ref:`a configuration
file <reference/cmdline/config>`
-An Odoo module is declared by its :ref:`manifest <reference/module/manifest>`. It
-is mandatory and contains a single python dictionary declaring various
-metadata for the module: the module's name and description, list of Odoo
-modules required for this one to work properly, references to data files, …
-
-The manifest's general structure is::
-
- {
- 'name': "MyModule",
- 'version': '1.0',
- 'depends': ['base'],
- 'author': "Author Name",
- 'category': 'Category',
- 'description': """
- Description text
- """,
- # data files always loaded at installation
- 'data': [
- 'mymodule_view.xml',
- ],
- # data files containing optionally loaded demonstration data
- 'demo': [
- 'demo_data.xml',
- ],
- }
+An Odoo module is declared by its :ref:`manifest <reference/module/manifest>`.
+See the :ref:`manifest documentation <reference/module/manifest>` information
+about it.
A module is also a
`Python package <http://docs.python.org/2/tutorial/modules.html#packages>`_
@@ -108,15 +86,15 @@ files in the module.
For instance, if the module has a single ``mymodule.py`` file ``__init__.py``
might contain::
- import mymodule
+ from . import mymodule
-Fortunately, there is a mechanism to help you set up an module. The command
-``odoo.py`` has a subcommand :ref:`scaffold <reference/cmdline/scaffold>` to
-create an empty module:
+Odoo provides a mechanism to help set up a new module, :ref:`odoo.py
+<reference/cmdline/server>` has a subcommand :ref:`scaffold
+<reference/cmdline/scaffold>` to create an empty module:
-.. code:: bash
+.. code-block:: console
- odoo.py scaffold <module name> <where to put it>
+ $ odoo.py scaffold <module name> <where to put it>
The command creates a subdirectory for your module, and automatically creates a
bunch of standard files for a module. Most of them simply contain commented code
diff --git a/doc/howtos/backend/exercise-creation b/doc/howtos/backend/exercise-creation
index 4b780bddbb7..353556a43b5 100644
--- a/doc/howtos/backend/exercise-creation
+++ b/doc/howtos/backend/exercise-creation
@@ -46,8 +46,8 @@ Index: addons/openacademy/__init__.py
+++ addons/openacademy/__init__.py 2014-08-26 17:25:49.791783523 +0200
@@ -0,0 +1,3 @@
+# -*- coding: utf-8 -*-
-+import controllers
-+import models
++from . import controllers
++from . import models
Index: addons/openacademy/controllers.py
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
diff --git a/doc/howtos/backend/exercise-dashboard b/doc/howtos/backend/exercise-dashboard
index 4e3e563f450..bf175edc7d3 100644
--- a/doc/howtos/backend/exercise-dashboard
+++ b/doc/howtos/backend/exercise-dashboard
@@ -54,6 +54,7 @@ Index: addons/openacademy/views/session_board.xml
+ <record model="ir.ui.view" id="board_session_form">
+ <field name="name">Session Dashboard Form</field>
+ <field name="model">board.board</field>
++ <field name="type">form</field>
+ <field name="arch" type="xml">
+ <form string="Session Dashboard">
+ <board style="2-1">
@@ -89,6 +90,6 @@ Index: addons/openacademy/views/session_board.xml
+ name="Session Dashboard" parent="base.menu_reporting_dashboard"
+ action="open_board_session"
+ sequence="1"
-+ id="menu_board_session"/>
++ id="menu_board_session" icon="terp-graph"/>
+ </data>
+</openerp>
diff --git a/doc/howtos/backend/exercise-model-inheritance b/doc/howtos/backend/exercise-model-inheritance
index ddc84ea6886..a3529403d55 100644
--- a/doc/howtos/backend/exercise-model-inheritance
+++ b/doc/howtos/backend/exercise-model-inheritance
@@ -7,9 +7,9 @@ Index: addons/openacademy/__init__.py
+++ addons/openacademy/__init__.py 2014-08-26 17:26:01.219783354 +0200
@@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
- import controllers
- import models
-+import partner
+ from . import controllers
+ from . import models
++from . import partner
Index: addons/openacademy/__openerp__.py
===================================================================
--- addons.orig/openacademy/__openerp__.py 2014-08-26 17:26:01.227783353 +0200
diff --git a/doc/howtos/backend/exercise-wizard b/doc/howtos/backend/exercise-wizard
index 1605185bf05..906cdef181b 100644
--- a/doc/howtos/backend/exercise-wizard
+++ b/doc/howtos/backend/exercise-wizard
@@ -3,10 +3,10 @@ Index: addons/openacademy/__init__.py
--- addons.orig/openacademy/__init__.py 2014-08-27 14:19:23.023111330 +0200
+++ addons/openacademy/__init__.py 2014-08-27 14:22:25.043108628 +0200
@@ -2,3 +2,4 @@
- import controllers
- import models
- import partner
-+import wizard
+ from . import controllers
+ from . import models
+ from . import partner
++from . import wizard
Index: addons/openacademy/wizard.py
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
diff --git a/doc/howtos/themes.rst b/doc/howtos/themes.rst
index 2c6eef2d405..dbc59f6392d 100644
--- a/doc/howtos/themes.rst
+++ b/doc/howtos/themes.rst
@@ -30,7 +30,7 @@ with the structure:
|-- pages.xml
`-- snippets.xml
-``static/styles`` contains your stylesheet(s), ``views`` contains the various
+``static/style`` contains your stylesheet(s), ``views`` contains the various
XML files describing the theme and theme features to Odoo.
Static Page
@@ -51,7 +51,12 @@ copy paste the lines::
</t>
</template>
-Refresh the page and feel the hit.
+Comment the lines about ``options.xml`` and ``pages.xml`` in ``__openerp__.py``.
+
+Run the server and update the theme (``./odoo.py -u dummy_theme``), then
+install the theme in the settings menu.
+
+Go to ``http://localhost:8069/page/hello`` feel the hit.
Editing content on a page
'''''''''''''''''''''''''
@@ -104,14 +109,25 @@ modify these lines as below:
.. code-block:: css
- .h1 {
+ h1 {
color: #215487;
}
- .span {
+ span {
border: 2px solid black;
background-color: #eee;
}
+Compile your file (http://lesscss.org/usage/#command-line-usage) to get the
+``custom.css`` file.
+
+Add this asset to your template in ``page.xml``::
+
+ <template id="dummy_theme_asset" name="website assete for Dummy theme" inherit_id="website.theme">
+ <xpath expr="." position="inside">
+ <link rel="stylesheet" href="/dummy_theme/static/style/custom.css"/>
+ </xpath>
+ </template>
+
Refresh the page and feel the hit.
Get the most of the dom
@@ -267,9 +283,9 @@ Adding images to your snippet
You can easely add images in your snippets simply by setting up css
backgrounds images.
-In ``odoo/addons/theme_dummy/static/`` create a new folder and name it
-``img``. Put your images there, in sub-folders if needed. Open
-:file:`odoo/addons/theme_dummy/static/style/custom.less`, add these lines
+Put your images in ``odoo/addons/theme_dummy/static/img``, or in sub-folders
+if needed. Open :file:`odoo/addons/theme_dummy/static/style/custom.less`, add
+these lines
.. code-block:: css
@@ -279,28 +295,20 @@ In ``odoo/addons/theme_dummy/static/`` create a new folder and name it
@img-02: url("../img/img-girl.png");
.dummy-girl { background-image: @img-02; }
+Add also the ``width`` and the ``height`` css attributes to theses new classes.
+
In :file:`odoo/addons/theme_dummy/views/pages.xml` change the correspondant
lines as below::
- <section>
- <div class="container">
- <div class="row dummy-bg">
- <div class="alert alert-primary" role="alert">
- <a href="#" class="alert-link">...</a>
- </div>
- <div class="col-md-6">
- <h2>BLUE it!</h2>
- <div class="dummy-boy">
- </div>
- </div>
- <div class="col-md-6">
- <h2>GREEN THAT!</h2>
- <div class="dummy-girl">
- </div>
- </div>
- </div>
- </div>
- </section>
+ <div class="row">
+ <div class="col-md-12 text-center mt32 mb32">
+ <h2 class="options_simple_snippet">A great Title, prmize</h2>
+ <h3 class="text-muted">And a great subtilte too</h3>
+ <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. </p>
+ <div class="dummy-boy"></div>
+ <div class="dummy-girl"></div>
+ </div>
+ </div>
Your new snippet is now ready to use. Just drag and drop it on your page to
see it in action.
@@ -329,9 +337,12 @@ Explain xpath
.. TODO:: syntax not correct (see website examples)
-Your option menu is now correctly set in the database, you can create an new dropdown menu.
+Your option menu is now correctly set in the database, you can create an new
+dropdown menu.
+
+Let's say yout want three options which will change the text color and the
+background.
-Let's say yout want three options which will change the text color and the background.
In option.xml, add these lines inside the xpath::
<li data-check_class="text-purple"><a>YOUR OPTION 1</a></li>
diff --git a/doc/reference/actions.rst b/doc/reference/actions.rst
index 8e31d58b36c..fe2dfb6d68c 100644
--- a/doc/reference/actions.rst
+++ b/doc/reference/actions.rst
@@ -204,6 +204,7 @@ field:
.. code-block:: xml
<record model="ir.actions.server" id="print_instance">
+ <field name="name">Res Partner Server Action</field>
<field name="model_id" ref="model_res_partner"/>
<field name="code">
print self, object
@@ -218,6 +219,7 @@ field:
.. code-block:: xml
<record model="ir.actions.server" id="print_instance">
+ <field name="name">Res Partner Server Action</field>
<field name="model_id" ref="model_res_partner"/>
<field name="code">
if object.some_condition():
diff --git a/doc/reference/cmdline.rst b/doc/reference/cmdline.rst
index 269f62ed2eb..280cd079622 100644
--- a/doc/reference/cmdline.rst
+++ b/doc/reference/cmdline.rst
@@ -249,6 +249,35 @@ customize the amout of logging output
enables DEBUG logging of SQL querying, equivalent to
``--log-handler=openerp.sql_db:DEBUG``
+.. option:: --log-level <level>
+
+ Shortcut to more easily set predefined levels on specific loggers. "real"
+ levels (``critical``, ``error``, ``warn``, ``debug``) are set on the
+ ``openerp`` and ``werkzeug`` loggers (except for ``debug`` which is only
+ set on ``openerp``).
+
+ Odoo also provides debugging pseudo-levels which apply to different sets
+ of loggers:
+
+ ``debug_sql``
+ sets the SQL logger to ``debug``
+
+ equivalent to ``--log-sql``
+ ``debug_rpc``
+ sets the ``openerp`` and HTTP request loggers to ``debug``
+
+ equivalent to ``--log-level debug --log-request``
+ ``debug_rpc_answer``
+ sets the ``openerp`` and HTTP request and response loggers to
+ ``debug``
+
+ equivalent to ``--log-level debug --log-request --log-response``
+
+ .. note::
+
+ In case of conflict between :option:`--log-level` and
+ :option:`--log-handler`, the latter is used
+
.. _reference/cmdline/scaffold:
Scaffolding
diff --git a/doc/reference/module.rst b/doc/reference/module.rst
index 14e7847f1da..5dd93ca2cf6 100644
--- a/doc/reference/module.rst
+++ b/doc/reference/module.rst
@@ -15,6 +15,27 @@ and to specify a number of module metadata.
It is a file called ``__openerp__.py`` and contains a single Python
dictionary, each dictionary key specifying a module metadatum.
+::
+
+ {
+ 'name': "A Module",
+ 'version': '1.0',
+ 'depends': ['base'],
+ 'author': "Author Name",
+ 'category': 'Category',
+ 'description': """
+ Description text
+ """,
+ # data files always loaded at installation
+ 'data': [
+ 'mymodule_view.xml',
+ ],
+ # data files containing optionally loaded demonstration data
+ 'demo': [
+ 'demo_data.xml',
+ ],
+ }
+
Available manifest fields are:
``name`` (``str``, required)
diff --git a/doc/reference/qweb.rst b/doc/reference/qweb.rst
index 08170da0d23..a7564ded394 100644
--- a/doc/reference/qweb.rst
+++ b/doc/reference/qweb.rst
@@ -418,7 +418,7 @@ the name of the template to alter as parameter.
The alteration is then performed with any number of ``t-jquery``
sub-directives::
- <t t-extends="base.template">
+ <t t-extend="base.template">
<t t-jquery="ul" t-operation="append">
<li>new element</li>
</t>
diff --git a/doc/reference/testing.rst b/doc/reference/testing.rst
index 2676c2b4084..e1c78919f15 100644
--- a/doc/reference/testing.rst
+++ b/doc/reference/testing.rst
@@ -24,8 +24,16 @@ and ``__init__.py`` contains::
from . import test_foo, test_bar
-.. note:: test modules which are not imported from ``tests/__init__.py`` will
- not be run
+.. warning::
+
+ test modules which are not imported from ``tests/__init__.py`` will not be
+ run
+
+.. versionchanged:: 8.0
+
+ previously, the test runner would only run modules added to two lists
+ ``fast_suite`` and ``checks`` in ``tests/__init__.py``. In 8.0 it will
+ run all imported modules
The test runner will simply run any test case, as described in the official
`unittest documentation`_, but Odoo provides a number of utilities and helpers
@@ -46,8 +54,8 @@ been installed, and not run right after the module installation:
.. autofunction:: openerp.tests.common.post_install
The most common situation is to use
-:class:`~openerp.tests.common.TransactionCase` and test a property of a of a
-model in each method::
+:class:`~openerp.tests.common.TransactionCase` and test a property of a model
+in each method::
class TestModelA(common.TransactionCase):
def test_some_action(self):
@@ -67,7 +75,7 @@ Tests are automatically run when installing or updating modules if
Odoo server.
As of Odoo 8, running tests outside of the install/update cycle is not
-
+supported.
.. _unittest2: http://pypi.python.org/pypi/unittest2
.. _unittest documentation: https://docs.python.org/2/library/unittest.html
diff --git a/doc/setup/install.rst b/doc/setup/install.rst
index f4758c1281f..7fb83ea4667 100644
--- a/doc/setup/install.rst
+++ b/doc/setup/install.rst
@@ -33,21 +33,19 @@ This documents attempts to describe most of the installation options.
Good for developing modules, can be used as base for production
deployment.
-:ref:`setup/install/vcs`
- Mostly has the same strengths and weaknesses as the
- :ref:`setup/install/source`, but allows (technically) simpler
- switching between versions of Odoo, as well as more structured patching
- and customisations of Odoo itself (not through custom modules): with a
- standard :ref:`setup/install/source`, a custom solution has to be
- implemented to keep track of patches applied to Odoo (e.g. Quilt_). With
- a VCS checkout, these changes can be implemented as standard Git revisions
- or a custom Git branch, and can more easily be contributed back to the
- main project.
+
+ The source code can be obtained by downloading a tarball or using git.
+ Using git makes it easier to update, switch between multiple versions
+ (including the current development version) or contribute.
+`docker image <https://registry.hub.docker.com/_/odoo/>`_
+ if you usually use docker_ for development or deployment, an official
+ docker_ base image is available, see the image's help document for more
+ information
.. _setup/install/demo:
-Demo_
-=====
+Demo
+====
To simply get a quick idea of Odoo, demo_ instances are available. They are
shared instances which only live for a few hours, and can be used to browse
@@ -57,8 +55,8 @@ Demo_ instances require no local installation, just a web browser.
.. _setup/install/saas:
-SaaS_
-=====
+SaaS
+====
Odoo's SaaS_ provides private instances and starts out free. It can be used to
discover and test Odoo and do non-code customizations without having to
@@ -72,11 +70,8 @@ browser is sufficient.
Packaged installers
===================
-.. Odoo provides packaged installers for Windows, deb-based distributions
-.. (Debian, Ubuntu, …) and RPM-based distributions (Fedora, CentOS, RHEL, …).
-
-Odoo provides packaged installers for Windows and deb-based distributions
-(Debian, Ubuntu, …).
+Odoo provides packaged installers for Windows, deb-based distributions
+(Debian, Ubuntu, …) and RPM-based distributions (Fedora, CentOS, RHEL, …).
These packages automatically set up all dependencies, but may be difficult to
keep up-to-date.
@@ -84,6 +79,33 @@ keep up-to-date.
Official packages with all relevant dependency requirements are available on
https://nightly.odoo.com.
+Windows
+-------
+
+* download https://nightly.odoo.com/8.0/nightly/exe/odoo_8.0.latest.exe
+* run the downloaded file
+
+ .. warning:: on Windows 8, you may see a warning titled "Windows protected
+ your PC". Click :guilabel:`More Info` then
+ :guilabel:`Run anyway`
+
+* Accept the UAC_ prompt
+* Go through the various installation steps
+
+Odoo will automatically be started at the end of the installation.
+
+Configuration
+'''''''''''''
+
+The :ref:`configuration file <reference/cmdline/config>` can be found at
+:file:`{%PROGRAMFILES%}\\Odoo 8.0-{id}\\server\\openerp-server.conf`.
+
+The configuration file can be edited to connect to a remote Postgresql, edit
+file locations or set a dbfilter.
+
+To reload the configuration file, restart the Odoo service via
+:menuselection:`Services --> odoo server`.
+
Deb
---
@@ -99,10 +121,6 @@ commands as root:
This will automatically install all dependencies, install Odoo itself as a
daemon and automatically start it.
-.. postgres-server apparently automatically installed due to being a
- recommended package, maybe install it explicitly for the purpose of this
- document?
-
.. danger:: to print PDF reports, you must install wkhtmltopdf_ yourself:
the version of wkhtmltopdf_ available in debian repositories does
not support headers and footers so it can not be installed
@@ -167,32 +185,6 @@ When the configuration file is edited, Odoo must be restarted via SystemD:
$ sudo systemctl restart odoo
-Windows
--------
-
-* download https://nightly.odoo.com/8.0/nightly/exe/odoo_8.0.latest.exe
-* run the downloaded file
-
- .. warning:: on Windows 8, you may see a warning titled "Windows protected
- your PC". Click :guilabel:`More Info` then
- :guilabel:`Run anyway`
-
-* Accept the UAC_ prompt
-* Go through the various installation steps
-
-Odoo will automatically be started at the end of the installation.
-
-Configuration
-'''''''''''''
-
-The :ref:`configuration file <reference/cmdline/config>` can be found at
-:file:`{%PROGRAMFILES%}\\Odoo 8.0-{id}\\server\\openerp-server.conf`.
-
-The configuration file can be edited to connect to a remote Postgresql, edit
-file locations or set a dbfilter.
-
-To reload the configuration file, restart the Odoo service via
-:menuselection:`Services --> odoo server`.
.. _setup/install/source:
@@ -214,77 +206,168 @@ edit a configuration file.
Finally it provides greater control over the system's set up, and allows more
easily keeping (and running) multiple versions of Odoo side-by-side.
-The Odoo source can be downloaded from
-https://nightly.odoo.com/8.0/nightly/src/odoo_8.0-latest.tar.gz
+There are two way to get the odoo source source zip or git.
+
+* Odoo zip can be downloaded from
+ https://nightly.odoo.com/8.0/nightly/src/odoo_8.0.latest.zip, the zip file
+ then needs to be uncompressed to use its content
+
+* git allows simpler update and easier switching between differents versions
+ of Odoo. It also simplifies maintaining non-module patches and
+ contributions. The primary drawback of git is that it is significantly
+ larger than a tarball as it contains the entire history of the Odoo project.
-.. warning:: Windows does not handle .tar.gz archives natively, you will have
- to download and install `7-Zip <http://www.7-zip.org>`_ to
- decompress the archive
+ The git repository is https://github.com/odoo/odoo.git.
+
+ Downloading it requires a `a git client <http://git-scm.com/download/>`_
+ (which may be available via your distribution on linux) and can be performed
+ using the following command:
+
+ .. code-block:: console
+
+ $ git clone https://github.com/odoo/odoo.git
Installing dependencies
-----------------------
-Source installation requires manually installing dependencies, be them native
-dependencies or Python libraries:
+Source installation requires manually installing dependencies:
+
+* Python 2.7.
+
+ - on Linux and OS X, included by default
+ - on Windows, use `the official Python 2.7.9 installer
+ <https://www.python.org/downloads/windows/>`_.
+
+ .. warning:: select "add python.exe to Path" during installation, and
+ reboot afterwards to ensure the :envvar:`PATH` is updated
-* Python, should be preinstalled on most systems. On Windows, use `the
- official Python 2.7 installer <https://www.python.org/downloads/windows/>`_.
+ .. note:: if Python is already installed, make sure it is 2.7.9, previous
+ versions are less convenient and 3.x versions are not compatible
+ with Odoo
-* PostgreSQL, if you want the database to be on the same machine as Odoo
- (simplest and default)
+* PostgreSQL, to use a local database
+
+ After installation you will need to create a postgres user: by default the
+ only user is ``postgres``, and Odoo forbids connecting as ``postgres``.
+
+ - on Linux, use your distribution's package, then create a postgres user
+ named like your login:
+
+ .. code-block:: console
+
+ $ sudo su - postgres -c "createuser -s $USER"
+
+ Because the role login is the same as your unix login unix sockets can be
+ use without a password.
- - on Linux, use your distribution's package
- - on Windows, use `the official installer`_
- on OS X, `postgres.app <http://postgresapp.com>`_ is the simplest way to
- get started
+ get started, then create a postgres user as on Linux
+
+ - on Windows, use `PostgreSQL for windows`_ then
- .. todo:: create new role?
+ - add PostgreSQL's ``bin`` directory (default:
+ ``C:\Program Files\PostgreSQL\9.4\bin``) to your :envvar:`PATH`
+ - create a postgres user with a password using the pg admin gui: open
+ pgAdminIII, double-click the server to create a connection, select
+ :menuselection:`Edit --> New Object --> New Login Role`, enter the
+ usename in the :guilabel:`Role Name` field (e.g. ``odoo``), then open
+ the :guilabel:`Definition` tab and enter the password (e.g. ``odoo``),
+ then click :guilabel:`OK`.
+
+ The user and password must be passed to Odoo using either the
+ :option:`-w <odoo.py -w>` and :option:`-r <odoo.py -r>` options or
+ :ref:`the configuration file <reference/cmdline/config>`
+
+* Python dependencies listed in the :file:`requirements.txt` file.
+
+ - on Linux, python dependencies may be installable with the system's package
+ manager or using pip.
+
+ For libraries using native code (Pillow, lxml, greenlet, gevent, psycopg2,
+ ldap) it may be necessary to install development tools and native
+ dependencies before pip is able to install the dependencies themselves.
+ These are available in ``-dev`` or ``-devel`` packages for Python,
+ Postgres, libxml2, libxslt, libevent and libsasl2. Then the Python
+ dependecies can themselves be installed:
+
+ .. code-block:: console
-* the :file:`requirements.txt` file in the source lists all the Python
- dependencies
+ $ pip install -r requirements.txt
- - for Windows, http://www.lfd.uci.edu/~gohlke/pythonlibs/ provides a number
- of libraries, for both pure-python and native, packaged as installers
- - dependencies may be installable with the system's package manager
- - pip_ can take the requirements file directly and install everything listed
- in it, either globally or within a `virtual environment`_:
+ - on OS X, you will need to install the Command Line Tools
+ (``xcode-select --install``) then download and install a package manager
+ of your choice (homebrew_, macports_) to install non-Python dependencies.
+ pip can then be used to install the Python dependencies as on Linux:
.. code-block:: console
- $ pip install -r path/to/requirements.txt
+ $ pip install -r requirements.txt
- For libraries using native code (Pillow, lxml, greenlet, gevent, psycopg2)
- it may be necessary to install development tools and native dependencies
- before pip is able to install the dependencies themselves:
+ - on Windows you need to install some of the dependencies manually, tweak the
+ requirements.txt file, then run pip to install the remaning ones.
- * Linux distributions generally require ``-dev`` or ``-devel`` packages
- for Python, Postgres, libxml2, libxslt and libevent
- * for OSX, install the Command Line Tools (``xcode-select --install``) the
- native dependency via your preferred package manager (macports_,
- homebrew_)
- * for Windows
+ Install ``psycopg`` using the installer here
+ http://www.stickpeople.com/projects/python/win-psycopg/
- .. danger:: you will have to remove ``python-ldap`` from the
- requirements file, it can not be installed via pip_ on
- Windows and must be installed as a precompiled binary
+ Then edit the requirements.txt file:
- - install the `Visual C++ Compiler for Python 2.7`_ (and restart)
- - install `PostgreSQL for windows`_ if not already done
- - Add PostgreSQL's ``bin`` directory (default:
- ``C:\Program Files\PostgreSQL\9.3\bin``) to your :envvar:`PATH`
+ - remove ``psycopg2`` as you already have it.
+ - remove the optional ``python-ldap``, ``gevent`` and ``psutil`` because
+ they require compilation.
+ - add ``pypiwin32`` because it's needed under windows.
- ``greenlet``, ``Pillow`` and ``lxml`` are available as pre-compiled
- wheels_ and trivially installed by pip_, ``gevent`` only needs the
- compiler to be installable and a local installation ``psycopg2``
+ Then use pip to install install the dependencies using the following
+ command from a cmd.exe prompt (replace ``\YourOdooPath`` by the actual
+ path where you downloaded Odoo):
- .. note:: by default, Python scripts are not on the PATH in windows,
- after installing pip_ add ``C:\Python27\Scripts`` to your
- :envvar:`PATH`
+ .. code-block:: ps1
-.. danger:: whatever the installation method, Odoo on Windows also needs
- pywin32_ which is not listed in the requirements file. It can be
- installed using pip_ with ``pip install pypiwin32``, or manually
- by downloading the official pywin32_ installer and running it.
+ C:\> cd \YourOdooPath
+ C:\YourOdooPath> C:\Python27\Scripts\pip.exe install -r requirements.txt
+
+* *Less CSS* via nodejs
+
+ - on Linux, use your distribution's package manager to install nodejs and
+ npm.
+
+ .. warning::
+
+ In debian wheezy and Ubuntu 13.10 and before you need to install
+ nodejs manually:
+
+ .. code-block:: console
+
+ $ wget -qO- https://deb.nodesource.com/setup | bash -
+ $ apt-get install -y nodejs
+
+ In later debian (>jessie) and ubuntu (>14.04) you may need to add a
+ symlink as npm packages call ``node`` but debian calls the binary
+ ``nodejs``
+
+ .. code-block:: console
+
+ $ apt-get install -y npm
+ $ sudo ln -s /usr/bin/nodejs /usr/bin/node
+
+ Once npm is installed, use it to install less and less-plugin-clean-css:
+
+ .. code-block:: console
+
+ $ sudo npm install -g less less-plugin-clean-css
+
+ - on OS X, install nodejs via your preferred package manager (homebrew_,
+ macports_) then install less and less-plugin-clean-css:
+
+ .. code-block:: console
+
+ $ sudo npm install -g less less-plugin-clean-css
+
+ - on Windows, `install nodejs <http://nodejs.org/download/>`_, reboot (to
+ update the :envvar:`PATH`) and install less and less-plugin-clean-css:
+
+ .. code-block:: ps1
+
+ C:\> npm install -g less less-plugin-clean-css
Running Odoo
------------
@@ -297,33 +380,37 @@ Once all dependencies are set up, Odoo can be launched by running ``odoo.py``.
Common necessary configurations are:
-* PostgreSQL host, port, user and password. Odoo has no defaults beyond
+* PostgreSQL host, port, user and password.
+
+ Odoo has no defaults beyond
`psycopg2's defaults <http://initd.org/psycopg/docs/module.html>`_: connects
- over a UNIX socket on port 5432 with the current user and no password.
+ over a UNIX socket on port 5432 with the current user and no password. By
+ default this should work on Linux and OS X, but it *will not work* on
+ windows as it does not support UNIX sockets.
- This may require creating new PostgreSQL roles, by default the only user is
- ``postgres``, and Odoo forbids connecting as ``postgres``.
* Custom addons path beyond the defaults, to load your own modules
-.. _setup/install/vcs:
+Under Windows a typical way to execute odoo would be:
+
+.. code-block:: ps1
-VCS Checkout
-============
+ C:\YourOdooPath> python odoo.py -w odoo -r odoo --addons-path=addons,../mymodules --db-filter=mydb$
-The VCS Checkout installation method is similar to
-:ref:`source-based installation <setup/install/source>` in most respect.
+Where ``odoo``, ``odoo`` are the postgresql login and password,
+``../mymodules`` a directory with additional addons and ``mydb`` the default
+db to serve on localhost:8069
+
+Under Unix a typical way to execute odoo would be:
+
+.. code-block:: console
-* Instead of downloading a tarball the Odoo source code is downloaded from
- `the repository`_ using git_
-* This simplifies the development and contributions to Odoo itself
-* This also simplifies maintaining non-module patches on top of the base Odoo
- system
+ $ ./odoo.py --addons-path=addons,../mymodules --db-filter=mydb$
-The primary drawback of the VCS checkout method is that it is significantly
-larger than a :ref:`source install <setup/install/source>` as it contains
-the entire history of the Odoo project.
+Where ``../mymodules`` is a directory with additional addons and ``mydb`` the
+default db to serve on localhost:8069
.. _demo: https://demo.odoo.com
+.. _docker: https://www.docker.com
.. _EPEL: https://fedoraproject.org/wiki/EPEL
.. _PostgreSQL: http://www.postgresql.org
.. _the official installer: