Make Your App Frontend Compatible

Odoo Experience 2018 / Developers

148 views
0 Likes
0 0

Share on Social Networks

Share Link

Use permanent link to share in social media

Share with a friend

Please login to send this presentation by email!

Embed in your website

Select page to start with

4. The use case: A Plant Nursery 4

3. Why creating a website? 1 3

8. What a website is actually made of... 2 8

12. How easy is it to create a website with Odoo? 3 12

34. And it’s just the beginning... 4 34

36. Next presentation Tutorial - From a web controller to a full CMS By Martin Geubelle at 4:30 PM, in this room 36

10. One page in more details The Plant Catalog Index URL View Data 10

1. Make Your App Frontend Compatible Sébastien THEYS • Developer - Odoo Or how to create a website with Odoo EXPERIENCE 2018 1

37. Thank you #odooexperience Based on work from Yannick TIVISSE, that was based on work from Thibault DELAVALLEE, Martin TRIGAUX, and Damien BOUVY. https://github.com/seb-odoo/oxp2018 EXPERIENCE 2018 37

2. Why creating a website? 1 What a website is actually made of... How easy is it to create one with Odoo? And it’s just the beginning... 2 3 4 2

7. Why creating a website? 1 What a website is actually made of... How easy is it to create one with Odoo? And it’s just the beginning... 2 3 4 7

11. Why creating a website? 1 What a website is actually made of... How easy is it to create one with Odoo? And it’s just the beginning... 2 3 4 11

5. Existing Backend App ● Made with Odoo Framework ● Offers great features: ○ Plant Catalog ○ Customers Management ○ Orders Management 5

35. 35 References https://www.odoo.com/documentation Including but not limited to: ● Building a Website ● Web Controllers ● QWeb ● Data Files ● Javascript Reference

23. QWeb: Putting it all together eg. Display the Plant Catalog Index Add Assets (inherit) + Use Layout (t-call) Company name (t-field) List of plants (t-foreach t-as) Plant name (t-field) and link (t-attf-) Display pending order conditionally (t-if) 23

24. Controllers eg. Main Controller, Customer Portal Controller ● Contain ○ Routes: mapping between URL, Models and Views ○ Tools: helping with request, access rights, display, ... ○ No business logic! ● Defined in: module_name/controllers/controller_name.py ● Class: odoo.http.Controller 24

6. So why creating a website? The nurseryman wants to grow even more plants! ● Gain of time ○ The customers order plants online. ● More visibility ○ The Plant Catalog can be ■ consulted by anyone ■ indexed by search engines ■ easily shared 6

14. Models eg. Plant, Customer, Order ● Contain data fields : name, price, description, ... ● Business methods always in models! ● Common to frontend and backend ● Defined in: ○ module_name/models/model_name.py ● Class: odoo.models.Model 14

9. A website is a collection of pages Each page has a distinct address ● The Plant Catalog ○ plantnursery.com/plants ● One page for each Plant : ○ plantnursery.com/plant/1-apple-tree ○ plantnursery.com/plant/2-cherry-tree ○ ... ● And many more ○ Such as a Contact Us page, the Customer Portal, ... 9

16. QWeb: Data Output (field) eg. Display Plant name ● Directive: t-field ● Output data ● Format depends on field type < span t-field = "plant.name" /> < span >Apple Tree</ span > Generates: Code: Result: Apple Tree 16

15. Views eg. Plant Catalog Index, Plant Details, Layout ● Actually called Templates in the frontend ● Using QWeb ● XML compliant templating language ● Used to generate HTML fragments and pages ● Control directives starting with t- ○ Output, conditions, loops, attributes, ... ● Defined in: ○ module_name/views/module_name_templates.xml 15

33. How easy is it to create a website? Just follow the 3 steps ● Create Models ○ Contain data and business methods ● Create Views (templates) ○ Define how data should be displayed ● Create Controllers , containing several Routes ○ Handle user request and return response 33

17. QWeb: Data Output (expression) eg. Display page number ● Directive: t-esc ● Output result of expression (or variable) ● HTML-Escape limiting XSS risks p. < span t-esc = "page" /> / < span t-esc = "page_max" /> p. < span >5</ span > / < span >6</ span > Generates: Code: Result: p. 5 / 6 17

18. QWeb: Conditions eg. Display Plant description only if it exists ● Directives: t-if , t-elif , t-else ● Evaluate expression ● Render content if true, else render something else < t t-if = "plant.description" > <span t-field="plant.description"/> < t t-else = "" > <span>No Description</span> </ t > <span>No Description</span> Generates: Code: Result: No Description 18

20. QWeb: Attributes eg. Create a link to each Plant page ● Directives: ○ t-att-$name evaluates expression, set attribute $name ○ t-attf-$name evaluates as format string, set attribute $name < a t-attf-href = "/plant/{{ plant.id }}" > <t t-field= " plant.name " /> </ a > < a href = "/plant/1" >Apple Tree</ a > Generates: Code: Result: Apple Tree 20

29. Routing: Authentication eg. Handle Customer Order ● Can be 'user', 'public', or 'none' ● /orders -> order_display (only if user logged in) from odoo.http import request, route, Controller class Controller ( Controller ) @ route ( '/orders' , type = 'http' , auth = 'user' ) def order_display ( self , ** kwargs ): # compute and display orders Code: 29

27. Routing: Model Parameter eg. Handle Plant Details ● Parameter can also be a Model ○ /plant/1-apple-tree -> plant_display (with argument plant set) ● Good for SEO (name in address) from odoo.http import request, route, Controller class Controller ( Controller ) @ route ( '/plant/<model("nursery.plant"):plant>' , type = 'http' ) def plant_display ( self , plant , ** kwargs ): # compute and display plant Code: 27

25. Routing eg. Handle Plant Catalog Index ● Python Decorator @odoo.http.route ● Map between the URL path and the Controller method ○ thebestnursery.com /plants -> plants_index from odoo.http import request, route, Controller class Controller ( Controller ) @ route ( '/plants' , type = 'http' ) def plants_index ( self , ** kwargs ): # compute and display plants Code: 25

19. QWeb: Loops eg. Display a list of Plants ● Directives: t-foreach , t-as ● Iterate on collection < ul t-foreach = "plants" t-as = "plant" > <li t-field= " plant.name " /> </ ul > < ul > <li>Apple Tree</li> <li>Cherry Tree</li> <li>Plum Tree</li> </ ul > Generates: Code: Result: ● Apple Tree ● Cherry Tree ● Plum Tree 19

26. Routing: Basic Type Parameter eg. Handle Plant Catalog Index with optional page ● Route can be array: map multiple paths to one method ○ /plants -> plants_index (with argument page=1 by default) ○ /plants/page/2 -> plants_index (with argument page=2) from odoo.http import request, route, Controller class Controller ( Controller ) @ route ([ '/plants' , '/plants/page/<int:page>' ], type = 'http' ) def plants_index ( self , page = 1 , ** kwargs ): # compute and display plants and pager Code: 26

13. The Odoo Framework uses MVC Controller Model View User 1. User Enter address (request) 2. Controller Listen to address (routing) 3. Controller Manipulate Models 4. Model Handle business logic 5. Controller Give data to View 6. View Render data 7. Controller Return View (response) 8. User See result 13

31. Routing: JSON eg. Handle Plant Catalog Index live filtering ● Asynchronous communication, without reloading the page ● Returns JSON data instead of view ● Typically called using AJAX (from Javascript) ● Route type='json' instead of 'http' from odoo.http import request, route, Controller class Controller ( Controller ) @ route ( '/plants/get_data' , type = 'json' ) def order_display ( self , ** kwargs ): # plants = ... compute filtered list of plants return { 'plants' : plants} Code: 31

28. Routing: Additional Parameters eg. Handle Plant Catalog Index with filters ● Handle arbitrary GET or POST parameters ○ Python keyword arguments and arbitrary arguments **kwargs ● /plants?category=1 -> plant_display (with argument category=1) from odoo.http import request, route, Controller class Controller ( Controller ) @ route ( '/plants' , type = 'http' ) def plant_display ( self , category = None , ** kwargs ): kwargs. get ( 'available' , True) # compute and display filtered plants Code: 28

22. QWeb: Improve Templates eg. Add custom assets ● Directive: inherit_id ● Improve existing template ● Using XPath < template id = "assets_frontend" inherit_id = "web.assets_frontend" name = "Plant Assets" > < xpath expr = "//link[last()]" position = "after" > <!-- include css here --> </ xpath > </ template > Code: Result: Apple Tree Plant Nursery Menu Home Plants My Orders 22

30. Request eg. Handle Customer Order ● Common to all routes ● Odoo.http.request ○ render/response: return template/data to user ○ env: environment, Odoo ORM entry point ○ session: session data, including current user from odoo.http import request, route, Controller class Controller ( Controller ) @ route ( '/orders' , type = 'http' , auth = 'user' ) def order_display ( self , ** kwargs ): values = { 'uid' : request.session.uid} return request. render ( "index" , values) Code: 30

21. QWeb: Reuse Templates eg. Display a general layout ● Directive: t-call ● Reuse existing template < t t-call = "plant_nursery.plant_layout" > <span t-field= " plant.name " /> </ t > < html >< head >...</ head > < body > ... <span>Apple Tree</span> ... </ body > </ html > Generates: Code: Result: Apple Tree Plant Nursery Menu ● Home ● Plants ● My Orders 21

32. Routing: JSON RPC eg. Handle Plant Catalog Index live filtering ● Used in Javascript, from inside a module and widget ● rpc.query to call server ● Handle asynchronous response (Deferred) var rpc = require ( 'web.rpc' ); var qweb = require ( 'web.core.qweb' ); # module and widget definition fetchData : function () { var self = this; return rpc. query ({ route : '/plants/get_data' , params : {}, }). then ( function (data) { var $plants = qweb. render ("plants", {widget: data}); self .$('.o_content'). replaceWith ($plants); }); } Code: 32

Views

  • 148 Total Views
  • 0 Website Views
  • 148 Embedded Views

Actions

  • 0 Social Shares
  • 0 Likes
  • 0 Dislikes
  • 0 Comments

Share count

  • 0 Facebook
  • 0 Twitter
  • 0 LinkedIn
  • 0 Google+