[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:
parent
50c5a23dec
commit
c2d5bf1bc3
|
@ -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']
|
||||
|
|
|
@ -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
|
|
@ -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!"
|
|
@ -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>
|
||||
+"""
|
|
@ -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",
|
||||
+}
|
|
@ -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
|
|
@ -0,0 +1,7 @@
|
|||
manifest
|
||||
basic-controller
|
||||
module-init
|
||||
basic-page
|
||||
ta-controller
|
||||
url-pattern
|
||||
templates-basic
|
|
@ -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)]
|
|
@ -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>
|
|
@ -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]
|
|
@ -4,6 +4,14 @@
|
|||
OpenERP Server Developers Documentation
|
||||
========================================
|
||||
|
||||
Howto
|
||||
'''''
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
howto/howto_website
|
||||
|
||||
OpenERP Server
|
||||
''''''''''''''
|
||||
|
||||
|
|
Loading…
Reference in New Issue