[IMP] website_blog: add breadcrumb; [IMP] clean links
[odoo/odoo.git] / addons / web / doc / web_controllers.rst
1
2 Web Controllers
3 ===============
4
5 Web controllers are classes in OpenERP able to catch the http requests sent by any browser. They allow to generate
6 html pages to be served like any web server, implement new methods to be used by the Javascript client, etc...
7
8 Controllers File
9 ----------------
10
11 By convention the controllers should be placed in the controllers directory of the module. Example:
12
13 .. code-block:: text
14
15     web_example
16     ├── controllers
17     │   ├── __init__.py
18     │   └── my_controllers.py
19     ├── __init__.py
20     └── __openerp__.py
21
22 In ``__init__.py`` you must add:
23
24 ::
25
26     import controllers
27
28 And here is the content of ``controllers/__init__.py``:
29
30 ::
31     
32     import my_controllers
33
34 Now you can put the following content in ``controllers/my_controllers.py``:
35
36 ::
37
38     import openerp.addons.web.http as http
39     from openerp.addons.web.http import request
40
41
42 Controller Declaration
43 ----------------------
44
45 In your controllers file, you can now declare a controller this way:
46
47 ::
48
49     class MyController(http.Controller):
50
51         @http.route('/my_url/some_html', type="http")
52         def some_html(self):
53             return "<h1>This is a test</h1>"
54
55         @http.route('/my_url/some_json', type="json")
56         def some_json(self):
57             return {"sample_dictionary": "This is a sample JSON dictionary"}
58
59 A controller must inherit from ``http.Controller``. Each time you define a method with ``@http.route()`` it defines a
60 url to match. As example, the ``some_html()`` method will be called a client query the ``/my_url/some_html`` url.
61
62 Pure HTTP Requests
63 ------------------
64
65 You can define methods to get any normal http requests by passing ``'http'`` to the ``type`` argument of
66 ``http.route()``. When doing so, you get the HTTP parameters as named parameters of the method:
67
68 ::
69
70     @http.route('/say_hello', type="http")
71     def say_hello(self, name):
72         return "<h1>Hello %s</h1>" % name
73
74 This url could be contacted by typing this url in a browser: ``http://localhost:8069/say_hello?name=Nicolas``.
75
76 JSON Requests
77 -------------
78
79 Methods that received JSON can be defined by passing ``'json'`` to the ``type`` argument of ``http.route()``. The
80 OpenERP Javascript client can contact these methods using the JSON-RPC protocol. JSON methods must return JSON. Like the
81 HTTP methods they receive arguments as named parameters (except these arguments are JSON-RPC parameters).
82
83 ::
84
85     @http.route('/division', type="json")
86     def division(self, i, j):
87         return i / j # returns a number
88
89 URL Patterns
90 ------------
91
92 Any URL passed to ``http.route()`` can contain patterns. Example:
93
94 ::
95
96     @http.route('/files/<path:file_path>', type="http")
97     def files(self, file_path):
98         ... # return a file identified by the path store in the 'my_path' variable
99
100 When such patterns are used, the method will received additional parameters that correspond to the parameters defined in
101 the url. For exact documentation about url patterns, see Werkzeug's documentation:
102 http://werkzeug.pocoo.org/docs/routing/ .
103
104 Also note you can pass multiple urls to ``http.route()``:
105
106
107 ::
108
109     @http.route(['/files/<path:file_path>', '/other_url/<path:file_path>'], type="http")
110     def files(self, file_path):
111         ...
112
113 Contacting Models
114 -----------------
115
116 To use the database you must access the OpenERP models. The global ``request`` object provides the necessary objects:
117
118 ::
119
120     @http.route('/my_name', type="http")
121     def my_name(self):
122         my_user_record = request.registry.get("res.users").browse(request.cr, request.uid, request.uid)
123         return "<h1>Your name is %s</h1>" % my_user_record.name
124
125 ``request.registry`` is the registry that gives you access to the models. It is the equivalent of ``self.pool`` when
126 working inside OpenERP models.
127
128 ``request.cr`` is the cursor object. This is the ``cr`` parameter you have to pass as first argument of every model
129 method in OpenERP.
130
131 ``request.uid`` is the id of the current logged in user. This is the ``uid`` parameter you have to pass as second
132 argument of every model method in OpenERP.
133
134 Authorization Levels
135 --------------------
136
137 By default, all methods can only be used by users logged into OpenERP (OpenERP uses cookies to track logged users).
138 There are some cases when you need to enable not-logged in users to access some methods. To do so, add the ``'db'``
139 value to the ``auth`` parameter of ``http.route()``:
140
141 ::
142
143     @http.route('/hello', type="http", auth="db")
144     def hello(self):
145         return "<div>Hello unknown user!</div>"
146
147 Please note the ``request.uid`` user id will be ``None`` inside this method call. This is due to the fact no user was
148 authenticated.
149
150 Overriding Controllers
151 ----------------------
152
153 Existing routes can be overridden. To do so, create a controller that inherit the controller containing the route you
154 want to override. Example that redefine the home page of your OpenERP application.
155
156 ::
157
158     import openerp.addons.web.controllers.main as main
159
160     class Home2(main.Home):
161         @http.route('/', type="http", auth="db")
162         def index(self):
163             return "<div>This is my new home page.</div>"
164
165 By re-defining the ``index()`` method, you change the behavior of the original ``Home`` class. Now the ``'/'`` route
166 will match the new ``index()`` method in ``Home2``.