blocked at introducing qweb template, ir.qweb lives in the registry but nodb -> no database
with --db-filter there's a database in the session (kinda) but need to fetch it and manually get the corresponding registry...
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
-extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.viewcode']
+extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.viewcode', 'patchqueue']
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
--- /dev/null
+===================================
+Howto: build a website with OpenERP
+===================================
+
+.. queue:: howto_website/series
+
+.. warning::
+
+ This guide assumes `basic knowledge of python
+ <http://docs.python.org/2/tutorial/>`_.
+
+ This guide assumes :ref:`an OpenERP installed and ready for
+ development <getting_started_installation_source-link>`.
+
+ For production deployment, see the dedicated guides
+ :ref:`using-gunicorn` and :ref:`using-mod-wsgi`.
+
+Minimal website module
+======================
+
+Hello, world!
+-------------
+
+In OpenERP, doing things takes the form of creating modules, and these
+modules customize the behavior of the OpenERP installation. The first
+step is thus to create a module:
+
+.. todo:: code generator in oe?
+
+ * Create empty module (mandatory name, category)
+ * Create controller (parent class?)
+ * Create model (concrete/abstract? Inherit?)
+ * Add field?
+
+* Create a new folder called :file:`academy` in a module directory,
+ inside it create an empty file called :file:`__openerp__.py` with
+ the following content:
+
+ .. patch::
+
+* Create a second file :file:`controllers.py`. This is where the code
+ interacting directly with your web browser will live. For starters,
+ just include the following in it:
+
+ .. patch::
+
+* Finally, create a third file :file:`__init__.py` containing just:
+
+ .. patch::
+
+ This makes :file:`controllers.py` "visible" to openerp (by running
+ the code it holds).
+
+.. todo::
+
+ * instructions for start & install
+ * db handling
+ - if existing db, automatically selected
+ - if no existing db, nodb -> login -> login of first db
+ - dbfilter
+
+Now start your OpenERP server and install your module in it, open a
+web browser and navigate to http://localhost:8069. A page should
+appear with just the words "Hello, world!" on it.
+
+The default response type is HTML (although we only sent some text,
+browsers are pretty good at finding ways to turn stuff into things
+they can display). Let's prettify things a bit: instead of returning
+just a bit of text, we can return a page, and use a tool/library like
+bootstrap_ to get a nicer rendering than the default.
+
+Change the string returned by the ``index`` method to get a more page-ish
+output:
+
+.. patch::
+
+.. note::
+
+ this example requires internet access at all time, as we're
+ accessing a :abbr:`CDN (Content Delivery Network, large distributed
+ networks hosting static files and trying to provide
+ high-performance and high-availability of these files)`-hosted
+ file.
+
+Data input: URL and query
+-------------------------
+
+Being able to build a static page in code is nice, but makes for limited
+usefulness (you could do that with static files in the first place, after all).
+
+But you can also create controllers which use data provided in the access URL,
+for instance so you have a single controller generating multiple pages. Any
+query parameter (``?name=value``) is passed as a parameter to the controller
+function, and is a string.
+
+.. patch::
+
+No validation is performed on query input values, it could be missing
+altogether (if a user accesses ``/tas/`` directly) or it could be incorrectly
+formatted. For this reason, query parameters are generally used to provide
+"options" to a given page, and "required" data tends (when possible) to be
+inserted directly in the URL.
+
+This can be done by adding `converter patterns`_ to the URL in ``@http.route``:
+
+.. patch::
+
+These patterns can perform conversions directly (in this case the conversion
+from a string URL section to a python integer) and will perform a some
+validation (if the ``id`` is not a valid integer, the converter will return
+a ``404 Not Found`` instead of generating a server error when the conversion
+fails).
+
+Templating: better experience in editing
+----------------------------------------
+
+So far we've created HTML output by munging together Python strings using
+string concatenation and formatting. It works, but is not exactly fun to edit
+(and somewhat unsafe to boot) as even advanced text editors have a hard time
+understanding they're dealing with HTML embedded in Python code.
+
+The usual solution is to use templates_, documents with placeholders which
+can be "rendered" to produce final pages (or others). OpenERP lets you use
+any Python templating system you want, but bundles its own
+:doc:`QWeb </06_ir_qweb>` templating system which we'll later see offers
+some useful features.
+
+Let's move our 2 pseudo-templates from inline strings to actual templates:
+
+.. patch::
+
+.. FIXME how can I access a QWeb template from a auth=none controller?
+ explicitly fetch a registry using request.session.db? That's a bit
+ horrendous now innit?
+
+.. todo:: reload/update of module?
+
+.. _bootstrap: http://getbootstrap.com
+
+.. _converter patterns: http://werkzeug.pocoo.org/docs/routing/#rule-format
+
+.. _templates: http://en.wikipedia.org/wiki/Web_template
--- /dev/null
+# HG changeset patch
+# Parent 458a542843918f6899fe64bfe1cead00972ef68a
+
+diff --git a/controllers.py b/controllers.py
+new file mode 100644
+--- /dev/null
++++ b/controllers.py
+@@ -0,0 +1,7 @@
++from openerp import http
++from openerp.addons.web.controllers import main
++
++class Home(main.Home):
++ @http.route('/', auth='none')
++ def index(self):
++ return "Hello, world!"
--- /dev/null
+# HG changeset patch
+# Parent b377930cec8f9445882bb3268f9f5fac71dd8c15
+
+diff --git a/controllers.py b/controllers.py
+--- a/controllers.py
++++ b/controllers.py
+@@ -4,4 +4,21 @@ from openerp.addons.web.controllers impo
+ class Home(main.Home):
+ @http.route('/', auth='none')
+ def index(self):
+- return "Hello, world!"
++ return """<!doctype html>
++<html>
++ <head>
++ <title>AcademyAcademy</title>
++ <link href="//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
++ </head>
++ <body class="container">
++ <h1>Introduction to a thing</h1>
++ <h2>Course description</h2>
++ <p>
++ This course will provide a basic introduction to a thing, for
++ motivated students with no prior experience in things. The course
++ will focus on the discovery of things and the planning and
++ organization necessary to handle things.
++ </p>
++ </body>
++</html>
++"""
--- /dev/null
+# HG changeset patch
+# Parent 0000000000000000000000000000000000000000
+diff --git a/__openerp__.py b/__openerp__.py
+new file mode 100644
+--- /dev/null
++++ b/__openerp__.py
+@@ -0,0 +1,4 @@
++{
++ 'name': "Academy",
++ 'category': "Tools",
++}
--- /dev/null
+# HG changeset patch
+# Parent 2d3441ff4321c4a931940e64fcfb2fe54bd0ad17
+diff --git a/__init__.py b/__init__.py
+new file mode 100644
+--- /dev/null
++++ b/__init__.py
+@@ -0,0 +1,1 @@
++import controllers
--- /dev/null
+manifest
+basic-controller
+module-init
+basic-page
+ta-controller
+url-pattern
+templates-basic
--- /dev/null
+# HG changeset patch
+# Parent 30a859b5dc378c0da751537b1342e8d22775ad44
+
+diff --git a/controllers.py b/controllers.py
+--- a/controllers.py
++++ b/controllers.py
+@@ -1,9 +1,22 @@
+ from openerp import http
+ from openerp.addons.web.controllers import main
+
++teaching_assistants = [
++ {'name': "Diana Padilla"},
++ {'name': "Jody Carroll"},
++ {'name': "Lester Vaughn"},
++ {'name': "Paul Jimenez"},
++ {'name': "Tanya Harris"},
++]
++
+ class Home(main.Home):
+ @http.route('/', auth='none')
+ def index(self):
++ tas = [
++ '<li><a href="/tas/?id=%d">%s</a></li>' % (i, ta['name'])
++ for i, ta in enumerate(teaching_assistants)
++ ]
++
+ return """<!doctype html>
+ <html>
+ <head>
+@@ -19,6 +32,26 @@ class Home(main.Home):
+ will focus on the discovery of things and the planning and
+ organization necessary to handle things.
+ </p>
++ <h2>Teaching Assistants</h2>
++ <ul>
++ %(tas)s
++ </ul>
+ </body>
+ </html>
+-"""
++""" % {
++ 'tas': '\n'.join(tas)
++ }
++
++ @http.route('/tas', auth='none')
++ def ta(self, id):
++ return """<!doctype html>
++<html>
++ <head>
++ <title>AcademyAcademy TA %(name)s</title>
++ <link href="//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
++ </head>
++ <body class="container">
++ <h1>%(name)s</h1>
++ </body>
++</html>
++""" % teaching_assistants[int(id)]
--- /dev/null
+# HG changeset patch
+# Parent 559e3266ed1eeba384445016ffd1438eed54f144
+
+diff --git a/__openerp__.py b/__openerp__.py
+--- a/__openerp__.py
++++ b/__openerp__.py
+@@ -1,4 +1,7 @@
+ {
+ 'name': "Academy",
+ 'category': "Tools",
++ 'data': [
++ 'views/templates.xml',
++ ]
+ }
+diff --git a/controllers.py b/controllers.py
+--- a/controllers.py
++++ b/controllers.py
+@@ -17,41 +17,11 @@ class Home(main.Home):
+ for i, ta in enumerate(teaching_assistants)
+ ]
+
+- return """<!doctype html>
+-<html>
+- <head>
+- <title>AcademyAcademy</title>
+- <link href="//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
+- </head>
+- <body class="container">
+- <h1>Introduction to a thing</h1>
+- <h2>Course description</h2>
+- <p>
+- This course will provide a basic introduction to a thing, for
+- motivated students with no prior experience in things. The course
+- will focus on the discovery of things and the planning and
+- organization necessary to handle things.
+- </p>
+- <h2>Teaching Assistants</h2>
+- <ul>
+- %(tas)s
+- </ul>
+- </body>
+-</html>
+-""" % {
+- 'tas': '\n'.join(tas)
+- }
++ # how in fuck do I get a db here?
++ return "" % {
++ 'tas': '\n'.join(tas)
++ }
+
+ @http.route('/tas/<int:id>/', auth='none')
+ def ta(self, id):
+- return """<!doctype html>
+-<html>
+- <head>
+- <title>AcademyAcademy TA %(name)s</title>
+- <link href="//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
+- </head>
+- <body class="container">
+- <h1>%(name)s</h1>
+- </body>
+-</html>
+-""" % teaching_assistants[id]
++ return "" % teaching_assistants[id]
+diff --git a/views/templates.xml b/views/templates.xml
+new file mode 100644
+--- /dev/null
++++ b/views/templates.xml
+@@ -0,0 +1,39 @@
++<openerp>
++ <data>
++<template id="academy.index" name="Index">
++ <html>
++ <head>
++ <title>AcademyAcademy</title>
++ <link href="//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet"/>
++ </head>
++ <body class="container">
++ <h1>Introduction to a thing</h1>
++ <h2>Course description</h2>
++ <p>
++ This course will provide a basic introduction to a thing, for
++ motivated students with no prior experience in things. The course
++ will focus on the discovery of things and the planning and
++ organization necessary to handle things.
++ </p>
++ <h2>Teaching Assistants</h2>
++ <ul>
++ <t t-raw="tas"/>
++ </ul>
++ </body>
++ </html>
++</template>
++
++<template id="academy.ta" name="Teaching Assistant">
++ <html>
++ <head>
++ <title>AcademyAcademy TA <t t-esc="name"/></title>
++ <link href="//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet"/>
++ </head>
++ <body class="container">
++ <h1><t t-esc="name"/></h1>
++ </body>
++ </html>
++</template>
++
++ </data>
++</openerp>
--- /dev/null
+# HG changeset patch
+# Parent a436864e066f91e51d30cc47f03fc42401c4296a
+diff --git a/controllers.py b/controllers.py
+--- a/controllers.py
++++ b/controllers.py
+@@ -13,7 +13,7 @@ class Home(main.Home):
+ @http.route('/', auth='none')
+ def index(self):
+ tas = [
+- '<li><a href="/tas/?id=%d">%s</a></li>' % (i, ta['name'])
++ '<li><a href="/tas/%d/">%s</a></li>' % (i, ta['name'])
+ for i, ta in enumerate(teaching_assistants)
+ ]
+
+@@ -42,7 +42,7 @@ class Home(main.Home):
+ 'tas': '\n'.join(tas)
+ }
+
+- @http.route('/tas', auth='none')
++ @http.route('/tas/<int:id>/', auth='none')
+ def ta(self, id):
+ return """<!doctype html>
+ <html>
+@@ -54,4 +54,4 @@ class Home(main.Home):
+ <h1>%(name)s</h1>
+ </body>
+ </html>
+-""" % teaching_assistants[int(id)]
++""" % teaching_assistants[id]
OpenERP Server Developers Documentation
========================================
+Howto
+'''''
+
+.. toctree::
+ :maxdepth: 1
+
+ howto/howto_website
+
OpenERP Server
''''''''''''''