diff --git a/doc/conf.py b/doc/conf.py index 19f2c9b727f..051fcde3ccb 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -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'] diff --git a/doc/howto/howto_website.rst b/doc/howto/howto_website.rst new file mode 100644 index 00000000000..69486d79734 --- /dev/null +++ b/doc/howto/howto_website.rst @@ -0,0 +1,142 @@ +=================================== +Howto: build a website with OpenERP +=================================== + +.. queue:: howto_website/series + +.. warning:: + + This guide assumes `basic knowledge of python + `_. + + This guide assumes :ref:`an OpenERP installed and ready for + development `. + + 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 ` 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 diff --git a/doc/howto/howto_website/basic-controller b/doc/howto/howto_website/basic-controller new file mode 100644 index 00000000000..4415d9516bc --- /dev/null +++ b/doc/howto/howto_website/basic-controller @@ -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!" diff --git a/doc/howto/howto_website/basic-page b/doc/howto/howto_website/basic-page new file mode 100644 index 00000000000..5a60c346acf --- /dev/null +++ b/doc/howto/howto_website/basic-page @@ -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 """ ++ ++ ++ AcademyAcademy ++ ++ ++ ++

Introduction to a thing

++

Course description

++

++ 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. ++

++ ++ ++""" diff --git a/doc/howto/howto_website/manifest b/doc/howto/howto_website/manifest new file mode 100644 index 00000000000..3cf359c9b30 --- /dev/null +++ b/doc/howto/howto_website/manifest @@ -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", ++} diff --git a/doc/howto/howto_website/module-init b/doc/howto/howto_website/module-init new file mode 100644 index 00000000000..4484236edc9 --- /dev/null +++ b/doc/howto/howto_website/module-init @@ -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 diff --git a/doc/howto/howto_website/series b/doc/howto/howto_website/series new file mode 100644 index 00000000000..4b45d06e6d1 --- /dev/null +++ b/doc/howto/howto_website/series @@ -0,0 +1,7 @@ +manifest +basic-controller +module-init +basic-page +ta-controller +url-pattern +templates-basic diff --git a/doc/howto/howto_website/ta-controller b/doc/howto/howto_website/ta-controller new file mode 100644 index 00000000000..5b8d0b799d5 --- /dev/null +++ b/doc/howto/howto_website/ta-controller @@ -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 = [ ++ '
  • %s
  • ' % (i, ta['name']) ++ for i, ta in enumerate(teaching_assistants) ++ ] ++ + return """ + + +@@ -19,6 +32,26 @@ class Home(main.Home): + will focus on the discovery of things and the planning and + organization necessary to handle things. +

    ++

    Teaching Assistants

    ++ + + +-""" ++""" % { ++ 'tas': '\n'.join(tas) ++ } ++ ++ @http.route('/tas', auth='none') ++ def ta(self, id): ++ return """ ++ ++ ++ AcademyAcademy TA %(name)s ++ ++ ++ ++

    %(name)s

    ++ ++ ++""" % teaching_assistants[int(id)] diff --git a/doc/howto/howto_website/templates-basic b/doc/howto/howto_website/templates-basic new file mode 100644 index 00000000000..5f0aefec2fe --- /dev/null +++ b/doc/howto/howto_website/templates-basic @@ -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 """ +- +- +- AcademyAcademy +- +- +- +-

    Introduction to a thing

    +-

    Course description

    +-

    +- 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. +-

    +-

    Teaching Assistants

    +- +- +- +-""" % { +- 'tas': '\n'.join(tas) +- } ++ # how in fuck do I get a db here? ++ return "" % { ++ 'tas': '\n'.join(tas) ++ } + + @http.route('/tas//', auth='none') + def ta(self, id): +- return """ +- +- +- AcademyAcademy TA %(name)s +- +- +- +-

    %(name)s

    +- +- +-""" % 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 @@ ++ ++ ++ ++ ++ ++ ++ ++ diff --git a/doc/howto/howto_website/url-pattern b/doc/howto/howto_website/url-pattern new file mode 100644 index 00000000000..8f37b1bdcda --- /dev/null +++ b/doc/howto/howto_website/url-pattern @@ -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 = [ +- '
  • %s
  • ' % (i, ta['name']) ++ '
  • %s
  • ' % (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//', auth='none') + def ta(self, id): + return """ + +@@ -54,4 +54,4 @@ class Home(main.Home): +

    %(name)s

    + + +-""" % teaching_assistants[int(id)] ++""" % teaching_assistants[id] diff --git a/doc/index.rst b/doc/index.rst index 4b988e747b4..a61de5ca0e0 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -4,6 +4,14 @@ OpenERP Server Developers Documentation ======================================== +Howto +''''' + +.. toctree:: + :maxdepth: 1 + + howto/howto_website + OpenERP Server ''''''''''''''