[ADD] tutorial beginning

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...
This commit is contained in:
Xavier Morel 2014-01-20 14:13:10 +01:00
parent 50c5a23dec
commit c2d5bf1bc3
11 changed files with 415 additions and 1 deletions

View File

@ -28,7 +28,7 @@ sys.path.append(os.path.abspath('../openerp'))
# 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']

142
doc/howto/howto_website.rst Normal file
View File

@ -0,0 +1,142 @@
===================================
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

View File

@ -0,0 +1,15 @@
# 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!"

View File

@ -0,0 +1,29 @@
# 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>
+"""

View File

@ -0,0 +1,11 @@
# 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",
+}

View File

@ -0,0 +1,8 @@
# 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

View File

@ -0,0 +1,7 @@
manifest
basic-controller
module-init
basic-page
ta-controller
url-pattern
templates-basic

View File

@ -0,0 +1,57 @@
# 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)]

View File

@ -0,0 +1,108 @@
# 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>

View File

@ -0,0 +1,29 @@
# 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]

View File

@ -4,6 +4,14 @@
OpenERP Server Developers Documentation
========================================
Howto
'''''
.. toctree::
:maxdepth: 1
howto/howto_website
OpenERP Server
''''''''''''''