From 57b7ca69d9d866cdbfb54aad33271116a40b05a7 Mon Sep 17 00:00:00 2001 From: "Antoine Vandevenne (anv)" Date: Tue, 9 Apr 2024 11:54:08 +0200 Subject: [PATCH] [IMP] developer: improve navigation in top-level pages Prior to this commit, users had to either know in advance or guess the location of the content they were looking for. Top-level pages of the "Developer" section of the documentation, in particular the "Developer" page itself, were listing their sub-pages without directions for users. This commit brings the following changes to improve the navigation: - add directions for users on the "Developer" page and list the three main categories of developer documentation ("Tutorials", "How-to guides", and "Reference") with explanations of their content and target audience; - add categories for content cards on the "Tutorials" and "How-to guides" pages, and fine-tune the toctree of the "Reference" page to more easily locate specific topics; - clarify what are the "Python framework" and the "JavaScript framework" by relabelling them to "Server framework" and "Web framework" on top-level pages, as some users were confused to find that the JS framework was not responsible for the server, and others that the documentation for QWeb template is located in the Python documentation; - extract the "Setup guide" from the "Getting started" tutorial and rename the latter to "Server framework 101" to allow reusing the setup guide in other tutorials and make clear that the "Server framework 101" tutorial is not about the Web framework. task-3802536 closes odoo/documentation#8712 X-original-commit: 7f623b6ad5aac4c5ab3e21886cfb3331ee2b5c63 Signed-off-by: Antoine Vandevenne (anv) Co-authored-by: Valeriya (vchu) --- .../odoo_sh/getting_started/first_module.rst | 2 +- content/administration/on_premise/source.rst | 2 +- content/contributing.rst | 3 +- content/developer.rst | 49 +++++++++++--- content/developer/howtos.rst | 64 +++++++++++------- .../howtos/accounting_localization.rst | 2 +- content/developer/howtos/company.rst | 2 +- content/developer/reference.rst | 23 ++++--- content/developer/reference/backend.rst | 25 +++---- content/developer/reference/frontend.rst | 33 ++++----- .../button_attribute_context.rst | 2 + .../button_attribute_help.rst | 2 + .../button_attribute_icon.rst | 2 + .../button_attribute_name.rst | 2 + .../button_attribute_string.rst | 2 + .../button_attribute_type.rst | 2 + .../field_attribute_name.rst | 2 + .../field_attribute_readonly.rst | 2 + .../field_attribute_required.rst | 2 + .../field_attribute_string.rst | 2 + .../field_attribute_widget.rst | 2 + .../generic_attribute_class.rst | 2 + .../generic_attribute_column_invisible.rst | 2 + .../generic_attribute_groups.rst | 2 + .../generic_attribute_invisible.rst | 2 + .../root_attribute_banner_route.rst | 2 + .../root_attribute_create.rst | 2 + .../root_attribute_default_group_by.rst | 2 + .../root_attribute_default_order.rst | 2 + .../root_attribute_delete.rst | 2 + .../root_attribute_edit.rst | 2 + .../root_attribute_sample.rst | 2 + .../root_attribute_string.rst | 2 + content/developer/tutorials.rst | 52 ++++++++------ content/developer/tutorials/backend.rst | 2 +- .../tutorials/define_module_data.rst | 16 ++--- .../tutorials/discover_js_framework.rst | 15 ++-- .../developer/tutorials/getting_started.rst | 47 ------------- .../02_setup/account-settings.png | Bin 20025 -> 0 bytes .../02_setup/settings-sidebar-ssh-keys.png | Bin 19437 -> 0 bytes .../02_setup/ssh-add-ssh-key.png | Bin 10485 -> 0 bytes .../02_setup/ssh-key-paste.png | Bin 14992 -> 0 bytes .../tutorials/master_odoo_web_framework.rst | 8 +-- .../03_customize_kanban_view.rst | 2 +- content/developer/tutorials/pdf_reports.rst | 10 ++- .../tutorials/restrict_data_access.rst | 10 ++- .../tutorials/server_framework_101.rst | 44 ++++++++++++ .../01_architecture.rst | 7 +- .../01_architecture/three_tier.svg | 0 .../02_newapp.rst} | 15 ++-- .../02_newapp}/app_in_list.png | Bin .../02_newapp}/overview_form_view_01.png | Bin .../02_newapp}/overview_form_view_02.png | Bin .../02_newapp}/overview_list_view_01.png | Bin .../03_basicmodel.rst} | 8 +-- .../04_securityintro.rst} | 8 +-- .../05_firstui.rst} | 30 ++++---- .../05_firstui}/attribute_and_default.gif | Bin .../05_firstui}/estate_form_default.png | Bin .../05_firstui}/estate_menu_action.png | Bin .../05_firstui}/estate_menu_root.png | Bin .../05_firstui}/inactive.gif | Bin .../05_firstui}/menu_01.png | Bin .../05_firstui}/menu_02.png | Bin .../06_basicviews.rst} | 18 +++-- .../06_basicviews}/form.png | Bin .../06_basicviews}/list.png | Bin .../06_basicviews}/search_01.png | Bin .../06_basicviews}/search_02.png | Bin .../06_basicviews}/search_03.png | Bin .../07_relations.rst} | 28 ++++---- .../07_relations}/property_many2many.png | Bin .../07_relations}/property_many2one.png | Bin .../07_relations}/property_offer.png | Bin .../07_relations}/property_tag.png | Bin .../07_relations}/property_type.png | Bin .../08_compute_onchange.rst} | 16 ++--- .../08_compute_onchange}/compute.gif | Bin .../08_compute_onchange}/compute_inverse.gif | Bin .../08_compute_onchange}/onchange.gif | Bin .../09_actions.rst} | 16 ++--- .../09_actions}/offer_01.gif | Bin .../09_actions}/offer_02.gif | Bin .../09_actions}/property.gif | Bin .../10_constraints.rst} | 14 ++-- .../10_constraints}/python.gif | Bin .../10_constraints}/sql_01.gif | Bin .../10_constraints}/sql_02.gif | Bin .../11_sprinkles.rst} | 32 ++++----- .../11_sprinkles}/decoration.png | Bin .../11_sprinkles}/editable_list.gif | Bin .../11_sprinkles}/form.gif | Bin .../11_sprinkles}/inline_view.png | Bin .../11_sprinkles}/search.gif | Bin .../11_sprinkles}/stat_button.gif | Bin .../11_sprinkles}/widget.png | Bin .../12_inheritance.rst} | 14 ++-- .../12_inheritance}/create.gif | Bin .../12_inheritance}/inheritance_methods.png | Bin .../12_inheritance}/unlink.gif | Bin .../12_inheritance}/users.png | Bin .../13_other_module.rst} | 22 +++--- .../13_other_module}/create_inv.gif | Bin .../14_qwebintro.rst} | 6 +- .../14_qwebintro}/kanban.png | Bin .../15_final_word.rst} | 4 +- .../02_setup.rst => setup_guide.rst} | 43 ++++-------- content/developer/tutorials/unit_tests.rst | 6 +- content/developer/tutorials/website.rst | 2 +- .../odoo_theme/layout_templates/homepage.html | 21 +++--- redirects/17.0.txt | 20 ++++++ 111 files changed, 424 insertions(+), 363 deletions(-) delete mode 100644 content/developer/tutorials/getting_started.rst delete mode 100644 content/developer/tutorials/getting_started/02_setup/account-settings.png delete mode 100644 content/developer/tutorials/getting_started/02_setup/settings-sidebar-ssh-keys.png delete mode 100644 content/developer/tutorials/getting_started/02_setup/ssh-add-ssh-key.png delete mode 100644 content/developer/tutorials/getting_started/02_setup/ssh-key-paste.png create mode 100644 content/developer/tutorials/server_framework_101.rst rename content/developer/tutorials/{getting_started => server_framework_101}/01_architecture.rst (93%) rename content/developer/tutorials/{getting_started => server_framework_101}/01_architecture/three_tier.svg (100%) rename content/developer/tutorials/{getting_started/03_newapp.rst => server_framework_101/02_newapp.rst} (92%) rename content/developer/tutorials/{getting_started/03_newapp => server_framework_101/02_newapp}/app_in_list.png (100%) rename content/developer/tutorials/{getting_started/03_newapp => server_framework_101/02_newapp}/overview_form_view_01.png (100%) rename content/developer/tutorials/{getting_started/03_newapp => server_framework_101/02_newapp}/overview_form_view_02.png (100%) rename content/developer/tutorials/{getting_started/03_newapp => server_framework_101/02_newapp}/overview_list_view_01.png (100%) rename content/developer/tutorials/{getting_started/04_basicmodel.rst => server_framework_101/03_basicmodel.rst} (98%) rename content/developer/tutorials/{getting_started/05_securityintro.rst => server_framework_101/04_securityintro.rst} (94%) rename content/developer/tutorials/{getting_started/06_firstui.rst => server_framework_101/05_firstui.rst} (91%) rename content/developer/tutorials/{getting_started/06_firstui => server_framework_101/05_firstui}/attribute_and_default.gif (100%) rename content/developer/tutorials/{getting_started/06_firstui => server_framework_101/05_firstui}/estate_form_default.png (100%) rename content/developer/tutorials/{getting_started/06_firstui => server_framework_101/05_firstui}/estate_menu_action.png (100%) rename content/developer/tutorials/{getting_started/06_firstui => server_framework_101/05_firstui}/estate_menu_root.png (100%) rename content/developer/tutorials/{getting_started/06_firstui => server_framework_101/05_firstui}/inactive.gif (100%) rename content/developer/tutorials/{getting_started/06_firstui => server_framework_101/05_firstui}/menu_01.png (100%) rename content/developer/tutorials/{getting_started/06_firstui => server_framework_101/05_firstui}/menu_02.png (100%) rename content/developer/tutorials/{getting_started/07_basicviews.rst => server_framework_101/06_basicviews.rst} (94%) rename content/developer/tutorials/{getting_started/07_basicviews => server_framework_101/06_basicviews}/form.png (100%) rename content/developer/tutorials/{getting_started/07_basicviews => server_framework_101/06_basicviews}/list.png (100%) rename content/developer/tutorials/{getting_started/07_basicviews => server_framework_101/06_basicviews}/search_01.png (100%) rename content/developer/tutorials/{getting_started/07_basicviews => server_framework_101/06_basicviews}/search_02.png (100%) rename content/developer/tutorials/{getting_started/07_basicviews => server_framework_101/06_basicviews}/search_03.png (100%) rename content/developer/tutorials/{getting_started/08_relations.rst => server_framework_101/07_relations.rst} (92%) rename content/developer/tutorials/{getting_started/08_relations => server_framework_101/07_relations}/property_many2many.png (100%) rename content/developer/tutorials/{getting_started/08_relations => server_framework_101/07_relations}/property_many2one.png (100%) rename content/developer/tutorials/{getting_started/08_relations => server_framework_101/07_relations}/property_offer.png (100%) rename content/developer/tutorials/{getting_started/08_relations => server_framework_101/07_relations}/property_tag.png (100%) rename content/developer/tutorials/{getting_started/08_relations => server_framework_101/07_relations}/property_type.png (100%) rename content/developer/tutorials/{getting_started/09_compute_onchange.rst => server_framework_101/08_compute_onchange.rst} (96%) rename content/developer/tutorials/{getting_started/09_compute_onchange => server_framework_101/08_compute_onchange}/compute.gif (100%) rename content/developer/tutorials/{getting_started/09_compute_onchange => server_framework_101/08_compute_onchange}/compute_inverse.gif (100%) rename content/developer/tutorials/{getting_started/09_compute_onchange => server_framework_101/08_compute_onchange}/onchange.gif (100%) rename content/developer/tutorials/{getting_started/10_actions.rst => server_framework_101/09_actions.rst} (90%) rename content/developer/tutorials/{getting_started/10_actions => server_framework_101/09_actions}/offer_01.gif (100%) rename content/developer/tutorials/{getting_started/10_actions => server_framework_101/09_actions}/offer_02.gif (100%) rename content/developer/tutorials/{getting_started/10_actions => server_framework_101/09_actions}/property.gif (100%) rename content/developer/tutorials/{getting_started/11_constraints.rst => server_framework_101/10_constraints.rst} (92%) rename content/developer/tutorials/{getting_started/11_constraints => server_framework_101/10_constraints}/python.gif (100%) rename content/developer/tutorials/{getting_started/11_constraints => server_framework_101/10_constraints}/sql_01.gif (100%) rename content/developer/tutorials/{getting_started/11_constraints => server_framework_101/10_constraints}/sql_02.gif (100%) rename content/developer/tutorials/{getting_started/12_sprinkles.rst => server_framework_101/11_sprinkles.rst} (95%) rename content/developer/tutorials/{getting_started/12_sprinkles => server_framework_101/11_sprinkles}/decoration.png (100%) rename content/developer/tutorials/{getting_started/12_sprinkles => server_framework_101/11_sprinkles}/editable_list.gif (100%) rename content/developer/tutorials/{getting_started/12_sprinkles => server_framework_101/11_sprinkles}/form.gif (100%) rename content/developer/tutorials/{getting_started/12_sprinkles => server_framework_101/11_sprinkles}/inline_view.png (100%) rename content/developer/tutorials/{getting_started/12_sprinkles => server_framework_101/11_sprinkles}/search.gif (100%) rename content/developer/tutorials/{getting_started/12_sprinkles => server_framework_101/11_sprinkles}/stat_button.gif (100%) rename content/developer/tutorials/{getting_started/12_sprinkles => server_framework_101/11_sprinkles}/widget.png (100%) rename content/developer/tutorials/{getting_started/13_inheritance.rst => server_framework_101/12_inheritance.rst} (96%) rename content/developer/tutorials/{getting_started/13_inheritance => server_framework_101/12_inheritance}/create.gif (100%) rename content/developer/tutorials/{getting_started/13_inheritance => server_framework_101/12_inheritance}/inheritance_methods.png (100%) rename content/developer/tutorials/{getting_started/13_inheritance => server_framework_101/12_inheritance}/unlink.gif (100%) rename content/developer/tutorials/{getting_started/13_inheritance => server_framework_101/12_inheritance}/users.png (100%) rename content/developer/tutorials/{getting_started/14_other_module.rst => server_framework_101/13_other_module.rst} (89%) rename content/developer/tutorials/{getting_started/14_other_module => server_framework_101/13_other_module}/create_inv.gif (100%) rename content/developer/tutorials/{getting_started/15_qwebintro.rst => server_framework_101/14_qwebintro.rst} (97%) rename content/developer/tutorials/{getting_started/15_qwebintro => server_framework_101/14_qwebintro}/kanban.png (100%) rename content/developer/tutorials/{getting_started/16_final_word.rst => server_framework_101/15_final_word.rst} (93%) rename content/developer/tutorials/{getting_started/02_setup.rst => setup_guide.rst} (87%) diff --git a/content/administration/odoo_sh/getting_started/first_module.rst b/content/administration/odoo_sh/getting_started/first_module.rst index 3499306fe..25c6dd1d6 100644 --- a/content/administration/odoo_sh/getting_started/first_module.rst +++ b/content/administration/odoo_sh/getting_started/first_module.rst @@ -146,7 +146,7 @@ Manually -------- If you want to create your module structure manually, -you can follow the :doc:`/developer/tutorials/getting_started` tutorial to understand +you can follow the :doc:`/developer/tutorials/server_framework_101` tutorial to understand the structure of a module and the content of each file. Push the development branch diff --git a/content/administration/on_premise/source.rst b/content/administration/on_premise/source.rst index e3d3a884d..e5fadc90d 100644 --- a/content/administration/on_premise/source.rst +++ b/content/administration/on_premise/source.rst @@ -45,7 +45,7 @@ Git To clone a Git repository, choose between cloning with HTTPS or SSH. In most cases, the best option is HTTPS. However, choose SSH to contribute to Odoo source code or when following the :doc:`Getting -Started developer tutorial `. +Started developer tutorial `. .. tabs:: diff --git a/content/contributing.rst b/content/contributing.rst index 3f9533401..dc141711f 100644 --- a/content/contributing.rst +++ b/content/contributing.rst @@ -48,7 +48,8 @@ lists the most important of them. pull requests from other contributors. By contributing to the codebase, you can make a direct and lasting impact on the quality and features of Odoo. - * :doc:`Guide: Contributing to the codebase ` - * :doc:`Developer tutorials ` + * :doc:`Developer tutorials ` + * :doc:`How-to guides ` - Developers with experience in Python and web development * - Contribute to the documentation - Submit corrections and improvements to the Odoo documentation. The product evolves fast, and diff --git a/content/developer.rst b/content/developer.rst index 84002fbfa..3a8825dcc 100644 --- a/content/developer.rst +++ b/content/developer.rst @@ -1,20 +1,47 @@ -:nosearch: :show-content: :hide-page-toc: -:show-toc: - ========= Developer ========= -Learn through tutorials and get help using reference guides. - - .. toctree:: - :titlesonly: - :maxdepth: 3 + developer/tutorials + developer/howtos + developer/reference - developer/tutorials - developer/howtos - developer/reference +Welcome to the developer documentation of Odoo! Whether you're a seasoned developer or just getting +started, you'll find here all the technical guidance and resources you need for developing Odoo +applications. Explore our extensive collection of tutorials, how-to guides, and reference materials +to achieve your development goals. + +The Odoo development ecosystem is built on a modular and extensible architecture that allows you +to extend existing applications or create new ones to meet the specific needs of modern businesses. +You can make use of the tools and frameworks provided by Odoo to focus on getting your web +application up and running quickly, without needing to reinvent the wheel and worry about the +underlying infrastructure. + +If you are new to Odoo or web application development, start with the +:doc:`developer/tutorials/server_framework_101` tutorial. + +.. cards:: + + .. card:: Tutorials + :target: developer/tutorials + + Tutorials take you by the hand through hands-on exercises to build skills and familiarity in + Odoo development. + + .. card:: How-to guides + :target: developer/howtos + + Recipes that provide a step-by-step guide for addressing real-world problems and use-cases. + + .. card:: Reference + :target: developer/reference + + Technical descriptions and factual information on the frameworks and APIs of Odoo. + +.. seealso:: + - :doc:`Guide: Contribute to the codebase ` + - `Community forums `_ diff --git a/content/developer/howtos.rst b/content/developer/howtos.rst index a25ab7d3d..f9a14f24e 100644 --- a/content/developer/howtos.rst +++ b/content/developer/howtos.rst @@ -6,22 +6,25 @@ How-to guides ============= .. toctree:: - :titlesonly: + howtos/scss_tips + howtos/javascript_field + howtos/javascript_view + howtos/javascript_client_action + howtos/standalone_owl_application + howtos/frontend_owl_components + howtos/website_themes - howtos/scss_tips - howtos/javascript_field - howtos/javascript_view - howtos/javascript_client_action - howtos/standalone_owl_application - howtos/frontend_owl_components - howtos/web_services - howtos/company - howtos/create_reports - howtos/accounting_localization - howtos/translations - howtos/website_themes - howtos/connect_device - howtos/upgrade_custom_db + howtos/web_services + howtos/company + howtos/create_reports + howtos/accounting_localization + howtos/translations + howtos/connect_device + + howtos/upgrade_custom_db + +Frontend development +==================== .. cards:: @@ -33,29 +36,39 @@ How-to guides .. card:: Customize a field :target: howtos/javascript_field - Learn how to customize field components in the Odoo JavaScript web framework. + Learn how to customize field components in the web framework. .. card:: Customize a view type :target: howtos/javascript_view - Learn how to customize view types in the Odoo JavaScript web framework. + Learn how to customize view types in the web framework. .. card:: Create a client action :target: howtos/javascript_client_action - Learn how to create client actions in the Odoo JavaScript web framework. + Learn how to create client actions in the web framework. .. card:: Create a standalone Owl application :target: howtos/standalone_owl_application Learn how to create a public-facing Owl application outside of the web client using a - controller and the Odoo JavaScript framework. + controller and the web framework. .. card:: Use Owl components on the portal and website :target: howtos/frontend_owl_components Learn how to use Owl components on the portal and website. + .. card:: Website themes + :target: howtos/website_themes + + Learn how to customize your website by creating a custom theme. + +Server-side development +======================= + +.. cards:: + .. card:: Web services :target: howtos/web_services @@ -82,17 +95,18 @@ How-to guides Learn how to provide translation abilities to your module. - .. card:: Website themes - :target: howtos/website_themes - - Learn how to customize your website by creating a custom theme. - .. card:: Connect with a device :target: howtos/connect_device Learn how to enable a module to detect and communicate with an IoT device. +Custom development +================== + +.. cards:: + .. card:: Upgrade a customized database :target: howtos/upgrade_custom_db - Learn how to upgrade a customized database, as well as the code and data of its custom modules. + Learn how to upgrade a customized database, as well as the code and data of its custom + modules. diff --git a/content/developer/howtos/accounting_localization.rst b/content/developer/howtos/accounting_localization.rst index 2b8d3ac0c..2b029678f 100644 --- a/content/developer/howtos/accounting_localization.rst +++ b/content/developer/howtos/accounting_localization.rst @@ -6,7 +6,7 @@ Accounting localization .. warning:: This tutorial requires knowledge about how to build a module in Odoo (see - :doc:`../tutorials/getting_started`). + :doc:`../tutorials/server_framework_101`). Installation procedure diff --git a/content/developer/howtos/company.rst b/content/developer/howtos/company.rst index b8f10480c..d6c6f7a08 100644 --- a/content/developer/howtos/company.rst +++ b/content/developer/howtos/company.rst @@ -8,7 +8,7 @@ Multi-company Guidelines .. warning:: This tutorial requires good knowledge of Odoo. - Please refer to the :doc:`../tutorials/getting_started` tutorial first if needed. + Please refer to the :doc:`../tutorials/server_framework_101` tutorial first if needed. As of version 13.0, a user can be logged in to multiple companies at once. This allows the user to access information from multiple companies, but also to create/edit records in a multi-company diff --git a/content/developer/reference.rst b/content/developer/reference.rst index 48c56b2d8..a8b0c34b4 100644 --- a/content/developer/reference.rst +++ b/content/developer/reference.rst @@ -1,18 +1,21 @@ :nosearch: +:show-content: +:show-toc: +:hide-page-toc: ========= Reference ========= .. toctree:: - :titlesonly: + :maxdepth: 3 - reference/backend - reference/frontend - reference/user_interface - reference/standard_modules - reference/cli - reference/upgrade_scripts - reference/upgrade_utils - reference/external_api - reference/extract_api + reference/backend + reference/frontend + reference/user_interface + reference/standard_modules + reference/cli + reference/upgrade_scripts + reference/upgrade_utils + reference/external_api + reference/extract_api diff --git a/content/developer/reference/backend.rst b/content/developer/reference/backend.rst index cd56eca9c..e7e1f06da 100644 --- a/content/developer/reference/backend.rst +++ b/content/developer/reference/backend.rst @@ -1,19 +1,20 @@ :nosearch: +:hide-page-toc: ================ -Python framework +Server framework ================ .. toctree:: - :titlesonly: + :titlesonly: - backend/orm - backend/data - backend/actions - backend/reports - backend/module - backend/security - backend/performance - backend/testing - backend/http - backend/mixins + backend/orm + backend/data + backend/actions + backend/reports + backend/module + backend/security + backend/performance + backend/testing + backend/http + backend/mixins diff --git a/content/developer/reference/frontend.rst b/content/developer/reference/frontend.rst index cf95a3841..cc65ce4a6 100644 --- a/content/developer/reference/frontend.rst +++ b/content/developer/reference/frontend.rst @@ -1,21 +1,22 @@ :nosearch: +:hide-page-toc: -==================== -JavaScript framework -==================== +============= +Web framework +============= .. toctree:: - :titlesonly: + :titlesonly: - frontend/framework_overview - frontend/assets - frontend/javascript_modules - frontend/owl_components - frontend/registries - frontend/services - frontend/hooks - frontend/patching_code - frontend/javascript_reference - frontend/mobile - frontend/qweb - frontend/odoo_editor + frontend/framework_overview + frontend/assets + frontend/javascript_modules + frontend/owl_components + frontend/registries + frontend/services + frontend/hooks + frontend/patching_code + frontend/javascript_reference + frontend/mobile + frontend/qweb + frontend/odoo_editor diff --git a/content/developer/reference/user_interface/view_architectures/button_attribute_context.rst b/content/developer/reference/user_interface/view_architectures/button_attribute_context.rst index 9bea9acc2..eec05a0b3 100644 --- a/content/developer/reference/user_interface/view_architectures/button_attribute_context.rst +++ b/content/developer/reference/user_interface/view_architectures/button_attribute_context.rst @@ -1,3 +1,5 @@ +:nosearch: + .. attribute:: context :noindex: diff --git a/content/developer/reference/user_interface/view_architectures/button_attribute_help.rst b/content/developer/reference/user_interface/view_architectures/button_attribute_help.rst index c06abff00..e2f69d76f 100644 --- a/content/developer/reference/user_interface/view_architectures/button_attribute_help.rst +++ b/content/developer/reference/user_interface/view_architectures/button_attribute_help.rst @@ -1,3 +1,5 @@ +:nosearch: + .. attribute:: help :noindex: diff --git a/content/developer/reference/user_interface/view_architectures/button_attribute_icon.rst b/content/developer/reference/user_interface/view_architectures/button_attribute_icon.rst index f1ba26cf2..b9f553922 100644 --- a/content/developer/reference/user_interface/view_architectures/button_attribute_icon.rst +++ b/content/developer/reference/user_interface/view_architectures/button_attribute_icon.rst @@ -1,3 +1,5 @@ +:nosearch: + .. attribute:: icon :noindex: diff --git a/content/developer/reference/user_interface/view_architectures/button_attribute_name.rst b/content/developer/reference/user_interface/view_architectures/button_attribute_name.rst index 86996cfa4..43938a320 100644 --- a/content/developer/reference/user_interface/view_architectures/button_attribute_name.rst +++ b/content/developer/reference/user_interface/view_architectures/button_attribute_name.rst @@ -1,3 +1,5 @@ +:nosearch: + .. attribute:: name :noindex: diff --git a/content/developer/reference/user_interface/view_architectures/button_attribute_string.rst b/content/developer/reference/user_interface/view_architectures/button_attribute_string.rst index dcfb97858..af525fc57 100644 --- a/content/developer/reference/user_interface/view_architectures/button_attribute_string.rst +++ b/content/developer/reference/user_interface/view_architectures/button_attribute_string.rst @@ -1,3 +1,5 @@ +:nosearch: + .. attribute:: string :noindex: diff --git a/content/developer/reference/user_interface/view_architectures/button_attribute_type.rst b/content/developer/reference/user_interface/view_architectures/button_attribute_type.rst index 51701e75e..d3f201236 100644 --- a/content/developer/reference/user_interface/view_architectures/button_attribute_type.rst +++ b/content/developer/reference/user_interface/view_architectures/button_attribute_type.rst @@ -1,3 +1,5 @@ +:nosearch: + .. attribute:: type :noindex: diff --git a/content/developer/reference/user_interface/view_architectures/field_attribute_name.rst b/content/developer/reference/user_interface/view_architectures/field_attribute_name.rst index 1f1cd534a..226a6e01e 100644 --- a/content/developer/reference/user_interface/view_architectures/field_attribute_name.rst +++ b/content/developer/reference/user_interface/view_architectures/field_attribute_name.rst @@ -1,3 +1,5 @@ +:nosearch: + .. attribute:: name :noindex: diff --git a/content/developer/reference/user_interface/view_architectures/field_attribute_readonly.rst b/content/developer/reference/user_interface/view_architectures/field_attribute_readonly.rst index 2900584a0..f7e346706 100644 --- a/content/developer/reference/user_interface/view_architectures/field_attribute_readonly.rst +++ b/content/developer/reference/user_interface/view_architectures/field_attribute_readonly.rst @@ -1,3 +1,5 @@ +:nosearch: + .. attribute:: readonly :noindex: diff --git a/content/developer/reference/user_interface/view_architectures/field_attribute_required.rst b/content/developer/reference/user_interface/view_architectures/field_attribute_required.rst index 9022debfc..814d83acb 100644 --- a/content/developer/reference/user_interface/view_architectures/field_attribute_required.rst +++ b/content/developer/reference/user_interface/view_architectures/field_attribute_required.rst @@ -1,3 +1,5 @@ +:nosearch: + .. attribute:: required :noindex: diff --git a/content/developer/reference/user_interface/view_architectures/field_attribute_string.rst b/content/developer/reference/user_interface/view_architectures/field_attribute_string.rst index d32e88cde..7c4d12c7b 100644 --- a/content/developer/reference/user_interface/view_architectures/field_attribute_string.rst +++ b/content/developer/reference/user_interface/view_architectures/field_attribute_string.rst @@ -1,3 +1,5 @@ +:nosearch: + .. attribute:: string :noindex: diff --git a/content/developer/reference/user_interface/view_architectures/field_attribute_widget.rst b/content/developer/reference/user_interface/view_architectures/field_attribute_widget.rst index 089f657ce..046741b51 100644 --- a/content/developer/reference/user_interface/view_architectures/field_attribute_widget.rst +++ b/content/developer/reference/user_interface/view_architectures/field_attribute_widget.rst @@ -1,3 +1,5 @@ +:nosearch: + .. attribute:: widget :noindex: diff --git a/content/developer/reference/user_interface/view_architectures/generic_attribute_class.rst b/content/developer/reference/user_interface/view_architectures/generic_attribute_class.rst index 606d3e57c..8c41f8e3e 100644 --- a/content/developer/reference/user_interface/view_architectures/generic_attribute_class.rst +++ b/content/developer/reference/user_interface/view_architectures/generic_attribute_class.rst @@ -1,3 +1,5 @@ +:nosearch: + .. attribute:: class :noindex: diff --git a/content/developer/reference/user_interface/view_architectures/generic_attribute_column_invisible.rst b/content/developer/reference/user_interface/view_architectures/generic_attribute_column_invisible.rst index 49578ebfc..de883c9b6 100644 --- a/content/developer/reference/user_interface/view_architectures/generic_attribute_column_invisible.rst +++ b/content/developer/reference/user_interface/view_architectures/generic_attribute_column_invisible.rst @@ -1,3 +1,5 @@ +:nosearch: + .. attribute:: column_invisible :noindex: diff --git a/content/developer/reference/user_interface/view_architectures/generic_attribute_groups.rst b/content/developer/reference/user_interface/view_architectures/generic_attribute_groups.rst index 4ea4e8eb5..03f2eb467 100644 --- a/content/developer/reference/user_interface/view_architectures/generic_attribute_groups.rst +++ b/content/developer/reference/user_interface/view_architectures/generic_attribute_groups.rst @@ -1,3 +1,5 @@ +:nosearch: + .. attribute:: groups :noindex: diff --git a/content/developer/reference/user_interface/view_architectures/generic_attribute_invisible.rst b/content/developer/reference/user_interface/view_architectures/generic_attribute_invisible.rst index d3d6849f0..c1e448595 100644 --- a/content/developer/reference/user_interface/view_architectures/generic_attribute_invisible.rst +++ b/content/developer/reference/user_interface/view_architectures/generic_attribute_invisible.rst @@ -1,3 +1,5 @@ +:nosearch: + .. attribute:: invisible :noindex: diff --git a/content/developer/reference/user_interface/view_architectures/root_attribute_banner_route.rst b/content/developer/reference/user_interface/view_architectures/root_attribute_banner_route.rst index 5e96dca09..e2be02b15 100644 --- a/content/developer/reference/user_interface/view_architectures/root_attribute_banner_route.rst +++ b/content/developer/reference/user_interface/view_architectures/root_attribute_banner_route.rst @@ -1,3 +1,5 @@ +:nosearch: + .. attribute:: banner_route :noindex: diff --git a/content/developer/reference/user_interface/view_architectures/root_attribute_create.rst b/content/developer/reference/user_interface/view_architectures/root_attribute_create.rst index a7b1f6f34..a3c3e0630 100644 --- a/content/developer/reference/user_interface/view_architectures/root_attribute_create.rst +++ b/content/developer/reference/user_interface/view_architectures/root_attribute_create.rst @@ -1,3 +1,5 @@ +:nosearch: + .. attribute:: create :noindex: diff --git a/content/developer/reference/user_interface/view_architectures/root_attribute_default_group_by.rst b/content/developer/reference/user_interface/view_architectures/root_attribute_default_group_by.rst index 419486bc2..2824700d1 100644 --- a/content/developer/reference/user_interface/view_architectures/root_attribute_default_group_by.rst +++ b/content/developer/reference/user_interface/view_architectures/root_attribute_default_group_by.rst @@ -1,3 +1,5 @@ +:nosearch: + .. attribute:: default_group_by :noindex: diff --git a/content/developer/reference/user_interface/view_architectures/root_attribute_default_order.rst b/content/developer/reference/user_interface/view_architectures/root_attribute_default_order.rst index bc3a9c0ee..5b1358f97 100644 --- a/content/developer/reference/user_interface/view_architectures/root_attribute_default_order.rst +++ b/content/developer/reference/user_interface/view_architectures/root_attribute_default_order.rst @@ -1,3 +1,5 @@ +:nosearch: + .. attribute:: default_order :noindex: diff --git a/content/developer/reference/user_interface/view_architectures/root_attribute_delete.rst b/content/developer/reference/user_interface/view_architectures/root_attribute_delete.rst index 04a290b4e..c0b2e86ff 100644 --- a/content/developer/reference/user_interface/view_architectures/root_attribute_delete.rst +++ b/content/developer/reference/user_interface/view_architectures/root_attribute_delete.rst @@ -1,3 +1,5 @@ +:nosearch: + .. attribute:: delete :noindex: diff --git a/content/developer/reference/user_interface/view_architectures/root_attribute_edit.rst b/content/developer/reference/user_interface/view_architectures/root_attribute_edit.rst index 90fe2f860..8642cdc53 100644 --- a/content/developer/reference/user_interface/view_architectures/root_attribute_edit.rst +++ b/content/developer/reference/user_interface/view_architectures/root_attribute_edit.rst @@ -1,3 +1,5 @@ +:nosearch: + .. attribute:: edit :noindex: diff --git a/content/developer/reference/user_interface/view_architectures/root_attribute_sample.rst b/content/developer/reference/user_interface/view_architectures/root_attribute_sample.rst index c41d31e6e..cfc46339d 100644 --- a/content/developer/reference/user_interface/view_architectures/root_attribute_sample.rst +++ b/content/developer/reference/user_interface/view_architectures/root_attribute_sample.rst @@ -1,3 +1,5 @@ +:nosearch: + .. attribute:: sample :noindex: diff --git a/content/developer/reference/user_interface/view_architectures/root_attribute_string.rst b/content/developer/reference/user_interface/view_architectures/root_attribute_string.rst index ba9ace025..82c89b229 100644 --- a/content/developer/reference/user_interface/view_architectures/root_attribute_string.rst +++ b/content/developer/reference/user_interface/view_architectures/root_attribute_string.rst @@ -1,3 +1,5 @@ +:nosearch: + .. attribute:: string :noindex: diff --git a/content/developer/tutorials.rst b/content/developer/tutorials.rst index d4aedc5ed..d133a3eab 100644 --- a/content/developer/tutorials.rst +++ b/content/developer/tutorials.rst @@ -6,42 +6,52 @@ Tutorials ========= .. toctree:: - :titlesonly: + tutorials/setup_guide + tutorials/server_framework_101 + tutorials/discover_js_framework + tutorials/master_odoo_web_framework + tutorials/define_module_data + tutorials/restrict_data_access + tutorials/unit_tests + tutorials/mixins + tutorials/pdf_reports - tutorials/getting_started - tutorials/discover_js_framework - tutorials/master_odoo_web_framework - tutorials/define_module_data - tutorials/restrict_data_access - tutorials/unit_tests - tutorials/mixins - tutorials/pdf_reports +.. tip:: + If you are new to Odoo development, we recommend starting with the :doc:`setup guide + `. + +Learn the server and web frameworks +=================================== .. cards:: - .. card:: Getting started - :target: tutorials/getting_started + .. card:: Server framework 101 + :target: tutorials/server_framework_101 :tag: Beginner :large: - Develop your own module with the Odoo framework. This step-by-step tutorial is crafted for - newcomers and any other individual curious about Odoo development. + This introductory tutorial is designed for complete beginners seeking to get started in Odoo + development. It covers the essential aspects and key concepts of the server framework. Learn + to create a simple module from scratch with step-by-step instructions and practical insights. - .. card:: Discover the JavaScript Framework + .. card:: Discover the web framework :target: tutorials/discover_js_framework :tag: Beginner - :large: - Learn the basics of the JavaScript framework of Odoo. This tutorial will teach you how to work - with Owl components and introduce the basic principles underlying the Odoo JavaScript - codebase. + This tutorial will teach the basics of the web framework and how to work with Owl components + by customizing the web client. - .. card:: Master the Odoo Web Framework + .. card:: Master the web framework :target: tutorials/master_odoo_web_framework :tag: Advanced - Become an expert in the Odoo Web Framework. A large variety of features are covered such as - fields, views, and even the kitten mode. + Become an expert in the web framework. A large variety of features are covered such as fields, + views, and even the kitten mode. + +Expand your knowledge on the server framework +============================================= + +.. cards:: .. card:: Define module data :target: tutorials/define_module_data diff --git a/content/developer/tutorials/backend.rst b/content/developer/tutorials/backend.rst index 8739c4d9f..9249e97d2 100644 --- a/content/developer/tutorials/backend.rst +++ b/content/developer/tutorials/backend.rst @@ -8,7 +8,7 @@ Building a Module ================= .. danger:: - This tutorial is outdated. We recommend reading :doc:`getting_started` instead. + This tutorial is outdated. We recommend reading :doc:`server_framework_101` instead. .. warning:: This tutorial requires :doc:`having installed Odoo ` diff --git a/content/developer/tutorials/define_module_data.rst b/content/developer/tutorials/define_module_data.rst index 1c1e912fb..d115be32e 100644 --- a/content/developer/tutorials/define_module_data.rst +++ b/content/developer/tutorials/define_module_data.rst @@ -3,11 +3,9 @@ Define module data ================== .. important:: - This tutorial is an extension of the :doc:`getting_started` tutorial. Make sure you have + This tutorial is an extension of the :doc:`server_framework_101` tutorial. Make sure you have completed it and use the `estate` module you have built as a base for the exercises in this - tutorial. Fetch the branch `{BRANCH}-core` from the `technical-training-solutions - `_ repository if you - want to start from a clean base. + tutorial. Data Types ========== @@ -193,7 +191,7 @@ When the data to create is more complex it can be useful, or even necessary, to Data Extension ~~~~~~~~~~~~~~ -During the Core Training, we saw in the :ref:`tutorials/getting_started/13_inheritance` chapter we +During the Core Training, we saw in the :doc:`server_framework_101/12_inheritance` chapter we could inherit (extend) an existing view. This was a special case of data extension: any data can be extended in a module. @@ -251,7 +249,7 @@ works too if you are in the module declaring it). The value to assign to a field is not always a simple string and you might need to compute it. It can also be used to optimize the insertion of related values, or because a constraint forces you to add the related values in batch. See ::ref:`Add X2many fields -`. +`. .. code-block:: xml @@ -298,7 +296,7 @@ You might also need to execute python code when loading data. others. -.. _tutorials/getting_started/C_data/x2m: +.. _tutorials/define_module_data/x2m: Add X2many fields ----------------- @@ -362,7 +360,7 @@ In CSV, the title of the column must be suffixed with ``:id`` or ``/id``. "child3","module.parent","Name3" In SQL, it is more complicated, see :ref:`the advanced section -`. +`. .. warning:: Data can always be deleted by the user. Always code defensively, taking this into account. @@ -373,7 +371,7 @@ In SQL, it is more complicated, see :ref:`the advanced section Advanced ======== -.. _tutorials/getting_started/C_data/xml_id: +.. _tutorials/define_module_data/xml_id: What is the XML id? ------------------- diff --git a/content/developer/tutorials/discover_js_framework.rst b/content/developer/tutorials/discover_js_framework.rst index fe178dd89..ca4f4d80a 100644 --- a/content/developer/tutorials/discover_js_framework.rst +++ b/content/developer/tutorials/discover_js_framework.rst @@ -1,8 +1,8 @@ :show-content: -========================= -Discover the JS framework -========================= +========================== +Discover the web framework +========================== .. toctree:: :titlesonly: @@ -10,12 +10,12 @@ Discover the JS framework discover_js_framework/* -This two parts tutorial is designed to introduce you to the basics of the Odoo Javascript framework. Whether +This two parts tutorial is designed to introduce you to the basics of the web framework. Whether you are new to the framework or have some prior experience, this tutorial will provide you with a -solid foundation for using the Odoo JavaScript framework in your projects. +solid foundation for using the web framework in your projects. The first part covers the basics of Owl components, which -are a key part of the Odoo JS framework. Owl components are reusable UI components that can be used +are a key part of the web framework. Owl components are reusable UI components that can be used to build complex web interfaces quickly and efficiently. We will explore how to create and use Owl components in Odoo. Then, in the second part of this tutorial, we focus on creating a dashboard using various features of Odoo. Dashboards are an essential part of any web application, and provide a nice starting @@ -23,8 +23,7 @@ point to use and interact with the Odoo codebase. This tutorial assumes that you have some basic knowledge of development with Odoo in general (models, controllers, QWeb, ...). If you are new to Odoo, we recommend that you start with the -:doc:`Getting started ` tutorial before proceeding with this -one. +:doc:`/developer/tutorials/server_framework_101` tutorial before proceeding with this one. .. note:: diff --git a/content/developer/tutorials/getting_started.rst b/content/developer/tutorials/getting_started.rst deleted file mode 100644 index 64c2aeb9d..000000000 --- a/content/developer/tutorials/getting_started.rst +++ /dev/null @@ -1,47 +0,0 @@ -:show-content: - -.. _tutorials/getting_started: - -=============== -Getting started -=============== - -.. toctree:: - :titlesonly: - :glob: - - getting_started/* - -Welcome to the Getting Started Odoo tutorial! If you reached this page that means you are -interested in the development of your own Odoo module. It might also mean that you recently -joined the Odoo company for a rather technical position. In any case, your journey to the -technical side of Odoo starts here. - -The goal of this tutorial is for you to get an insight of the most important parts of the Odoo -development framework while developing your own Odoo module to manage real estate assets. The -chapters should be followed in their given order since they cover the development of a new Odoo -application from scratch in an incremental way. In other words, each chapter depends on the previous -one. - -.. attention:: - Are you following this tutorial as part of your technical onboarding as an Odoo employee? Then, - we ask you to complete all the chapters before joining your new team. - -Ready? Let's get started! - -* :doc:`getting_started/01_architecture` -* :doc:`getting_started/02_setup` -* :doc:`getting_started/03_newapp` -* :doc:`getting_started/04_basicmodel` -* :doc:`getting_started/05_securityintro` -* :doc:`getting_started/06_firstui` -* :doc:`getting_started/07_basicviews` -* :doc:`getting_started/08_relations` -* :doc:`getting_started/09_compute_onchange` -* :doc:`getting_started/10_actions` -* :doc:`getting_started/11_constraints` -* :doc:`getting_started/12_sprinkles` -* :doc:`getting_started/13_inheritance` -* :doc:`getting_started/14_other_module` -* :doc:`getting_started/15_qwebintro` -* :doc:`getting_started/16_final_word` diff --git a/content/developer/tutorials/getting_started/02_setup/account-settings.png b/content/developer/tutorials/getting_started/02_setup/account-settings.png deleted file mode 100644 index 90392e7b2501d40471b92566b1c6e668619ee4a7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20025 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 diff --git a/content/developer/tutorials/getting_started/02_setup/settings-sidebar-ssh-keys.png b/content/developer/tutorials/getting_started/02_setup/settings-sidebar-ssh-keys.png deleted file mode 100644 index 67c61910afe66ce700f3a39bef26a766b64591ce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19437 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 diff --git a/content/developer/tutorials/getting_started/02_setup/ssh-add-ssh-key.png b/content/developer/tutorials/getting_started/02_setup/ssh-add-ssh-key.png deleted file mode 100644 index e8a103e3248e1da02fca2dfd3fb11faaf353967c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10485 zcmbt)bx>Tv^Ct-jNeGYxg1ftG&|pCpcUUC2E$*I#0Ks7w*C2}qhlRz1yTjt{?k-1? zZ(Y@|>RWepb^pA6^{Qv4yQin8`|~ik92?>?9_m_VVS+nI*+VB&28Bo@!doDu!-k_KtRDmLO9yXAgT*GE;X;GbAMU=~N9% z+fyF2y93qJm&+`~LDOI6e|8=~Iw3ToZ@u%L0ZD?_k1wSMtM0G74Ezk=R_I$PH^6bx zY^M2+lzOdGHX=eD`Vksu$0TagK24qKuF>W_1KxebB*eTl?f$Np?IzOr9 zM^E+~QhNqlNx<908a@qP#6pTK=ogf$3CC;Wb%KgINJyB2QHH{J#>jlcHLNc>!j*`7 zXm(SwiDGUq@v4JPMZcy8rJObyeAt2pt(BbRI=nbL?v3&>IpS(^cq#Kn*Db7Ew3C@ z?9O{kCk}-2wMHn_wzBgYU2LO724dLBs6UgD<^C>+_THe+#{yKbH5|XKM-j`!6SXv) zEm_)jJO?US9Vz18-2FDqo>!{>sqYn*Q{O%#l6jd9c6uh`JK?JzA(OpmW4=3wULTq2 z_RA&Pdt_;=wSTiQ^!f-a@8EwdykRn-(=qBzIn;l<&!y-2wvZTSd^@f*(aYcC%P%hm z>o@*E(@Fgkm6&5QwMi8%8i~f8eN#);%?KFtms;tclvh&*^4#~0sRvIV4ZXnM0*J*`F>Sm)7F_d^dIW6YIRmv}}JT$sm$+B6GcZZ%tVcDTM zu9@m!bN$qEEhlP34CfDT@AKeZvQ!(D8eo{f!D&$GN^}&yQ?R^&=8Tq(3I(y&mdHz~B?r zSPc4vy6mjik9aNw+!34WwLE)D@QeXVT`ge!ognFV)gn45zWs>8j=oD+tu@ywuaIj4 zU(POs(MDJleG!4k2^J#^MooQwHK9^SRbU*GAlZPM#z;m3?~C4PEKW1lU|r+%p;Rl!uOMGysPyUxZOfnMw-(L+jAXrIXFXI?_R&G)W8+h zWOYD7qLP-85LI)Z-b)QvCERE@7&LHPPt%{4;1HD}QYTkek0`b^(Z;ZPN!=&ul=wrH zCJDe%n?+wKH%2a6O=XWk)8GAiBF2aXKSVvVK%6fLAjwaWglA!uO(mU(B|{9H`7WKC zZQXfv&4+Q};d)jMb`|COY=qc1#o;Ng0eO#B%BkdVj*7sy`!eftdf zOG>H#l1a?J1oY}Jfj#?6fPW$<(ii3@e@JuOpC{6Ph9UjmS^mvTME3O}E-lUP+)Ly@ z>2}u;)bh#EfAv*2{@)et6Ny|sW7oH*D2|HB0?dB zt6%uALL@ZofBEB#Om&RGm2R?(9A=eo5TRjw)VSpI8~#6BsC0fKtGuo;)(io4(vQaP(K* z3%-R9XZ|nr1JK6Vs4qeSR>z|&sXGweg^H?(u3K3Oi0LbBns;f0R--2vCiqi}w)gIT z?C`~lsC|$m@YQ%tbUl9vtdbp+!!ybb`E{>t6^KhIpDW@v+S&TY{>^beMcpcy*UaiH zKIYjZMPJk7x^Cs|)WpG)1xfyH3G5lLw!$V@Z!@E}G8u&eyaR`iU606`P`1zS9tBwd zrm%UNyk!v|Qr}Vs&gl}lxoT}4JH_U78##qN=hYrQJ6B1!CeYoWYKzuQ>S#<5;jiEr zT^OC$)#=zzdkOuZ=J_Z^Db&k`hGoZ%ZtJOy_=f#w|0RsuOYw4QSDS38PHfF7sN}1G zU9mFZ3{a;?zQxKptD@#S<@H(q76PuxI5KcK-St~%<7xU(*uqp>2~d-;h?#hgrr{Hx zO|KSO%cJWp+Jm-+b48}-;h6Wsi7g}tihfR}JG*wIcLeuGmsrvErz58O*W3{^A--H^ zZHaT|yeti^`Z~L(alUtO5d%PqpRD%)?1Y|Y&$2!jWNA(-G-FIBIF@5s?kw}GavR->(4FEaU%QL=H*CFP5ZOcW-njI)VSocfzXxfQoL{ZUn(|~?7 zt*{YIRX2q%c<{~cdfkdoMXHW;G8XXdh3p=kwYtf zj^`uo4>y5bad~&Q`&&k(+h^&*6{}YB#(v?jQ}+${MZ(@;r0R76@>~C+En_$31Iq$4w_mGCIat(LHy2^uiio+ca1_IQT=| zLVIFC9x}`i$-iF9u1+05ImekulajKCk)EkmlQZ|8rOFnaY(*hf>*C6JV!+p)nTCvn zRO14B@5J47B@hTmITq3>hjOwq8OYu)hj->9H7E!h2;O`e%rDwogLZo0!u#}>##h5X zdIER(X+0uk)@t@nCj^>;<%LdwUMs~n`ONB2gPu4AAqU~#t2oaWwguCTMpzRzFNEhk zgrn>13$D0loctPzgrrhS*zwF98({(>Fg0eezE2h%bEY_4d6r}?kEiEFt!=)jwmYMl zlRB8^yCq){99q@j$T<=_=TZdeHmd9v%TkR{x+h9*)$klx(poZ^%|U3WeS|j739|_k z%9@m!JVw{%r5TkK>qwDzbzSREQz0Heik9E{O?@B(xlx-?c=?^{E0BV$N6tI#i-Y_TDa23?g@+mL~e<5@Y{1BkMAHP*AY>} z2(%>kh=)1Ngetl#3cp9&fFaxH&v4?x5UuCebwhCs*`jL+gY&C@c8IHBZ0Bb*dB9YI z1`X@dlR1(l#@$~JQk1w*m~$}0OQGFy$eaF2QhuLu-*Zrkp67bxQJV*XGWyxc@Rq?UOPr#+&~@9D z+dv~VM=U~7s)SbIPS)119~Sdk@NPl?&UkS6dL*B@D9GkHaz)~RU|RZ@nR)&?XU|k3 z9uL|Qpb>7WRV?48%AQCs26oeDI#13{(n@AaoxtEGV}<$EUF^c29RW4|Rqz`eKstAPrUc>g_o04P;}! zSMQa`UhG^`x(fhC>QmXzD(zRv=^A}Gilr6|QuM2A*LR0&U!FS!&&JxUx2E&VPZib& zU<-zvzkkT_0muVHhYg%*GJvPiydl>CtgZRSxkDjeN@rgwXLY=I> z;F+c-^W_2e`@NC1vqQ+)d~Vte+wZsRwUw#&oJ~D-@5>p0F1|qnZS8_M_eEmF5JF6T z)dX!u7Qgw6qoA`!=&uEtjV`r4toAL=B~c!Jam^$3KDD5n>+l$+hh;jKgPLUB=pLS4 zwfj7sdM%NMa{q|Gxxg3kQfLEAQ<220-EkL+wcx39QGM|+x4>|}4^;FCx{crcB@*IS zb)jtJ)t9cAy#I~&WhvwS`mL%Z%-4>LNYT6;&IHLBRcyFT4tdXCmk!@rd9$ZC-v`2d z(A3}$QD|K^7P;OJuF_@yRmn9uzzQvwhZeMa)+sj-_bu2(jVbEwK^<({n(mkY+$5S- zOHw|oR62Rgd}c9#H~}K$6mWe0hSCbR*PZEFvPRzBT@hvmvC(+wmo=O-j}1wSKku<%v}bpf;T6rg;@SI}>One6RFS zu)m)0mUkPcKWmNWmNMYGWsIkFuC+Hg%iY>+NHT-+Qc0?szR}pmR#oCDKY_Ojev&}S z{+2XK!Jqs1d}^dDUSU?`bfNL8-wxHBhP3gl?;@hXB4>%(&}+@)cgnuBO)b^}nSDIv zZGYXZfxw@X5hLgztZEo4`N9NnfljbrcObmfx7u3m`>W(3e&uXs{rU*&Ok{&sG&y9z zc_RV^_iMtsmN0h(xXD2X0Fudx!`;PTx(KVc`$5A6$t5fV)X9b3dGF?Q*EDZ<;t+x> zM^*9}AoX?G`Zu)!@8euZL~NQR`giH(x;|;z4(|N-XTle*V3~KK z;h!otc)`Z|4@V*lL6@9k_b%1mlyK4G@2hDJJ$@ zg6c?-t5qYKlU{@S5u-Bi%cY=TiRHFntT)1!i)jmz5!yh5Ci^3b58`_UZachSLMp{Z zzRg#B|MLBk!*NXmy#~*-GlYTPYP6IJ{k0~2R}-yb+UyA~spn>fGk?DW(TCQCl&}AE zV%g{jCqxwM)!8q#3=Kt%TQQ@KrZrv89r#`-`dwpzUj37C?JeT!xR;gHpz-$i3sS+G z-HM{3qAh37!3BzMrd$NU#?f#7)g!ZaEzWn>E^(#{eh+uQfB)_z@d7CtQb^q|z7V;* zT!{>3Chi!q{8tV|6tf9E&a}6;7c3!m+|?V;Y6k+{9tMecZ$aZ>)z#g0L7=*!K!YmsQMd9u>M~U3; zYqCoJVTweByfvvM_kXMMjp6tIDAKCu;#k;#lck2Of#`%hASrY4fA!sBM9BYFO^5W) zJV^huTKs=6D0_kY#ERj2Vm3@Q(8a+>Y0$i3_CXTXRR%MD<2e!HFD!g@JUxPrCQ;PY0-XzGWWxjbdp zKB^Ph)txabxdzBdhO|31ANOZf#=bkoT_GEQuF?Ds(A4b%1-sSomqL5$jbs!Gh)#CrQaGzy;!qyL>2w?t zXv=yUT;=CEYdcJ@Ub|i#4FyT^4%*6HRN-|ia?2MD496B=_7$oVB%@WV|ng((FPMPvN964$Nl!QpEAX2t+G^hw3YCQf;L_yC`Pg)m(> z>>e)B-JIFJ^K!bXzM8$4#Fs~@dt)-EjR+Tu#0j?PatgY3-EfxMJTA9hiO}%ZfhrST zOv*U9mnN^;`+mwvkd!m2tWJHfD)eCz!(vGaHePAGXDLjYeVH*iw9wP0ZhWu`; zceUah)ns;Vu8Vu;o;s{;;rge&z1g&e=5G6myuE1HL|~F^b?iQf@El&(ce>3K5nL6L zmi`(-IHp=FD)Dn%=!x(~yp)$T25%J6J`ozKDH!Pd!?Q%CNo>E|^7E|xv65Z#56#oJ zJ6J3_N-|}ja=uRp$MPw3AP zIwcmDjcNBJ`HM;ndGt|7vC-XdYH`Zc%JLn#Vk618JfBJu{2(3)og5nOZzO|E=mK(; zV_VYsK=8IUv`0&ry5jbLK|K)m`?Fd6Hl-zCw>DRObc}G(*m5>!VNN^EEJ@nNphgK% zgY5>Hm%nG!^FfUlI4hQ&v=(0LZDOkfT`P8UIpc^@8sj)?isk${fh6p7P#j2S2G$sFMo&Usj z&O{@9i7Io9cej`d1F}h!20Q*-HI*tJ5=h1bP|4|}P(%eD{@5fbZW4gyb}}4oR%GK$ zooYC;#Gb6PqibaP{c{QB2S+4JQ5>v9CWtQn!I%~Q9bCvJ_%uFymKB-+vhpbi!V6|i zwj+|M*4x6sZxS!Eal0|@Rx>i3%+Z*-EKZ%l>6ZY2e?pP&wpjmApPfxp59NIa^;= z3hi0chfKj+S>R~0fQ4Nhe*8$eC?Z%GXb2~fr%_&rvyh$!&SRN-$Ef-U=}hG#s?b?S zzqiNF6=hE{oj4hbK~h&tSRrqwE$gJjgH60WDnoyOpvtw13oz>LrS@90(Whq@IE60 zCto_nUc-C+T|+?or!T!7{@Kfn0%n&a)S}nz>+^~BA>D2Mw#Oc1EvR#mVxt^HH*7DXd431 zT|7J0Vqj`ZqKq=k{rZVwj0j;>AjO3(S!pfK)Mt~PW?!qI(x$03pgffK))rF0rVzzK z1+@)WnG}>867B3`S14vfngr9qvYi5t+mkdQ-Pv7VYn0M;b`tvIz08c6qt~)+EC(s4 z-0gb|h@xaVzZTjAhbVNen)!|;YlU;9fU>t?e4D;60g;J#1!sW%GUKSi}=U!@K?7mo>JX(~H&w|Akd ztAo*scf~AJ#542xb)rJTQHo5(v}5yqJ_z@hwWLx9$e)t?RrPwqnM-~;nuaOL{6?M( zXz7L)C{{7|zl~OR3&XAdp14g1a3c4DQ^&K2*sfA{H+0Borq7uzQ%$SGd6dj(6#jY$ z3NX_&=e<6(^JIZ#1{5~~-h7wn-l*1vtpiWwQxIHY)I>Q~7wEdb?Xr^EWRitZsY@4_ z87FFUbZx!U*zLwfK>}j-w}s<~O_<2#^u@!(+J1zFyKZi-iWO%0F_re%mvcIJk;u?i zOl&kz+QwH@jQ2%?jJyWhqNAVK%(~r+d%+{hP-4=Q;5y;EQdS9IWs&Dp zq6t1$u8FyMe)UilKs_B5m>HjAp%fqXH9h(rwf_W0W5%M!b<(9a+x71R14}aXT-P${ zd{^}x^cY|@RWw>6D$t*K*vb^s<-ssM;$HKTS9-lS zgf=Ghk3;m>1kd1EYZBa`LbA&Po;1gWOeG;C2Hx<8C-JMR+n29XPGP%M z$Rb7rxY&ucLTJpqxVWbWwK&~8ehn_;8es`|{9qpb)=Gt0@X zS8ELBKfVjQ8|=iXXPW=U=`2-g+$>(k_<3-X*y9+Xc{4F^91uGW#fo2PvjwN}nghHqYxA=P zSI(G!wP|#A4Z&ODOjs&L;x@yy&KT@Q%nQBzyW#sZ9Hlh!6%+8c)DNiak;&E6zBDcD z>Ck2Bup3Br6|;2!vez_tni{T>FmON@K6hu#SrHoDKNQ7wIUmHl$4gz$yf>T89DE#t z=Eww<619Ba#vzfrB2k%OD6Rn;&btIAfZCNl7Ke3DfpyQ` z&4A173{AlpE@Gez|FOx9k!2H;?@@f=Yf%L;Ku7$x{uq-~a2a*5t9mhdjNY1FY8ZhH zJ%bHk`SUAF&}*1UjSLV>|91~LOnaIetvV59P|y!Fi5V$Ci9j?f8WKz`l-U$vCg{Xo zJX8ucDDghdo1nDhQ>)CR5VFdrhPByTOVMbwRmG5&5qHTE`Jl&=Kd5}^`NH||O!vs< zY0LBPDOT92jqqUgc_waVup@NQUdkp0lQYt(TJ~fIyi3>^Cae;Dj-}y3Nciv zpwZXXtxF?!5yb`)G_1{vCOzO4#j?vDL>H->Sa@pVLwC^q+TBe_TO$6W@Xy@5S{kC;^{ zwF*nJy2gbOMRNaR%FMh>f8t0!xg*UYHyuBb!PZ)??aQ2znNgr1+ZJc>ob9}SRK2gS zpc+`Tv4bW8vzL?N>GhIOsT!Mh9WU=c$}2Zd zP7`9M_q7e5NO{*wjt`A3r5&=e7BLNa-RM*X)H!_iO z&)JuODPNndLSpOW_)ihjf*BHlEHk{CCC50$z4EOPvF_D4&n+~&j4~YV*=%csYh*DM zhi*8mE$CF8z_$w27@kuo;dMm~RZbrj(~L9=;G}a-o$oSZfU#LvtE}a+nb-uUr&JA6 zclnS_t+DZp(O*9MPlhPb5$7&Lj7g&X8R4CUc_3EkOA~?q25-Ca7So+$plk?x7T{nQ zTTLTkS5?j2J<-@AElwGNf4Gq6CRcRG=&fgFYFVH&h9eWl?g1<)5C+2}NEbH|5YQ^_ zId~+moPT2ig7y&gy=R*qrc)_OX-P8m-a|(HEI(-*o5P@1FV+qjKn-V@!|skMEdAE3 zJ^On2biF6cU-(j^sz;zbUd4_|hO}*qW`QLJs%Ja952FHFm`-mv(#Oyv-xLtv`a&2> zqh(J32a<*LZe`T2bK;p1ctwu721>6SqcFu*d1w4BzrDk+7vjuUeE3-xY~?# zvyy0T7ey>nmbbGP@~!tVd3k;h%0p*vz+}}mL(uHu5I0FQ%(3I(?UCte>Rh4*9b)Sg z`nYTJWvnV(4|KO6cds%^3?8jFB?)hf!1V7?o_MMz9Y?y>ndjalRbDN9b{rV~W%XA7 z37J#kZ8FViwkD@rg#0-WO$F8#4OY_Zs@>JC-dwU$ZtedhSd^{#nDkj!QR@q%-B~Zw z5&_~ZNm+yw`)mf*u%>wMQb@TD3<0O^=76QMCnOKqdc7sxv3(r`uKTH&_`u~%NNV=& z$r4>=pbKWn4cOhkSs^a(qxjO-oZGBvms_XxtLhoVXMkf>$s#+tDPsxzwB<8zQ*$WM zE{;C0&agNjzDy64UwbV*tOPCFDxM%IH?e=Y45%wf?Q~BE!uwQ`4Maey3y47Em6bQR`ETmhl*8e8w<1 zexaX^1}k5qd=37+tSVbKt>T;wKgK7{5Q=9(<2ZXcy9Rp}!3UpWA)YUHcOQCb;md@f z z;#QP9jOgdJnigWc=Xm#vI`bXu2awiJiV|N6k6?{M;I2%LCtf$PPjTkSBxX%r^3CBF zh5RahT;-WJ`G(M)yrfzhUb3t_VXu#xOmyK9Q~vNZ&jWhc;aY3 z{nuB5^be5z?_lEpq4nfH!;t(+nFlu9_3p>?h{ieVE_BeL`VZW1Pk41I zB21~^_}*sggwX)B26G7d`~4<>zFNL-wQCAfWGLi}s#bTeo{V)8Ha2Wsq diff --git a/content/developer/tutorials/getting_started/02_setup/ssh-key-paste.png b/content/developer/tutorials/getting_started/02_setup/ssh-key-paste.png deleted file mode 100644 index 139047c5787da40693a5cfc448dba69628439d4b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14992 zcmeHucU05Mw=at22!aYC(v>PfKr_ujYOeRr+9-uvV6$Cu1x&&;0h?ETrZOJHhXISMj*G7=IJ3I%!4 zOA-=N1`?7Bm493$_E_%K5j#joou4Z}|M=sNu^H8AVw28AR@+70-ps}QwUa4{xt+bO zDX+7!lc}klvxU9O25G$%35f)o0_YjkV-%NSpava6EZJjyJB*pPJ=$r-_m+hlGxI%C zLKR{cHd7s1;9`ju8sHVi9*1JGsGE&quX;^&NtbT+3wVJ(@r*yZ{^;B5ATo~hd*4+g zm_xhd_sP=SGF1A@Cx(R>*qidv?*8leNnVyWtTTIgQ=~%hiRz(AZ`_%oH4f`vO5~P= zM74QJ?b7)NcEI_Qist+YJKynJ(B<>b|B3!@Rr1j7S`6ouq~y-*Ro|Yox~0mpNh3z4 zQD;lUX?F&f!KC-uQ2oZi*p$D&%Y$CMqX=di@}1)Oq##ztf?)ewe!*}HKAJ;hd0KPB96u~IC-BiF`aoWbQE=fvRdPE zGGz!MmopXUYD73$kTsAp^XTJryQtq|uTX1D?el|X+Z=?t=nOZx4C6d49&Jo2#v7%< zR^iD745GD=O6@038XM%MOuWn-wS>f!-vf84usUU3zW1Q+;orVI!yh8%+=yV#E8-;%vRTrqZ$=H^< zUw`{Z6e}LMTetPnsc(@dGbzBMF*W7Vgy^_uQ!lBoVaYhS zh>et!3gk+WPtxIFAuk*)D)Dls$-!qRt3&gocjm;&ScKDlB(-GYB+6Q5CW|qCvTt+@ zp}SlcZCYa4XnlY|l$W2r9WIX-DCABqAinx+YHacuQ26H)|Ml>N!OjmFMyK2yDDkYF zvh~+KcnfH9mAm)xf{<&dkM3DW%T=S}FIr5`rjDFUYK}t}D)gtZ{AL+bGgobWhC|R+ zhe>`OJK9B6sdbsgGW;xOrs_KrX*tT%=Qm>|+8 zNti65#@a0C92BPqsS^&fv)hhV?-td?^VFulC}F`*)a_XX_&D~|UuGLg^icU-Tu*aqvplrBCvmhv_TN?R_K%m8X8B_8a?K z`0Ve;i5nSM^)=h(8a<>!+F91VI((-d-ZQBtsIp4q8y&W>-6+6S8^yrX>%&VomO&jG zXDq^!9|Q)oA~|@)A-10NL^XU+p)hlXJDIaf4Bpjf&R6=nh=0lTc3Dldghx&!HtYB+ z*Z3V*la6K;$*EBu78{>>ww-5XO_Z7yVj34nrp+Uf?_sa|jHcW+ZsY_ScK$R?DQl1( zPck^z%7Y`xIM+I^ritQxx9j)b*@Q?q@bF#i_M8IuN5uO>J$0{S$1^l`S#1-{n|Nwx zJXyS~uVSU@dTSU?y`4J%vJ0a}VuQ%KQ*!%8zrKPhhFEp$Om5{#gseM z?rczX2Gun~4{lD~66frMoV<8opkq3w zv2|gjKs-16FxX#?Xsglj$cvsWUTOWplRq*D{y?oS6xWRKTX`u+sk^*1?-nQL^DH4B zx?JsJEOY~hZ_@dc6bTd;Kho2^_eOnc409d+#bjI0bZ&x_#h-;y)Xk-a*HQY5M3v81 z`(u`Fh#no9Xya1kV2V<^n?DiOJ=VXKk!oL+_%(<(xvhnfp}0{2t=9+gHdr1h;| zlMWi^B-L!zHl5e05A<*SS+#qe(|H58J(c8hn;`VYVK>(sQ^s{EW9ebaCIEAI%+}jx zx!C2((#HHM*x|-VM$0 z%9*5LnHDJmBZ9B{MX)I08R|^em|SF~ULw_tw3yUs6cb0k6iysy5{&uw@~#ta3aMQn zw8O^K3v71$DQQ5w$i@eZDZk-HUi$s94ujL&F1ZD1FXhuAa`Q&j-7Zms&(wZWXO1rR zUy|_+_Z#~+0z(iw%rB$nt4B`_dqa3TX!8BH;w{~b$=Wv zNE;o$^k4uPq0Zybt~V^OcF%0X z(_9Y!B;UrR21Oa{g79pR_mqv*9fMAH%5+TFRR*HFy~&CiS`~S zIBfcqo8X3ib=5R!U+iRqup-lU0|WR#Efn+OMMlrm;hUYy=-2svqaJM7#jGYXEi#qJ zUkQ(HDRa$ae@TrR63r8oHCQGqr#SH9q1*_DM<|-`AAB_E!zcI12qsh)F4b@L^(|%S z3PE^>*UDCa?pc~{pQus=wB6@pr}e)a_7sN6Ox@nTgxC#2>|}*ncdlO}A(4&;p^G2k zdU%%o`5G+nOA!;fp^0y-bULJ)HVAP0sxN+zx37k0tNoy>oRKH%PMnN)@mXHT@EvuN z@;{y&+I+m6y36~qDi`IF27&je&zI7MQ`Y(TJmQu)LZ9InN?{@|yU0R(d<{M5Ro9Gl z&EHSSQz!aCm*5=Jsng*|qQsiIr8egaxyr!yhB zx8_tI>+LwI&cn^$B*1fvT#pa6>km%^Yx#X1?XQvV0XCkPv0*PvAKLL}n3kC_WNglP zy$60cL?3vqo_Tnj@r*@Bi`aWF6og6}x_^}Olsn0r-7k4)K80u63OOjxS??$~<@4%( z&jp5(H}KP4_bW(W`NL5vv_Ui@O7k| zh^Rzo;#vZPWzQQwcXa98)3^uW6_odkjcglm zXJi~`YJyhKD@|$5|6qN7sQ)$*Nr>IV2Z=oN{P|A@<-gYNhXM&NI1#b&>|8axcfBhPtRlVWK z!RNz%(H4x|c#KO0B;AF`%3GpvebMijsCIS_c33k@%qq80h4@bxnZWbKYm7T~Kg18* zCQNX7N1JrA{$?EpxL=nf!wRwOsIWU;vJQ+E{r$R#^K^n}RtQJ<`9g=l>A`V^$FO#S zio$9tlLEu}4gRdL-H=6=^88h!_CcogPRC)m*`;}{$+p&9hHynFkfX?cvTPZ`=*o+5Oe5Kj7DJb3Yj zc&EC|fj@WE2}1K^6t2bbnnZj^KR@E92mwXtM#tlqEQS#Z(DryajO}p3@ry*6Iw|Pc z%uI3wp!&Bc5b5NhgX2t2<*1=u{1N-Aj&#%RN_Q90?U+PwoFtPvnN-PZHQtu^eU8_u zV*9p7-VH^G+Dw)UVq{>czy`k)b=TdGDhgwJ*@hJ}h*ly)uWC7ed&d7f{(lPIf4+ZB z0s`E*%E<}bt)@1n zye=E-arQ1k=?{{JY!H~(!mfvTOyx+WTxrDO(#=~#UlH`TV`n?Fk=h?1$4 zgw({WNf0Ph3mUOo&G%2HU--mV>wyh)F8adrd%EGUwGR@js1~n-p=ynuPq^>=AU0A3E={q z?Syumy!E2K_1F*s1grKq{3ec_J|#^Xo6A@QfdLsN;xLY)A@i$4d4G}M^&*mL292pEHG{XKqsuP#p3*XxRjG_G3py;2H^`D=| znh)aYv)`9Z!Ej@6|9$;YACx?QLEKGpo)Q&jVxmMKi;}JQ`0~p$mz9&y8>&_x`kRV)>1J7sM(;am^v%5ZJ@7NqMbO8vZJ26(LjCzR zH~YqunCQ)LnD0cN)6E?bj zjX`9?WA0>i!(~LFGPP7=jg_5v#UuH42!`^sXt=AbQU7j}z^q30>$uy*e164tIiXND zinek7#94`0dtoTTUc($B?T{XF6`%( z|BfARkI1m!Jad^|`ivZBPU|@NCb_V8HD)DIhxqLe7P&|u=;AH$`BT!VQ81JhTnU_{ zGqrQW_pWCgi2tTgI;TiX^qsHU@QstfvclS>nQrE)C8iih5Uuj8DpEjn$;tb;U(i|r zBF+V@3+!K)JzuzuAhn~a>@{fe7lfJ8{w6PMW#6qX6i!4oGlF+n&h0w2F=~++X7Zc} zNFb08s{#?I&Y_CfAR-bGV{Q@Q>UWbJ5=q3a^JawLPv6ID+PY?~`8CuWw!l;xnz$A( zK*vkT)3V(kWd%=wm^!(W5mB>JO76$}oDOAA_7ZZtzb5ZF4J;;t(cWo&S2xkLIi_*C zq&eW`K&QC*TEU#6iJZx5I9&*~pl(t*7#sw zerZZw>${~Go*s#~R09XpsM(OBaSaZXU0LQ$qr|CczMbfz6zEKFUn_BcS6!X^h+j3v z#0#J3+?7$M@uc@j29roj`y{XzyhGut|L}8%c~VGTRjtynPJ5St`Y81s!q0`|{J!wq zG(U5dYMTXfasgS5M1#*pW=z)}p4295kux6|5~-b2>rmUX6Do;|h?jZJ68g~~w_uNn z$4uKsd~3PuHGQX9$vSz4Fy2y>rZ^+-7(*d=N&8`3 z^4k+2PK8OPz1@9~&AqfK#Ihj0Coa&~RQUF^n}k9Plv*NqVC?bdhYb-E@MpW5T%v{}$JtTlY>-4UNt%fnZEma19JP=Fr%x60Ada;R)9kPu zIC8OyN00^6C5^ihh!Xcqh4YWzHmDAAyBJbBl&lW4y6x`LA-Cg(r7<^MNbFqPaX=)k zKI{}oTiXfb`(?{j5}YJkD`?8oDG^;kFulyN9m)w1jx85=<&{}Eyi&teYW+3DW!7DE z62|6w#~@wYiZ|{h-2ZC|$7$ZZZAZ+8H5Y_1WWIs|L6%I+v?i|~%S&3@<+t6gY~~r< z&h8ABa?P_UDfyn*?2GQL zjm_eskR~{-aS0lh((8Fs2P==)nx3e8rE>5@AvNdp*&x6yP*y53eU)vxT$6Um1m0KD znY|rv9}ph8vf2GIWR%Q6ZDd?6HE~D?u@U-9d%H9^Z`69LNfuhJZCJO`>$-!q7PM%F z-bg|{wr#8HTQ{D`&>z^>q4AxZ_MEjvUt*9qRbe-JSU;+7*DjJ}zObO>GCF5fl^W2O zCsUP5`E{fu$N1;ogWiym?_EXs2bkNfL)(hhM<)Rq>ACs2W%u|6tCv?3Hrtn;e9-C` zh{(5Bb#pb$F9t69&2rlo*TL@rG0ShPD~ejiuxbGEN7Y}7XPjOm!`h{URFnv^(uBgL0i3xW1+ zeG=4bRp{q;T-9=Q1$5$)@@UdQranS|-R?tmD|c<(_l=g7)!#%-G*shWt<{$2_A|G9 z)6Tq(RW^2I(BJP`q8~8GF5E_ygAIy|j^jdwwBJu$UF=}nQho@qe;^$RkB?7WG` z3!1d=$*Go9_tOCb{KnelswJhNs>9rS-#+)}RKGGei*4aTr3Tj|mz0lEg^cfy3(}6E z?J8OiN?N;Ly6@#mR4QxQ8HRH>DOa^j%rsBPBd8R31dECd+%6slByE*$^SK4`e@ppP zXPKd1%(rx$Qk_uO=znXV;7RiJdh z3v_z5caxi7{A75zYu4-o#eRwE4{$)Ry9;~Y7kobNBYCJ(%4I^A>((R9A)3 zg>PNeX83SuP21)ak{goita zFls-EFMs$JHsqOa3n-PT%Q9ZNyy6*KZ~|W1x3Es+0IJ%0T)!R%R}nWIOm$p(i|%7b zmF|N$z)DK$@p88a8DdY-@JF8J$y)x-oj6988m~!4_iK?DorYlV^%4cfpoTFELe(2} zR(EDAwwm$9p9!h?r7EIg&&VH%Iu3>Cq81U0J-R}<@skAXq8DaNcod@fxjetR3Oo7AR=+7X z0Dmjq`v)g#`jt^cDf$7h8ac=*Ic>!|E7LS324JHw?{nrc4SPtLVABtyB5cK_xFhn7 zpH|l36o8?5LSWq@Q%^TCDzTEZe1QJ#^p|qd_SfXy=<0B z!q`Ie&Fw6=KZ^lt4X|-8wkb2zT^>re9Zk&QayJlnY`mUDkIP+<+a6KdutJ=J+lPh9 zY-gOW7B>HLF1e6uS?NIPluPO1p|*SMLplh~qkzNAaixS(95=!AsdCmTlM|KRAwGK( z=O$s$U08+aTz6U<=xcZLTeG@L6 z(kieN@;wG!*j95Yks$tD9a^0ylcvyOUV9(VomKnXKN7dwLbQerlBW&TGKT? zGN+mGt-%TWV%M%b0NSR{@(n!+wTTYh@E{D(}ng9qmA*UYTnEb?jzb#efJv zcqunfZn6@*SEl?~ID7q7b%u?wC~cagbtLa?&nAuXeXpllCod=ikf5g49dlQcsv2Q_ z6xQn`XTbLk9v;7xBX%KXrF*NhbyDLBiaeAmR@|qNy$A7Lr25G|Ss$-0+vw%txn(-1 z7O4MhIPXbKSI()@;K(fXNLI;Y%+;)X4OiRB-daDRJ#Ki+aT>nOnL(K=&oJBs#;MR8 z{roZ!JuQp2>Oe6khr0lg1tk~i?E%YWnnNF}!J$KQcq?4cxF|n{+!!tDky-dO?Tw6q zbZ^0UNtrRxQRjRgR9UQU{mNSMzExaFIG>Il`jgzmL4MXs;^j|W6Qsr&1~^u8_*TZo zHi9a4bUo70p|T@OSyfzDi3~)MP`?9;U2a{EJGsY{e&I!TcQy)~BZ`W65jlq$0GWCS z9X8u&6-2^qJjJlEMgxFs)xj)#0 zy{-!EdAtl3%HZvFWpA5LqUA>JvpqVTpkDt`7c$Z^@Zz#wkD8GjA<>jVNP#GmLu}|D ziZZusBnXGy?|hKnTB=gwTi2UO!%kYOTqw+rnvkjRqb1Ex`UK|K4Gpe z9Z)jMw1?vQqPhx+W_P*!Wgc3-$KVUUwps&CuzsFMXPPbfWaFhDFy}>RitVe;UM!#m zVo=rw=;i&c|Lck|9Zb=trq1cJhNEFLFgs4^C&n6@*GjDqbbn9Uo3tk3_2e2VX+a}3 znBPg@PuUBe80@95qXY`aq;mRd91|YR^Ge#>~DXZWFv_w^Aa2K9y|3ZLT$b9gU290D-l4XeOEWrP{U? ztv#T?{mh~)dMqI@!CGw{h&bgdeZ>_%`EGUDUq0cN?Gw0fyC4$mA> z9NdcgNtszxNCd8cVldo>G+(@f%uOEH<(zgDfh-M1MVRqO6Ltc{L;Mw zHp%fd%y2iEaPt}q)c{7n-R_c>QGxuoJDz`xWW2ZpSf#0LT=|;PfsV0`pEqR(*ynM0 zrMYQY0pY#q@&w3BZY%lqles5 zuQl~rU1YB0v=l5kspu>f=&I{?GBg#IvR8D=7p1-SrAk5WxF0$B6YC`6-cAv(j=)b} z7_?}OPNI;5qhbI84B+W~-=4gCfU+{BFbL0Wn}Fhjj8L(oHjyBjnr_%pM|U`?8_m0|5F{`xdIpj@OrB^2z!;5UWWQ1TnZQ!JLn;z}gzO&QOe9dg$MJwrX2k!_)q7 zrL1~KazK(vt4m{rDz;xYHP%!LyDqPt)y|-j@nWmHZ)d%|u!S9f<5L47;#>ups$L6= z3B<=C71`>WnZoMu^br4)2f0PIxSEj-3rb2ILimmxvyJ{BpW23(icVZRYB8L0%tEy> z@!S=l&j&opS;CHoW|B3D3*Gg}@XO(MOWB0A@BaZ)fuzCYF&d=dyysnEshbtrIC|0)H z##8bt&3@{5h(>t;!BbnZHD!&?H@2(&2kxDo1bshw#2tz?gV51(0CKFGyFnYv%DlF zYxi*Fiuw)Vlt)A3$!gvw->(Mv;I;8;?*4Kb*2rkSdw>Tc-(xClv?@v$sZxvEpMF?h z&tux+?{nNu_-#`nFs<|VQoElM6o8JiEdVazE24 z4?wonjd+OW&$S%vY6u4kgbp5DTl!-P5TC@WaYD2tv0ACkLot_VFFRKAxqX!0x^0-v zoq*IYcXmQ%byW^5U7e%Wc%P@ITx4Y8Z`oreF+cPAaavI4AJi+n!ufs*P-`106rbJ_ zRzRtWF)7DF{Y~aVoM9~Kb2&XFvc4ZMU{(rqdU{>T>Ju3y>x`(0PiC&KzO-ZWY&O=nmagA}?WO`R|qaT4It3J>}ayXiM zGylmow>S|2pwJw+pea9GS?fk<4ZZD$Ca%60*&W>r)6}Gf)r{5;)wK{M2AkcA9^cz@ zR+YI>l59;_oCCiogtw~n{oDc;7TJ7Mm`ckPbm&+nSlB6XFAejVOG#4!b9noc81ul_ zc|P&D@mGq1bJX`kqdqteS-+6+%!#=vq5x!%N8&^CV&vN(4xlf*XznaRpNp zzWCOdh6Shg>HPQVuC}!3?0tMv=P>@mE4E4zx@Xx{QR=P}>2f|;&#Uu|ea(VmExU&* zVTQb4P0Vs59?O-Rs`Mgs}X?7Jxkpz`GDFMxgieo!$p=Ww(*W&$hrZ zXtXBC)j`^=o_+Z8tU-IXiDkrI2+k(9z;Te))_XW>fH z=N@QkUfz>*sUqei`03+~R0l4UeJ1dlk)N=e9i@1B+gxEa%uUmSwzbG=`HveFclc4% zH*d#^3=!2h^-Gskfn9>g<9CiDQVrdT4&U3&_J^GtzI^rUHLRC)i<7XygGLsdJ)QdK z`VX=Tf7u8dr=$yl_b!tfq67ju37`UAQhQBKuX-Z$KTzs}Ta(@>gtNgdNQYwL`` zxLGl1gdtPrh4>&`5Qi5qq`$I0@dn}NHnp}yhg*&4>}D-JSXBX6Oz!A(@VfzGNIAA$ zz*wX=JZITM?=|7x{zD+d8)8YBJhTUj@X8F;UNEU>NHm{YbOQY#U|)Q)Muw3QL*OWL zZenJSm6+T6GYJ0An0O>e_ILQ4{V$61R2(t;$NIYo3nr!l&zt7~_P>JYe-HR8!XEh- z#lH+VPZtu`BW4eYLHB<%;IEK8F+%^F;?EWS8W2U?330vuO$`4}ir?e^8t^y2|9^wT zGyd;5!KPE0f0tDG`vm`kGyYpB{sXc3Th9K!B>uM?)St@yui3A^59cH$eY)!vBbh2pIlbVjKdnlR|41P83X`Cr0`ko+x}j(nP?p zG+EADZ6+$5f2I6^!9*;OwoRsz4p9~W0!ulm|4RBB*Au~IR`qVqIP=EIRdw*`7PwoUJp`b(?9woyFCz7Q-IML`(!%DM2aIw%uLN z=Cu4zTWC8@#VcpS{Lkw5X8$6~e4q+JG5Qd>TYCV(75Uh2e~O{yIrVft@E?Vqs_wG~ z3&e1E-Z%Bf9{owh0l~V7o~*9pdC%6;uF2#f&nH0Gh@TRt7?edE773r7Z16|E(=_^* z?m%aI+e593Kh>8{kA`CWA9#h#5$l0p8L*>>JV*MaM*TH~JoLPDjsw->V0bfyM)?_#`cq>nEiz_r;_>ZVq-VA*RKcnii@(2 z<_m*=8SUXP<>SA+Vh%2wP71EuJejQEFQdc6>a0bQO`rhbQ0ZhQJdmpPR8;*cuzi2U zK2fU41&r<*cmYMri!h_Dr2Udmurv85g}> zs`#a-Zb*Vo5jsX6!m!~Tb1>3&G$hUNm7xqGEOMRSgMQ49!82=dVj#}l9ckbvK3Cdq zGBPP|<0ZI|wDPL4j)oIOua0(i>(j|EbeKA=H{75=8iY;4)6h)8`GPT*F=##CDkEZ{ z&UtBoI^6 zhr+S;njlGgPOXpmQR4is5h$^(mCPwoopK|Cw!$L2L$koOf)Q_q$*$!(pt!WY(?XYu zaE|2S2`_F`t-x0fzt1HH=IlSO(IXZ#bb+vHgObwTjexP}C_PTaF)QP~ z@84^3tbe&E%07b7`ITLQp*a1==c=bZ>(T@V>=6od0=Kx(4SGjT%_j|h%_wPfrx*R$ zWabc2x`{<}NiaZ`x5qP37CrBk#8p!A_Wd+>ixov_hgHR{;={GmNu*sJlYg!4etw#i zF3z4muYSWQp*EL7dgy8fla}&o1>v&oc$G4A8>6IKa>I~(WNRtzts|mO3f-f_=(9%_ z8TW&{wB1K-Gi3I7Tf{&$?fCxBDBT9JbEToeT5+P>mGCVE7N>5fM%Sq{iXezlGhun? z(V16m#@@WhNrn&{Tuc|$O zbWQH>wodYF1gIQ@j81aGvyXXkfhO^3eqZjM3p;VMWUy7m#$VrUwA^=3o7tY#SK+l2 zVyV^J45d{ohE&V(AH7a|N=2Pf-`mVsr65^8V>z9Z-S$DNdh1Dh9r$vx1Cuo4Z zM*>%X?I$HMv7yTTg2Dp3YZFu(-{)U>gbt)9H^9RN-5YD8quq6NFH#eRCg*je|K96K z?e3@Ht5XA-Joa6aTT{%Ha}Z`jX+PXVEpHR=4RaZ`eihbPiO2nd?p;I{dwV>E($`PY}^gs%-Sv&9A>6X8cA= zDl7^ODPXe(yLSc;G+j?S*JJ<{Hkfl!ZS!JD(kBoh3a#)Nz%~4K7*OCzecU(-LtqmgRWW z$WMku_XI@XufJv5u}Lf>E9RrpsKt%)_ux563jE@yMkfBJg-A+FJg{B3>hFHa()N^S zK6+%%mXHth!imTD)-@7&X)4_1%y-7#??BrB#GTfEJ5Qh)3Vfz&G_vOJzR4o1a9S;R zHXth1+Hk&3I2ATSE&?x}Vrn#Wib+~OQ`<4}vmE)vqaKs`Kn4=k4TG`x?Z5kQZflr0 z0Ab%cJ4uV&zb{a&kZEN<073#TNE{J&JZSsd==}R%I{sPw^#4Ntw9f1qDaWxm4@=?* Rh{!UDf-D$R`25xT{{f+i-Sz+g diff --git a/content/developer/tutorials/master_odoo_web_framework.rst b/content/developer/tutorials/master_odoo_web_framework.rst index 608c44f69..9e5d7a915 100644 --- a/content/developer/tutorials/master_odoo_web_framework.rst +++ b/content/developer/tutorials/master_odoo_web_framework.rst @@ -1,8 +1,8 @@ :show-content: -============================= -Master the Odoo web framework -============================= +======================== +Master the web framework +======================== .. toctree:: :titlesonly: @@ -11,7 +11,7 @@ Master the Odoo web framework master_odoo_web_framework/* This tutorial is designed for those who have completed the :doc:`discover_js_framework` tutorial and -are looking to deepen their knowledge of the Odoo web framework. It is organized in four independant +are looking to deepen their knowledge of the web framework. It is organized in four independent projects, each focusing on different features of Odoo. .. note:: diff --git a/content/developer/tutorials/master_odoo_web_framework/03_customize_kanban_view.rst b/content/developer/tutorials/master_odoo_web_framework/03_customize_kanban_view.rst index b67987489..bea7197d6 100644 --- a/content/developer/tutorials/master_odoo_web_framework/03_customize_kanban_view.rst +++ b/content/developer/tutorials/master_odoo_web_framework/03_customize_kanban_view.rst @@ -2,7 +2,7 @@ Chapter 3: Customize a kanban view ================================== -We have gained an understanding of the numerous capabilities offered by the Odoo web framework. As a +We have gained an understanding of the numerous capabilities offered by the web framework. As a next step, we will customize a kanban view. This is a more complicated project that will showcase some non trivial aspects of the framework. The goal is to practice composing views, coordinating various aspects of the UI, and doing it in a maintainable way. diff --git a/content/developer/tutorials/pdf_reports.rst b/content/developer/tutorials/pdf_reports.rst index 83bcba73c..614ff5894 100644 --- a/content/developer/tutorials/pdf_reports.rst +++ b/content/developer/tutorials/pdf_reports.rst @@ -3,13 +3,11 @@ Build PDF Reports ================= .. important:: - This tutorial is an extension of the :doc:`getting_started` tutorial. Make sure you have + This tutorial is an extension of the :doc:`server_framework_101` tutorial. Make sure you have completed it and use the `estate` module you have built as a base for the exercises in this - tutorial. Fetch the branch `{BRANCH}-core` from the `technical-training-solutions - `_ repository if you - want to start from a clean base. + tutorial. -We were previously :ref:`introduced to QWeb ` +We were previously :doc:`introduced to QWeb ` where it was used to build a kanban view. Now we will expand on one of QWeb's other main uses: creating PDF reports. A common business requirement is the ability to create documents to send to customers and to use internally. These reports can be used to summarize and display @@ -180,7 +178,7 @@ Its contents are all explained in :ref:`the documentation `_ repository if you - want to start from a clean base. + tutorial. So far we have mostly concerned ourselves with implementing useful features. However in most business scenarios *security* quickly becomes a concern: @@ -17,7 +15,7 @@ currently, update or delete properties, property types, or property tags. * If ``estate_account`` is installed then only agents allowed to interact with invoicing can confirm sales as that's necessary to :ref:`create an - invoice `. + invoice `. However: @@ -142,7 +140,7 @@ Access Rights real-estate application. - Real-estate agents will not be able to update the property types or tags. -Access rights were first introduced in :ref:`tutorials/getting_started/05_securityintro`. +Access rights were first introduced in :doc:`server_framework_101/04_securityintro`. Access rights are a way to give users access to models *via* groups: associate an access right to a group, then all users with that group will have the access. diff --git a/content/developer/tutorials/server_framework_101.rst b/content/developer/tutorials/server_framework_101.rst new file mode 100644 index 000000000..e6ef2e04e --- /dev/null +++ b/content/developer/tutorials/server_framework_101.rst @@ -0,0 +1,44 @@ +:show-content: + +==================== +Server framework 101 +==================== + +.. toctree:: + :titlesonly: + :glob: + + server_framework_101/* + +Welcome to the Server framework 101 tutorial! If you reached this page that means you are +interested in the development of your own Odoo module. It might also mean that you recently +joined the Odoo company for a rather technical position. In any case, your journey to the +technical side of Odoo starts here. + +The goal of this tutorial is for you to get an insight of the most important parts of the Odoo +development framework while developing your own Odoo module to manage real estate assets. The +chapters should be followed in their given order since they cover the development of a new Odoo +application from scratch in an incremental way. In other words, each chapter depends on the previous +one. + +.. important:: + Before going further, make sure you have prepared your development environment with the + :doc:`setup guide `. + +Ready? Let's get started! + +* :doc:`server_framework_101/01_architecture` +* :doc:`server_framework_101/02_newapp` +* :doc:`server_framework_101/03_basicmodel` +* :doc:`server_framework_101/04_securityintro` +* :doc:`server_framework_101/05_firstui` +* :doc:`server_framework_101/06_basicviews` +* :doc:`server_framework_101/07_relations` +* :doc:`server_framework_101/08_compute_onchange` +* :doc:`server_framework_101/09_actions` +* :doc:`server_framework_101/10_constraints` +* :doc:`server_framework_101/11_sprinkles` +* :doc:`server_framework_101/12_inheritance` +* :doc:`server_framework_101/13_other_module` +* :doc:`server_framework_101/14_qwebintro` +* :doc:`server_framework_101/15_final_word` diff --git a/content/developer/tutorials/getting_started/01_architecture.rst b/content/developer/tutorials/server_framework_101/01_architecture.rst similarity index 93% rename from content/developer/tutorials/getting_started/01_architecture.rst rename to content/developer/tutorials/server_framework_101/01_architecture.rst index 1cc0a2486..5c5f3ca6f 100644 --- a/content/developer/tutorials/getting_started/01_architecture.rst +++ b/content/developer/tutorials/server_framework_101/01_architecture.rst @@ -1,4 +1,4 @@ -.. _tutorials/getting_started/01_architecture: +.. _tutorials/server_framework_101/01_architecture: ================================ Chapter 1: Architecture Overview @@ -121,10 +121,7 @@ Odoo is available in `two versions`_: Odoo Enterprise (licensed & shared sources functionalities to Odoo. From a technical point-of-view, these functionalities are simply new modules installed on top of the modules provided by the Community version. -Ready to start? Before writing actual code, let's go to the :doc:`next chapter <02_setup>` to review -the Odoo installation process. Even if Odoo is already running on your system, we strongly suggest -you go through this chapter to make sure we start on the same page during the development of our new -application. +Ready to start? It is now time to :doc:`write your own application <02_newapp>`! .. _multitier architecture: https://en.wikipedia.org/wiki/Multitier_architecture diff --git a/content/developer/tutorials/getting_started/01_architecture/three_tier.svg b/content/developer/tutorials/server_framework_101/01_architecture/three_tier.svg similarity index 100% rename from content/developer/tutorials/getting_started/01_architecture/three_tier.svg rename to content/developer/tutorials/server_framework_101/01_architecture/three_tier.svg diff --git a/content/developer/tutorials/getting_started/03_newapp.rst b/content/developer/tutorials/server_framework_101/02_newapp.rst similarity index 92% rename from content/developer/tutorials/getting_started/03_newapp.rst rename to content/developer/tutorials/server_framework_101/02_newapp.rst index d40afedbd..31e02dcfd 100644 --- a/content/developer/tutorials/getting_started/03_newapp.rst +++ b/content/developer/tutorials/server_framework_101/02_newapp.rst @@ -1,7 +1,5 @@ -.. _tutorials/getting_started/03_newapp: - ============================ -Chapter 3: A New Application +Chapter 2: A New Application ============================ The purpose of this chapter is to lay the foundation for the creation of a completely new Odoo module. @@ -18,7 +16,7 @@ to answer the specific business case. Here is an overview of the main list view containing some advertisements: -.. image:: 03_newapp/overview_list_view_01.png +.. image:: 02_newapp/overview_list_view_01.png :align: center :alt: List view 01 @@ -26,14 +24,14 @@ The top area of the form view summarizes important information for the property, the property type, the postcode and so on. The first tab contains information describing the property: bedrooms, living area, garage, garden... -.. image:: 03_newapp/overview_form_view_01.png +.. image:: 02_newapp/overview_form_view_01.png :align: center :alt: Form view 01 The second tab lists the offers for the property. We can see here that potential buyers can make offers above or below the expected selling price. It is up to the seller to accept an offer. -.. image:: 03_newapp/overview_form_view_02.png +.. image:: 02_newapp/overview_form_view_02.png :align: center :alt: Form view 02 @@ -52,7 +50,7 @@ Prepare the addon directory **Goal**: the goal of this section is to have Odoo recognize our new module, which will be an empty shell for now. It will be listed in the Apps: - .. image:: 03_newapp/app_in_list.png + .. image:: 02_newapp/app_in_list.png :align: center :alt: The new module appears in the list @@ -98,5 +96,4 @@ tadaaa, your module appears! Did it not appear? Maybe try removing the default ' You can even install the module! But obviously it's an empty shell, so no menu will appear. -All good? If yes, then let's :ref:`create our first model -`! +All good? If yes, then let's :doc:`create our first model <03_basicmodel>`! diff --git a/content/developer/tutorials/getting_started/03_newapp/app_in_list.png b/content/developer/tutorials/server_framework_101/02_newapp/app_in_list.png similarity index 100% rename from content/developer/tutorials/getting_started/03_newapp/app_in_list.png rename to content/developer/tutorials/server_framework_101/02_newapp/app_in_list.png diff --git a/content/developer/tutorials/getting_started/03_newapp/overview_form_view_01.png b/content/developer/tutorials/server_framework_101/02_newapp/overview_form_view_01.png similarity index 100% rename from content/developer/tutorials/getting_started/03_newapp/overview_form_view_01.png rename to content/developer/tutorials/server_framework_101/02_newapp/overview_form_view_01.png diff --git a/content/developer/tutorials/getting_started/03_newapp/overview_form_view_02.png b/content/developer/tutorials/server_framework_101/02_newapp/overview_form_view_02.png similarity index 100% rename from content/developer/tutorials/getting_started/03_newapp/overview_form_view_02.png rename to content/developer/tutorials/server_framework_101/02_newapp/overview_form_view_02.png diff --git a/content/developer/tutorials/getting_started/03_newapp/overview_list_view_01.png b/content/developer/tutorials/server_framework_101/02_newapp/overview_list_view_01.png similarity index 100% rename from content/developer/tutorials/getting_started/03_newapp/overview_list_view_01.png rename to content/developer/tutorials/server_framework_101/02_newapp/overview_list_view_01.png diff --git a/content/developer/tutorials/getting_started/04_basicmodel.rst b/content/developer/tutorials/server_framework_101/03_basicmodel.rst similarity index 98% rename from content/developer/tutorials/getting_started/04_basicmodel.rst rename to content/developer/tutorials/server_framework_101/03_basicmodel.rst index c7b1a7ea5..fcdbceaeb 100644 --- a/content/developer/tutorials/getting_started/04_basicmodel.rst +++ b/content/developer/tutorials/server_framework_101/03_basicmodel.rst @@ -1,10 +1,8 @@ -.. _tutorials/getting_started/04_basicmodel: - ================================== -Chapter 4: Models And Basic Fields +Chapter 3: Models And Basic Fields ================================== -At the end of the :ref:`previous chapter `, we were able to +At the end of the :doc:`previous chapter <02_newapp>`, we were able to create an Odoo module. However, at this point it is still an empty shell which doesn't allow us to store any data. In our real estate module, we want to store the information related to the properties (name, description, price, living area...) in a database. The Odoo framework provides @@ -289,7 +287,7 @@ useful or necessary: Now that we have created our first model, let's -:ref:`add some security `! +:doc:`add some security <04_securityintro>`! .. [#autofields] it is possible to :ref:`disable the automatic creation of some diff --git a/content/developer/tutorials/getting_started/05_securityintro.rst b/content/developer/tutorials/server_framework_101/04_securityintro.rst similarity index 94% rename from content/developer/tutorials/getting_started/05_securityintro.rst rename to content/developer/tutorials/server_framework_101/04_securityintro.rst index 80c8ccbd2..5c4c2317f 100644 --- a/content/developer/tutorials/getting_started/05_securityintro.rst +++ b/content/developer/tutorials/server_framework_101/04_securityintro.rst @@ -1,10 +1,8 @@ -.. _tutorials/getting_started/05_securityintro: - ========================================== -Chapter 5: Security - A Brief Introduction +Chapter 4: Security - A Brief Introduction ========================================== -In the :ref:`previous chapter `, we created our first table +In the :doc:`previous chapter <03_basicmodel>`, we created our first table intended to store business data. In a business application such as Odoo, one of the first questions to consider is who\ [#who]_ can access the data. Odoo provides a security mechanism to allow access to the data for specific groups of users. @@ -119,7 +117,7 @@ Here is an example for our previous `test_model`: Restart the server and the warning message should have disappeared! -It's now time to finally :ref:`interact with the UI `! +It's now time to finally :doc:`interact with the UI <05_firstui>`! .. [#who] meaning which Odoo user (or group of users) diff --git a/content/developer/tutorials/getting_started/06_firstui.rst b/content/developer/tutorials/server_framework_101/05_firstui.rst similarity index 91% rename from content/developer/tutorials/getting_started/06_firstui.rst rename to content/developer/tutorials/server_framework_101/05_firstui.rst index ec1558431..22974b67a 100644 --- a/content/developer/tutorials/getting_started/06_firstui.rst +++ b/content/developer/tutorials/server_framework_101/05_firstui.rst @@ -1,11 +1,9 @@ -.. _tutorials/getting_started/06_firstui: - ======================================== -Chapter 6: Finally, Some UI To Play With +Chapter 5: Finally, Some UI To Play With ======================================== -Now that we've created our new :ref:`model ` and its -corresponding :ref:`access rights `, it is time to +Now that we've created our new :doc:`model <03_basicmodel>` and its +corresponding :doc:`access rights <04_securityintro>`, it is time to interact with the user interface. At the end of this chapter, we will have created a couple of menus in order to access a default list @@ -17,7 +15,7 @@ Data Files (XML) **Reference**: the documentation related to this topic can be found in :ref:`reference/data`. -In :ref:`tutorials/getting_started/05_securityintro`, we added data through a CSV file. The CSV +In :doc:`04_securityintro`, we added data through a CSV file. The CSV format is convenient when the data to load has a simple format. When the format is more complex (e.g. load the structure of a view or an email template), we use the XML format. For example, this @@ -65,7 +63,7 @@ Actions can be triggered in three ways: 3. as contextual actions on object We will only cover the first case in this chapter. The second case will be covered in a -:ref:`later chapter ` while the last is the focus of an +:doc:`later chapter <09_actions>` while the last is the focus of an advanced topic. In our Real Estate example, we would like to link a menu to the ``estate.property`` model, so we are able to create a new record. The action can be viewed as the link between the menu and the model. @@ -86,7 +84,7 @@ A basic action for our `test_model` is: - ``name`` is the name of the action. - ``res_model`` is the model which the action applies to. - ``view_mode`` are the views that will be available; in this case they are the list (tree) and form views. - We'll see :ref:`later ` that there can be other view modes. + We'll see :doc:`later <14_qwebintro>` that there can be other view modes. Examples can be found everywhere in Odoo, but `this `__ @@ -113,15 +111,15 @@ Menus **Goal**: at the end of this section, three menus should be created and the default view is displayed: - .. image:: 06_firstui/estate_menu_root.png + .. image:: 05_firstui/estate_menu_root.png :align: center :alt: Root menus - .. image:: 06_firstui/estate_menu_action.png + .. image:: 05_firstui/estate_menu_action.png :align: center :alt: First level and action menus - .. image:: 06_firstui/estate_form_default.png + .. image:: 05_firstui/estate_form_default.png :align: center :alt: Default form view @@ -145,11 +143,11 @@ However, menus always follow an architecture, and in practice there are three le 2. The first level menu, displayed in the top bar 3. The action menus - .. image:: 06_firstui/menu_01.png + .. image:: 05_firstui/menu_01.png :align: center :alt: Root menus - .. image:: 06_firstui/menu_02.png + .. image:: 05_firstui/menu_02.png :align: center :alt: First level and action menus @@ -186,7 +184,7 @@ Fields, Attributes And View of bedrooms and the availability date should have default values. Additionally the selling price and availability date values won't be copied when the record is duplicated. - .. image:: 06_firstui/attribute_and_default.gif + .. image:: 05_firstui/attribute_and_default.gif :align: center :alt: Interaction between model and view @@ -266,7 +264,7 @@ not be listed! ``active`` is an example of a reserved field with a specific beha a record has ``active=False``, it is automatically removed from any search. To display the created property, you will need to specifically search for inactive records. -.. image:: 06_firstui/inactive.gif +.. image:: 05_firstui/inactive.gif :align: center :alt: Inactive records @@ -287,7 +285,7 @@ Note that the default ``active=False`` value was assigned to all existing record The ``state`` will be used later on for several UI enhancements. Now that we are able to interact with the UI thanks to the default views, the next step is -obvious: we want to define :ref:`our own views `. +obvious: we want to define :doc:`our own views <06_basicviews>`. .. [#refresh] A refresh is needed since the web client keeps a cache of the various menus and views for performance reasons. diff --git a/content/developer/tutorials/getting_started/06_firstui/attribute_and_default.gif b/content/developer/tutorials/server_framework_101/05_firstui/attribute_and_default.gif similarity index 100% rename from content/developer/tutorials/getting_started/06_firstui/attribute_and_default.gif rename to content/developer/tutorials/server_framework_101/05_firstui/attribute_and_default.gif diff --git a/content/developer/tutorials/getting_started/06_firstui/estate_form_default.png b/content/developer/tutorials/server_framework_101/05_firstui/estate_form_default.png similarity index 100% rename from content/developer/tutorials/getting_started/06_firstui/estate_form_default.png rename to content/developer/tutorials/server_framework_101/05_firstui/estate_form_default.png diff --git a/content/developer/tutorials/getting_started/06_firstui/estate_menu_action.png b/content/developer/tutorials/server_framework_101/05_firstui/estate_menu_action.png similarity index 100% rename from content/developer/tutorials/getting_started/06_firstui/estate_menu_action.png rename to content/developer/tutorials/server_framework_101/05_firstui/estate_menu_action.png diff --git a/content/developer/tutorials/getting_started/06_firstui/estate_menu_root.png b/content/developer/tutorials/server_framework_101/05_firstui/estate_menu_root.png similarity index 100% rename from content/developer/tutorials/getting_started/06_firstui/estate_menu_root.png rename to content/developer/tutorials/server_framework_101/05_firstui/estate_menu_root.png diff --git a/content/developer/tutorials/getting_started/06_firstui/inactive.gif b/content/developer/tutorials/server_framework_101/05_firstui/inactive.gif similarity index 100% rename from content/developer/tutorials/getting_started/06_firstui/inactive.gif rename to content/developer/tutorials/server_framework_101/05_firstui/inactive.gif diff --git a/content/developer/tutorials/getting_started/06_firstui/menu_01.png b/content/developer/tutorials/server_framework_101/05_firstui/menu_01.png similarity index 100% rename from content/developer/tutorials/getting_started/06_firstui/menu_01.png rename to content/developer/tutorials/server_framework_101/05_firstui/menu_01.png diff --git a/content/developer/tutorials/getting_started/06_firstui/menu_02.png b/content/developer/tutorials/server_framework_101/05_firstui/menu_02.png similarity index 100% rename from content/developer/tutorials/getting_started/06_firstui/menu_02.png rename to content/developer/tutorials/server_framework_101/05_firstui/menu_02.png diff --git a/content/developer/tutorials/getting_started/07_basicviews.rst b/content/developer/tutorials/server_framework_101/06_basicviews.rst similarity index 94% rename from content/developer/tutorials/getting_started/07_basicviews.rst rename to content/developer/tutorials/server_framework_101/06_basicviews.rst index 0fd158150..bf1f769ba 100644 --- a/content/developer/tutorials/getting_started/07_basicviews.rst +++ b/content/developer/tutorials/server_framework_101/06_basicviews.rst @@ -1,10 +1,8 @@ -.. _tutorials/getting_started/07_basicviews: - ====================== -Chapter 7: Basic Views +Chapter 6: Basic Views ====================== -We have seen in the :ref:`previous chapter ` that Odoo is able +We have seen in the :doc:`previous chapter <05_firstui>` that Odoo is able to generate default views for a given model. In practice, the default view is **never** acceptable for a business application. Instead, we should at least organize the various fields in a logical manner. @@ -29,7 +27,7 @@ List **Goal**: at the end of this section, the list view should look like this: - .. image:: 07_basicviews/list.png + .. image:: 06_basicviews/list.png :align: center :alt: List view @@ -78,7 +76,7 @@ Form **Goal**: at the end of this section, the form view should look like this: - .. image:: 07_basicviews/form.png + .. image:: 06_basicviews/form.png :align: center :alt: Form view @@ -140,15 +138,15 @@ Search **Goal**: at the end of this section, the search view should look like this: - .. image:: 07_basicviews/search_01.png + .. image:: 06_basicviews/search_01.png :align: center :alt: Search fields - .. image:: 07_basicviews/search_02.png + .. image:: 06_basicviews/search_02.png :align: center :alt: Filter - .. image:: 07_basicviews/search_03.png + .. image:: 06_basicviews/search_03.png :align: center :alt: Group By @@ -239,4 +237,4 @@ services *OR* have a unit price which is *NOT* between 1000 and 2000':: Looking good? At this point we are already able to create models and design a user interface which makes sense business-wise. However, a key component is still missing: the -:ref:`link between models `. +:doc:`link between models <07_relations>`. diff --git a/content/developer/tutorials/getting_started/07_basicviews/form.png b/content/developer/tutorials/server_framework_101/06_basicviews/form.png similarity index 100% rename from content/developer/tutorials/getting_started/07_basicviews/form.png rename to content/developer/tutorials/server_framework_101/06_basicviews/form.png diff --git a/content/developer/tutorials/getting_started/07_basicviews/list.png b/content/developer/tutorials/server_framework_101/06_basicviews/list.png similarity index 100% rename from content/developer/tutorials/getting_started/07_basicviews/list.png rename to content/developer/tutorials/server_framework_101/06_basicviews/list.png diff --git a/content/developer/tutorials/getting_started/07_basicviews/search_01.png b/content/developer/tutorials/server_framework_101/06_basicviews/search_01.png similarity index 100% rename from content/developer/tutorials/getting_started/07_basicviews/search_01.png rename to content/developer/tutorials/server_framework_101/06_basicviews/search_01.png diff --git a/content/developer/tutorials/getting_started/07_basicviews/search_02.png b/content/developer/tutorials/server_framework_101/06_basicviews/search_02.png similarity index 100% rename from content/developer/tutorials/getting_started/07_basicviews/search_02.png rename to content/developer/tutorials/server_framework_101/06_basicviews/search_02.png diff --git a/content/developer/tutorials/getting_started/07_basicviews/search_03.png b/content/developer/tutorials/server_framework_101/06_basicviews/search_03.png similarity index 100% rename from content/developer/tutorials/getting_started/07_basicviews/search_03.png rename to content/developer/tutorials/server_framework_101/06_basicviews/search_03.png diff --git a/content/developer/tutorials/getting_started/08_relations.rst b/content/developer/tutorials/server_framework_101/07_relations.rst similarity index 92% rename from content/developer/tutorials/getting_started/08_relations.rst rename to content/developer/tutorials/server_framework_101/07_relations.rst index 6042df068..28538d4dd 100644 --- a/content/developer/tutorials/getting_started/08_relations.rst +++ b/content/developer/tutorials/server_framework_101/07_relations.rst @@ -1,10 +1,8 @@ -.. _tutorials/getting_started/08_relations: - =================================== -Chapter 8: Relations Between Models +Chapter 7: Relations Between Models =================================== -The :ref:`previous chapter ` covered the creation of custom +The :doc:`previous chapter <06_basicviews>` covered the creation of custom views for a model containing basic fields. However, in any real business scenario we need more than one model. Moreover, links between models are necessary. One can easily imagine one model containing the customers and another one containing the list of users. You might need to refer to a customer @@ -30,13 +28,13 @@ Many2one - a new ``estate.property.type`` model should be created with the corresponding menu, action and views. - .. image:: 08_relations/property_type.png + .. image:: 07_relations/property_type.png :align: center :alt: Property type - three Many2one fields should be added to the ``estate.property`` model: property type, buyer and seller. - .. image:: 08_relations/property_many2one.png + .. image:: 07_relations/property_many2one.png :align: center :alt: Property @@ -78,10 +76,10 @@ In practice a many2one can be seen as a dropdown list in a form view. and search views This exercise is a good recap of the previous chapters: you need to create a - :ref:`model `, set the - :ref:`model `, add an - :ref:`action and a menu `, and - :ref:`create a view `. + :doc:`model <03_basicmodel>`, set the + :doc:`model <04_securityintro>`, add an + :doc:`action and a menu <05_firstui>`, and + :doc:`create a view <06_basicviews>`. Tip: do not forget to import any new Python files in ``__init__.py``, add new data files in ``__manifest.py__`` or add the access rights ;-) @@ -137,13 +135,13 @@ Many2many - a new ``estate.property.tag`` model should be created with the corresponding menu and action. - .. image:: 08_relations/property_tag.png + .. image:: 07_relations/property_tag.png :align: center :alt: Property tag - tags should be added to the ``estate.property`` model: - .. image:: 08_relations/property_many2many.png + .. image:: 07_relations/property_many2many.png :align: center :alt: Property @@ -185,7 +183,7 @@ operations like ``recs1 | recs2``. Tip: in the view, use the ``widget="many2many_tags"`` attribute as demonstrated `here `__. - The ``widget`` attribute will be explained in detail in :ref:`a later chapter of the training `. + The ``widget`` attribute will be explained in detail in :doc:`a later chapter of the training <11_sprinkles>`. For now, you can try to adding and removing it and see the result ;-) One2many @@ -201,7 +199,7 @@ One2many - a new ``estate.property.offer`` model should be created with the corresponding form and tree view. - offers should be added to the ``estate.property`` model: - .. image:: 08_relations/property_offer.png + .. image:: 07_relations/property_offer.png :align: center :alt: Property offers @@ -263,4 +261,4 @@ for convenience. Still alive? This chapter is definitely not the easiest one. It introduced a couple of new concepts while relying on everything that was introduced before. The -:ref:`next chapter ` will be lighter, don't worry ;-) +:doc:`next chapter <08_compute_onchange>` will be lighter, don't worry ;-) diff --git a/content/developer/tutorials/getting_started/08_relations/property_many2many.png b/content/developer/tutorials/server_framework_101/07_relations/property_many2many.png similarity index 100% rename from content/developer/tutorials/getting_started/08_relations/property_many2many.png rename to content/developer/tutorials/server_framework_101/07_relations/property_many2many.png diff --git a/content/developer/tutorials/getting_started/08_relations/property_many2one.png b/content/developer/tutorials/server_framework_101/07_relations/property_many2one.png similarity index 100% rename from content/developer/tutorials/getting_started/08_relations/property_many2one.png rename to content/developer/tutorials/server_framework_101/07_relations/property_many2one.png diff --git a/content/developer/tutorials/getting_started/08_relations/property_offer.png b/content/developer/tutorials/server_framework_101/07_relations/property_offer.png similarity index 100% rename from content/developer/tutorials/getting_started/08_relations/property_offer.png rename to content/developer/tutorials/server_framework_101/07_relations/property_offer.png diff --git a/content/developer/tutorials/getting_started/08_relations/property_tag.png b/content/developer/tutorials/server_framework_101/07_relations/property_tag.png similarity index 100% rename from content/developer/tutorials/getting_started/08_relations/property_tag.png rename to content/developer/tutorials/server_framework_101/07_relations/property_tag.png diff --git a/content/developer/tutorials/getting_started/08_relations/property_type.png b/content/developer/tutorials/server_framework_101/07_relations/property_type.png similarity index 100% rename from content/developer/tutorials/getting_started/08_relations/property_type.png rename to content/developer/tutorials/server_framework_101/07_relations/property_type.png diff --git a/content/developer/tutorials/getting_started/09_compute_onchange.rst b/content/developer/tutorials/server_framework_101/08_compute_onchange.rst similarity index 96% rename from content/developer/tutorials/getting_started/09_compute_onchange.rst rename to content/developer/tutorials/server_framework_101/08_compute_onchange.rst index a5b73f39c..a5ac62f5d 100644 --- a/content/developer/tutorials/getting_started/09_compute_onchange.rst +++ b/content/developer/tutorials/server_framework_101/08_compute_onchange.rst @@ -1,10 +1,8 @@ -.. _tutorials/getting_started/09_compute_onchange: - ======================================== -Chapter 9: Computed Fields And Onchanges +Chapter 8: Computed Fields And Onchanges ======================================== -The :ref:`relations between models ` are a key component of +The :doc:`relations between models <07_relations>` are a key component of any Odoo module. They are necessary for the modelization of any business case. However, we may want links between the fields within a given model. Sometimes the value of one field is determined from the values of other fields and other times we want to help the user with data entry. @@ -26,13 +24,13 @@ Computed Fields - In the property model, the total area and the best offer should be computed: - .. image:: 09_compute_onchange/compute.gif + .. image:: 08_compute_onchange/compute.gif :align: center :alt: Compute fields - In the property offer model, the validity date should be computed and can be updated: - .. image:: 09_compute_onchange/compute_inverse.gif + .. image:: 08_compute_onchange/compute_inverse.gif :align: center :alt: Compute field with inverse @@ -52,7 +50,7 @@ method should set the value of the computed field for every record in By convention, :attr:`~odoo.fields.Field.compute` methods are private, meaning that they cannot be called from the presentation tier, only from the business tier (see -:ref:`tutorials/getting_started/01_architecture`). Private methods have a name starting with an +:ref:`tutorials/server_framework_101/01_architecture`). Private methods have a name starting with an underscore ``_``. Dependencies @@ -230,7 +228,7 @@ Onchanges **Goal**: at the end of this section, enabling the garden will set a default area of 10 and an orientation to North. - .. image:: 09_compute_onchange/onchange.gif + .. image:: 08_compute_onchange/onchange.gif :align: center :alt: Onchange @@ -301,5 +299,5 @@ When using stored computed fields, pay close attention to the dependencies. When depend on other computed fields, changing a value can trigger a large number of recomputations. This leads to poor performance. -In the :ref:`next chapter `, we'll see how we can trigger some +In the :doc:`next chapter <09_actions>`, we'll see how we can trigger some business logic when buttons are clicked. diff --git a/content/developer/tutorials/getting_started/09_compute_onchange/compute.gif b/content/developer/tutorials/server_framework_101/08_compute_onchange/compute.gif similarity index 100% rename from content/developer/tutorials/getting_started/09_compute_onchange/compute.gif rename to content/developer/tutorials/server_framework_101/08_compute_onchange/compute.gif diff --git a/content/developer/tutorials/getting_started/09_compute_onchange/compute_inverse.gif b/content/developer/tutorials/server_framework_101/08_compute_onchange/compute_inverse.gif similarity index 100% rename from content/developer/tutorials/getting_started/09_compute_onchange/compute_inverse.gif rename to content/developer/tutorials/server_framework_101/08_compute_onchange/compute_inverse.gif diff --git a/content/developer/tutorials/getting_started/09_compute_onchange/onchange.gif b/content/developer/tutorials/server_framework_101/08_compute_onchange/onchange.gif similarity index 100% rename from content/developer/tutorials/getting_started/09_compute_onchange/onchange.gif rename to content/developer/tutorials/server_framework_101/08_compute_onchange/onchange.gif diff --git a/content/developer/tutorials/getting_started/10_actions.rst b/content/developer/tutorials/server_framework_101/09_actions.rst similarity index 90% rename from content/developer/tutorials/getting_started/10_actions.rst rename to content/developer/tutorials/server_framework_101/09_actions.rst index c1820eec0..9fc86d913 100644 --- a/content/developer/tutorials/getting_started/10_actions.rst +++ b/content/developer/tutorials/server_framework_101/09_actions.rst @@ -1,11 +1,9 @@ -.. _tutorials/getting_started/10_actions: - ================================== -Chapter 10: Ready For Some Action? +Chapter 9: Ready For Some Action? ================================== So far we have mostly built our module by declaring fields and views. We just introduced business -logic in the :ref:`previous chapter ` thanks to +logic in the :doc:`previous chapter <08_compute_onchange>` thanks to computed fields and onchanges. In any real business scenario, we would want to link some business logic to action buttons. In our real estate example, we would like to be able to: @@ -28,7 +26,7 @@ Object Type - You should be able to cancel or set a property as sold: - .. image:: 10_actions/property.gif + .. image:: 09_actions/property.gif :align: center :alt: Cancel and set to sold @@ -37,13 +35,13 @@ Object Type - You should be able to accept or refuse an offer: - .. image:: 10_actions/offer_01.gif + .. image:: 09_actions/offer_01.gif :align: center :alt: Accept or refuse an offer - Once an offer is accepted, the selling price and the buyer should be set: - .. image:: 10_actions/offer_02.gif + .. image:: 09_actions/offer_02.gif :align: center :alt: Accept an offer @@ -125,7 +123,7 @@ and its Action Type =========== -In :ref:`tutorials/getting_started/06_firstui`, we created an action that was linked to a menu. You +In :doc:`05_firstui`, we created an action that was linked to a menu. You may be wondering if it is possible to link an action to a button. Good news, it is! One way to do it is: @@ -135,5 +133,5 @@ is: We use ``type="action"`` and we refer to the :term:`external identifier` in the ``name``. -In the :ref:`next chapter ` we'll see how we can prevent +In the :doc:`next chapter <10_constraints>` we'll see how we can prevent encoding incorrect data in Odoo. diff --git a/content/developer/tutorials/getting_started/10_actions/offer_01.gif b/content/developer/tutorials/server_framework_101/09_actions/offer_01.gif similarity index 100% rename from content/developer/tutorials/getting_started/10_actions/offer_01.gif rename to content/developer/tutorials/server_framework_101/09_actions/offer_01.gif diff --git a/content/developer/tutorials/getting_started/10_actions/offer_02.gif b/content/developer/tutorials/server_framework_101/09_actions/offer_02.gif similarity index 100% rename from content/developer/tutorials/getting_started/10_actions/offer_02.gif rename to content/developer/tutorials/server_framework_101/09_actions/offer_02.gif diff --git a/content/developer/tutorials/getting_started/10_actions/property.gif b/content/developer/tutorials/server_framework_101/09_actions/property.gif similarity index 100% rename from content/developer/tutorials/getting_started/10_actions/property.gif rename to content/developer/tutorials/server_framework_101/09_actions/property.gif diff --git a/content/developer/tutorials/getting_started/11_constraints.rst b/content/developer/tutorials/server_framework_101/10_constraints.rst similarity index 92% rename from content/developer/tutorials/getting_started/11_constraints.rst rename to content/developer/tutorials/server_framework_101/10_constraints.rst index 02fd5f783..b6f5f771e 100644 --- a/content/developer/tutorials/getting_started/11_constraints.rst +++ b/content/developer/tutorials/server_framework_101/10_constraints.rst @@ -1,10 +1,8 @@ -.. _tutorials/getting_started/11_constraints: - ======================= -Chapter 11: Constraints +Chapter 10: Constraints ======================= -The :ref:`previous chapter ` introduced the ability to add +The :doc:`previous chapter <09_actions>` introduced the ability to add some business logic to our model. We can now link buttons to business code, but how can we prevent users from entering incorrect data? For example, in our real estate module nothing prevents users from setting a negative expected price. @@ -25,13 +23,13 @@ SQL - Amounts should be (strictly) positive - .. image:: 11_constraints/sql_01.gif + .. image:: 10_constraints/sql_01.gif :align: center :alt: Constraints on amounts - Property types and tags should have a unique name - .. image:: 11_constraints/sql_02.gif + .. image:: 10_constraints/sql_02.gif :align: center :alt: Constraints on names @@ -76,7 +74,7 @@ Python **Goal**: at the end of this section, it will not be possible to accept an offer lower than 90% of the expected price. - .. image:: 11_constraints/python.gif + .. image:: 10_constraints/python.gif :align: center :alt: Python constraint @@ -123,7 +121,7 @@ prefer SQL over Python constraints. Our real estate module is starting to look good. We added some business logic, and now we make sure the data is consistent. However, the user interface is still a bit rough. Let's see how we can -improve it in the :ref:`next chapter `. +improve it in the :doc:`next chapter <11_sprinkles>`. .. _PostgreSQL's documentation: .. _table_constraint: diff --git a/content/developer/tutorials/getting_started/11_constraints/python.gif b/content/developer/tutorials/server_framework_101/10_constraints/python.gif similarity index 100% rename from content/developer/tutorials/getting_started/11_constraints/python.gif rename to content/developer/tutorials/server_framework_101/10_constraints/python.gif diff --git a/content/developer/tutorials/getting_started/11_constraints/sql_01.gif b/content/developer/tutorials/server_framework_101/10_constraints/sql_01.gif similarity index 100% rename from content/developer/tutorials/getting_started/11_constraints/sql_01.gif rename to content/developer/tutorials/server_framework_101/10_constraints/sql_01.gif diff --git a/content/developer/tutorials/getting_started/11_constraints/sql_02.gif b/content/developer/tutorials/server_framework_101/10_constraints/sql_02.gif similarity index 100% rename from content/developer/tutorials/getting_started/11_constraints/sql_02.gif rename to content/developer/tutorials/server_framework_101/10_constraints/sql_02.gif diff --git a/content/developer/tutorials/getting_started/12_sprinkles.rst b/content/developer/tutorials/server_framework_101/11_sprinkles.rst similarity index 95% rename from content/developer/tutorials/getting_started/12_sprinkles.rst rename to content/developer/tutorials/server_framework_101/11_sprinkles.rst index 567a8e871..32977b6a3 100644 --- a/content/developer/tutorials/getting_started/12_sprinkles.rst +++ b/content/developer/tutorials/server_framework_101/11_sprinkles.rst @@ -1,13 +1,11 @@ -.. _tutorials/getting_started/12_sprinkles: - ============================= -Chapter 12: Add The Sprinkles +Chapter 11: Add The Sprinkles ============================= Our real estate module now makes sense from a business perspective. We created -:ref:`specific views `, added several -:ref:`action buttons ` and -:ref:`constraints `. However our user interface is still a bit +:doc:`specific views <06_basicviews>`, added several +:doc:`action buttons <09_actions>` and +:doc:`constraints <10_constraints>`. However our user interface is still a bit rough. We would like to add some colors to the list views and make some fields and buttons conditionally disappear. For example, the 'Sold' and 'Cancel' buttons should disappear when the property is sold or canceled since it is no longer allowed to change the state at this point. @@ -27,7 +25,7 @@ Inline Views **Goal**: at the end of this section, a specific list of properties should be added to the property type view: - .. image:: 12_sprinkles/inline_view.png + .. image:: 11_sprinkles/inline_view.png :align: center :alt: Inline list view @@ -102,7 +100,7 @@ Widgets **Goal**: at the end of this section, the state of the property should be displayed using a specific widget: - .. image:: 12_sprinkles/widget.png + .. image:: 11_sprinkles/widget.png :align: center :alt: Statusbar widget @@ -241,7 +239,7 @@ Form - Conditional display of buttons and fields - Tag colors - .. image:: 12_sprinkles/form.gif + .. image:: 11_sprinkles/form.gif :align: center :alt: Form view with sprinkles @@ -269,7 +267,7 @@ behavior customizations, we can add the ``options`` attribute to several field w Have a look at the :ref:`FieldMany2ManyTags widget documentation ` for more info. -In :ref:`tutorials/getting_started/06_firstui`, we saw that reserved fields were used for +In :doc:`05_firstui`, we saw that reserved fields were used for specific behaviors. For example, the ``active`` field is used to automatically filter out inactive records. We added the ``state`` as a reserved field as well. It's now time to use it! A ``state`` field can be used in combination with an ``invisible`` attribute in the view to display @@ -322,11 +320,11 @@ List Additionally, offers and tags will be editable directly in the list, and the availability date will be hidden by default. - .. image:: 12_sprinkles/decoration.png + .. image:: 11_sprinkles/decoration.png :align: center :alt: List view with decorations and optional field - .. image:: 12_sprinkles/editable_list.gif + .. image:: 11_sprinkles/editable_list.gif :align: center :alt: Editable list @@ -392,7 +390,7 @@ Search and searching on the living area returns results where the area is larger than the given number. - .. image:: 12_sprinkles/search.gif + .. image:: 11_sprinkles/search.gif :align: center :alt: Default filters and domains @@ -440,7 +438,7 @@ Stat Buttons **Goal**: at the end of this section, there will be a stat button on the property type form view which shows the list of all offers related to properties of the given type when it is clicked on. - .. image:: 12_sprinkles/stat_button.gif + .. image:: 11_sprinkles/stat_button.gif :align: center :alt: Stat button @@ -505,7 +503,7 @@ Every time the partner name is changed, the description is modified. - Create a stat button on ``estate.property.type`` pointing to the ``estate.property.offer`` action. This means you should use the ``type="action"`` attribute (go back to the end of - :ref:`tutorials/getting_started/10_actions` if you need a refresher). + :doc:`09_actions` if you need a refresher). At this point, clicking on the stat button should display all offers. We still need to filter out the offers. @@ -514,8 +512,8 @@ Every time the partner name is changed, the description is modified. as equal to the ``active_id`` (= the current record, `here is an example `__) -Looking good? If not, don't worry, the :ref:`next chapter -` doesn't require stat buttons ;-) +Looking good? If not, don't worry, the :doc:`next chapter +<12_inheritance>` doesn't require stat buttons ;-) .. _order_by: https://www.postgresql.org/docs/12/queries-order.html diff --git a/content/developer/tutorials/getting_started/12_sprinkles/decoration.png b/content/developer/tutorials/server_framework_101/11_sprinkles/decoration.png similarity index 100% rename from content/developer/tutorials/getting_started/12_sprinkles/decoration.png rename to content/developer/tutorials/server_framework_101/11_sprinkles/decoration.png diff --git a/content/developer/tutorials/getting_started/12_sprinkles/editable_list.gif b/content/developer/tutorials/server_framework_101/11_sprinkles/editable_list.gif similarity index 100% rename from content/developer/tutorials/getting_started/12_sprinkles/editable_list.gif rename to content/developer/tutorials/server_framework_101/11_sprinkles/editable_list.gif diff --git a/content/developer/tutorials/getting_started/12_sprinkles/form.gif b/content/developer/tutorials/server_framework_101/11_sprinkles/form.gif similarity index 100% rename from content/developer/tutorials/getting_started/12_sprinkles/form.gif rename to content/developer/tutorials/server_framework_101/11_sprinkles/form.gif diff --git a/content/developer/tutorials/getting_started/12_sprinkles/inline_view.png b/content/developer/tutorials/server_framework_101/11_sprinkles/inline_view.png similarity index 100% rename from content/developer/tutorials/getting_started/12_sprinkles/inline_view.png rename to content/developer/tutorials/server_framework_101/11_sprinkles/inline_view.png diff --git a/content/developer/tutorials/getting_started/12_sprinkles/search.gif b/content/developer/tutorials/server_framework_101/11_sprinkles/search.gif similarity index 100% rename from content/developer/tutorials/getting_started/12_sprinkles/search.gif rename to content/developer/tutorials/server_framework_101/11_sprinkles/search.gif diff --git a/content/developer/tutorials/getting_started/12_sprinkles/stat_button.gif b/content/developer/tutorials/server_framework_101/11_sprinkles/stat_button.gif similarity index 100% rename from content/developer/tutorials/getting_started/12_sprinkles/stat_button.gif rename to content/developer/tutorials/server_framework_101/11_sprinkles/stat_button.gif diff --git a/content/developer/tutorials/getting_started/12_sprinkles/widget.png b/content/developer/tutorials/server_framework_101/11_sprinkles/widget.png similarity index 100% rename from content/developer/tutorials/getting_started/12_sprinkles/widget.png rename to content/developer/tutorials/server_framework_101/11_sprinkles/widget.png diff --git a/content/developer/tutorials/getting_started/13_inheritance.rst b/content/developer/tutorials/server_framework_101/12_inheritance.rst similarity index 96% rename from content/developer/tutorials/getting_started/13_inheritance.rst rename to content/developer/tutorials/server_framework_101/12_inheritance.rst index fbab169b4..31440969f 100644 --- a/content/developer/tutorials/getting_started/13_inheritance.rst +++ b/content/developer/tutorials/server_framework_101/12_inheritance.rst @@ -1,7 +1,5 @@ -.. _tutorials/getting_started/13_inheritance: - ======================= -Chapter 13: Inheritance +Chapter 12: Inheritance ======================= A powerful aspect of Odoo is its modularity. A module is dedicated to a business need, but @@ -21,14 +19,14 @@ Python Inheritance - It should not be possible to delete a property which is not new or canceled. - .. image:: 13_inheritance/unlink.gif + .. image:: 12_inheritance/unlink.gif :align: center :alt: Unlink - When an offer is created, the property state should change to 'Offer Received' - It should not be possible to create an offer with a lower price than an existing offer - .. image:: 13_inheritance/create.gif + .. image:: 12_inheritance/create.gif :align: center :alt: Create @@ -126,7 +124,7 @@ The second inheritance mechanism (delegation) allows every record of a model to to a parent model's record and provides transparent access to the fields of this parent record. -.. image:: 13_inheritance/inheritance_methods.png +.. image:: 12_inheritance/inheritance_methods.png :align: center :alt: Inheritance Methods @@ -173,7 +171,7 @@ View Inheritance **Goal**: at the end of this section, the list of available properties linked to a salesperson should be displayed in their user form view - .. image:: 13_inheritance/users.png + .. image:: 12_inheritance/users.png :align: center :alt: Users @@ -245,7 +243,7 @@ An example of a view inheritance extension can be found Inheritance is extensively used in Odoo due to its modular concept. Do not hesitate to read the corresponding documentation for more info! -In the :ref:`next chapter `, we will learn how to +In the :doc:`next chapter <13_other_module>`, we will learn how to interact with other modules. .. _XPath: https://w3.org/TR/xpath diff --git a/content/developer/tutorials/getting_started/13_inheritance/create.gif b/content/developer/tutorials/server_framework_101/12_inheritance/create.gif similarity index 100% rename from content/developer/tutorials/getting_started/13_inheritance/create.gif rename to content/developer/tutorials/server_framework_101/12_inheritance/create.gif diff --git a/content/developer/tutorials/getting_started/13_inheritance/inheritance_methods.png b/content/developer/tutorials/server_framework_101/12_inheritance/inheritance_methods.png similarity index 100% rename from content/developer/tutorials/getting_started/13_inheritance/inheritance_methods.png rename to content/developer/tutorials/server_framework_101/12_inheritance/inheritance_methods.png diff --git a/content/developer/tutorials/getting_started/13_inheritance/unlink.gif b/content/developer/tutorials/server_framework_101/12_inheritance/unlink.gif similarity index 100% rename from content/developer/tutorials/getting_started/13_inheritance/unlink.gif rename to content/developer/tutorials/server_framework_101/12_inheritance/unlink.gif diff --git a/content/developer/tutorials/getting_started/13_inheritance/users.png b/content/developer/tutorials/server_framework_101/12_inheritance/users.png similarity index 100% rename from content/developer/tutorials/getting_started/13_inheritance/users.png rename to content/developer/tutorials/server_framework_101/12_inheritance/users.png diff --git a/content/developer/tutorials/getting_started/14_other_module.rst b/content/developer/tutorials/server_framework_101/13_other_module.rst similarity index 89% rename from content/developer/tutorials/getting_started/14_other_module.rst rename to content/developer/tutorials/server_framework_101/13_other_module.rst index 6a8dd188c..f32e4a4f7 100644 --- a/content/developer/tutorials/getting_started/14_other_module.rst +++ b/content/developer/tutorials/server_framework_101/13_other_module.rst @@ -1,10 +1,8 @@ -.. _tutorials/getting_started/14_other_module: - ======================================= -Chapter 14: Interact With Other Modules +Chapter 13: Interact With Other Modules ======================================= -In the :ref:`previous chapter `, we used inheritance to +In the :doc:`previous chapter <12_inheritance>`, we used inheritance to modify the behavior of a module. In our real estate scenario, we would like to go a step further and be able to generate invoices for our customers. Odoo provides an Invoicing module, so it would be neat to create an invoice directly from our real estate module, i.e. once a property @@ -20,7 +18,7 @@ Concrete Example: Account Move - A new module ``estate_account`` should be created - When a property is sold, an invoice should be issued for the buyer - .. image:: 14_other_module/create_inv.gif + .. image:: 13_other_module/create_inv.gif :align: center :alt: Invoice creation @@ -42,14 +40,14 @@ independently. When both are installed, the link module provides the new feature For now, it will be an empty shell. Tip: you already did this at the - :ref:`beginning of the tutorial `. The process is very + :doc:`beginning of the tutorial <02_newapp>`. The process is very similar. When the ``estate_account`` module appears in the list, go ahead and install it! You'll notice that the Invoicing application is installed as well. This is expected since your module depends on it. If you uninstall the Invoicing application, your module will be uninstalled as well. -.. _tutorials/getting_started/14_other_module/create: +.. _tutorials/server_framework_101/13_other_module/create: Invoice Creation ---------------- @@ -57,12 +55,12 @@ Invoice Creation It's now time to generate the invoice. We want to add functionality to the ``estate.property`` model, i.e. we want to add some extra logic for when a property is sold. Does that sound familiar? If not, it's a good idea to go back to the -:ref:`previous chapter ` since you might have missed +:doc:`previous chapter <12_inheritance>` since you might have missed something ;-) As a first step, we need to extend the action called when pressing the -:ref:`'Sold' button ` on a property. To do so, we need to -create a :ref:`model inheritance ` in the `estate_account` +:doc:`'Sold' button <09_actions>` on a property. To do so, we need to +create a :doc:`model inheritance <12_inheritance>` in the `estate_account` module for the ``estate.property`` model. For now, the overridden action will simply return the ``super`` call. Maybe an example will make things clearer:: @@ -168,5 +166,5 @@ field ``line_ids`` at creation of a ``test_model``:: For each line, we need a ``name``, ``quantity`` and ``price_unit``. This chapter might be one of the most difficult that has been covered so far, but it is the closest -to what Odoo development will be in practice. In the :ref:`next chapter -`, we will introduce the templating mechanism used in Odoo. +to what Odoo development will be in practice. In the :doc:`next chapter +<14_qwebintro>`, we will introduce the templating mechanism used in Odoo. diff --git a/content/developer/tutorials/getting_started/14_other_module/create_inv.gif b/content/developer/tutorials/server_framework_101/13_other_module/create_inv.gif similarity index 100% rename from content/developer/tutorials/getting_started/14_other_module/create_inv.gif rename to content/developer/tutorials/server_framework_101/13_other_module/create_inv.gif diff --git a/content/developer/tutorials/getting_started/15_qwebintro.rst b/content/developer/tutorials/server_framework_101/14_qwebintro.rst similarity index 97% rename from content/developer/tutorials/getting_started/15_qwebintro.rst rename to content/developer/tutorials/server_framework_101/14_qwebintro.rst index 12fd3098b..b4643eb57 100644 --- a/content/developer/tutorials/getting_started/15_qwebintro.rst +++ b/content/developer/tutorials/server_framework_101/14_qwebintro.rst @@ -1,7 +1,5 @@ -.. _tutorials/getting_started/15_qwebintro: - =================================== -Chapter 15: A Brief History Of QWeb +Chapter 14: A Brief History Of QWeb =================================== So far the interface design of our real estate module has been rather limited. Building @@ -31,7 +29,7 @@ Concrete Example: A Kanban View **Goal**: at the end of this section a Kanban view of the properties should be created: - .. image:: 15_qwebintro/kanban.png + .. image:: 14_qwebintro/kanban.png :align: center :alt: Kanban view diff --git a/content/developer/tutorials/getting_started/15_qwebintro/kanban.png b/content/developer/tutorials/server_framework_101/14_qwebintro/kanban.png similarity index 100% rename from content/developer/tutorials/getting_started/15_qwebintro/kanban.png rename to content/developer/tutorials/server_framework_101/14_qwebintro/kanban.png diff --git a/content/developer/tutorials/getting_started/16_final_word.rst b/content/developer/tutorials/server_framework_101/15_final_word.rst similarity index 93% rename from content/developer/tutorials/getting_started/16_final_word.rst rename to content/developer/tutorials/server_framework_101/15_final_word.rst index 80a9d1f34..57ae22961 100644 --- a/content/developer/tutorials/getting_started/16_final_word.rst +++ b/content/developer/tutorials/server_framework_101/15_final_word.rst @@ -1,7 +1,5 @@ -.. _tutorials/getting_started/16_final_word: - ========================== -Chapter 16: The final word +Chapter 15: The final word ========================== Coding guidelines diff --git a/content/developer/tutorials/getting_started/02_setup.rst b/content/developer/tutorials/setup_guide.rst similarity index 87% rename from content/developer/tutorials/getting_started/02_setup.rst rename to content/developer/tutorials/setup_guide.rst index aa9920299..a1d56720d 100644 --- a/content/developer/tutorials/getting_started/02_setup.rst +++ b/content/developer/tutorials/setup_guide.rst @@ -1,28 +1,28 @@ -======================================== -Chapter 2: Development environment setup -======================================== +=========== +Setup guide +=========== Depending on the intended use case, there are multiple ways to install Odoo. For developers of the Odoo community and Odoo employees alike, the preferred way is to perform a source install (:dfn:`running Odoo from the source code`). -Prepare the environment -======================= +.. important:: + Follow the :ref:`contributing/development/setup` section of the contributing guide to prepare + your environment for pushing local changes to the Odoo repositories. -First, follow the :ref:`contributing/development/setup` section of the contributing guide to prepare -your environment. +Adapt the environment for the tutorials +======================================= By now, you should have downloaded the source code into two local repositories, one for `odoo/odoo` and one for `odoo/enterprise`. These repositories are set up to push changes to pre-defined forks on GitHub. This will prove to be convenient when you start contributing to the codebase, but -for the scope of this tutorial, we want to avoid polluting them with training material. Let's then -develop your own module in a third repository `odoo/tutorials`. Like the first two repositories, -it will be part of the `addons-path` that references all directories containing Odoo modules. -In this repository, we will create our first module! +in the scope of following a tutorial, we want to avoid polluting them with training material. Let's +then push your changes in a third repository: `odoo/tutorials`. Like the first two repositories, it +will be part of the `addons-path` that references all directories containing Odoo modules. .. note:: - - This repository also already contains some bare modules that will be used in other tutorials. + Depending on the tutorial that you are following, you might not need to install all the modules + that this repository contains. #. Following the same process as with the `odoo/odoo` and `odoo/enterprise` repositories, clone the `odoo/tutorials` repository on your machine with: @@ -147,10 +147,6 @@ the server. In this training you will only need some of them. (comma-separated list). This is equivalent to going to :guilabel:`Apps` in the user interface, selecting a module, and upgrading it from there. -.. note:: - For now you cannot add `../technical-training-sandbox` to your `addons-path` as it is empty - and will result into an invalid addons-path folder error, but you will have to add it back later on ! - Log in to Odoo -------------- @@ -167,14 +163,8 @@ Enable the developer mode ========================= The developer or debug mode is useful for training as it gives access to additional (advanced) -tools. In the next chapters, **we will always assume that you have enabled the developer mode**. - -:ref:`Enable the developer mode ` now. Choose the method that you prefer; they are -all equivalent. - -.. note:: - The main page of the Settings screen is only accessible if at least one application is installed. - You will be led into installing your own application in the next chapter. +tools. :ref:`Enable the developer mode ` now. Choose the method that you prefer; +they are all equivalent. Extra tools =========== @@ -318,6 +308,3 @@ Here is a list of commands: .. option:: q(uit) Quit the debugger. The program being executed is aborted. - -Now that your server is running, it's time to start :ref:`writing your own application -`! diff --git a/content/developer/tutorials/unit_tests.rst b/content/developer/tutorials/unit_tests.rst index 19969e83f..5448b3b95 100644 --- a/content/developer/tutorials/unit_tests.rst +++ b/content/developer/tutorials/unit_tests.rst @@ -3,11 +3,9 @@ Safeguard your code with unit tests =================================== .. important:: - This tutorial is an extension of the :doc:`getting_started` tutorial. Make sure you have + This tutorial is an extension of the :doc:`server_framework_101` tutorial. Make sure you have completed it and use the `estate` module you have built as a base for the exercises in this - tutorial. Fetch the branch `{BRANCH}-core` from the `technical-training-solutions - `_ repository if you - want to start from a clean base. + tutorial. **Reference**: `Odoo's Test Framework: Learn Best Practices `__ diff --git a/content/developer/tutorials/website.rst b/content/developer/tutorials/website.rst index 9e0c324d8..3c6a09109 100644 --- a/content/developer/tutorials/website.rst +++ b/content/developer/tutorials/website.rst @@ -5,7 +5,7 @@ Building a Website ================== .. danger:: - This tutorial is outdated. We recommend reading :doc:`getting_started` instead. + This tutorial is outdated. We recommend reading :doc:`server_framework_101` instead. .. warning:: diff --git a/extensions/odoo_theme/layout_templates/homepage.html b/extensions/odoo_theme/layout_templates/homepage.html index 9f5f4b4c7..09df56e4c 100644 --- a/extensions/odoo_theme/layout_templates/homepage.html +++ b/extensions/odoo_theme/layout_templates/homepage.html @@ -62,31 +62,26 @@

{{ _("Developer") }}

-

{{ _("Learn to develop in Odoo by reading the framework references and programmer tutorials.") }}

+

{{ _("Learn to develop in Odoo with the developer tutorials and framework references.") }}

{{ _("Top Links") }}
  • - - {{ _("Tutorial: Getting started") }} + + {{ _("Tutorials") }}
  • - - {{ _("ORM") }} + + {{ _("How-to guides") }}
  • - - {{ _("Regular Views") }} + + {{ _("Reference") }}
  • - - {{ _("QWeb Views") }} - -
  • -
  • - + {{ _("External API") }}
  • diff --git a/redirects/17.0.txt b/redirects/17.0.txt index eb098d3c9..b19e99b9d 100644 --- a/redirects/17.0.txt +++ b/redirects/17.0.txt @@ -3,6 +3,26 @@ developer/reference/backend/views.rst developer/reference/user_interface/view_records.rst developer/reference/user_interface/view_architecture.rst developer/reference/user_interface/view_architectures.rst +# developer/tutorials + +developer/tutorials/getting_started.rst developer/tutorials/server_framework_101.rst +developer/tutorials/getting_started/01_architecture.rst developer/tutorials/server_framework_101/01_architecture.rst +developer/tutorials/getting_started/02_setup.rst developer/tutorials/setup_guide.rst +developer/tutorials/getting_started/03_newapp.rst developer/tutorials/server_framework_101/02_newapp.rst +developer/tutorials/getting_started/04_basicmodel.rst developer/tutorials/server_framework_101/03_basicmodel.rst +developer/tutorials/getting_started/05_securityintro.rst developer/tutorials/server_framework_101/04_securityintro.rst +developer/tutorials/getting_started/06_firstui.rst developer/tutorials/server_framework_101/05_firstui.rst +developer/tutorials/getting_started/07_basicviews.rst developer/tutorials/server_framework_101/06_basicviews.rst +developer/tutorials/getting_started/08_relations.rst developer/tutorials/server_framework_101/07_relations.rst +developer/tutorials/getting_started/09_compute_onchange.rst developer/tutorials/server_framework_101/08_compute_onchange.rst +developer/tutorials/getting_started/10_actions.rst developer/tutorials/server_framework_101/09_actions.rst +developer/tutorials/getting_started/11_constraints.rst developer/tutorials/server_framework_101/10_constraints.rst +developer/tutorials/getting_started/12_sprinkles.rst developer/tutorials/server_framework_101/11_sprinkles.rst +developer/tutorials/getting_started/13_inheritance.rst developer/tutorials/server_framework_101/12_inheritance.rst +developer/tutorials/getting_started/14_other_module.rst developer/tutorials/server_framework_101/13_other_module.rst +developer/tutorials/getting_started/15_qwebintro.rst developer/tutorials/server_framework_101/14_qwebintro.rst +developer/tutorials/getting_started/16_final_word.rst developer/tutorials/server_framework_101/15_final_word.rst + # applications/inventory_and_mrp applications/inventory_and_mrp/inventory/warehouses_storage/advanced_operations_warehouse/closest_location.rst applications/inventory_and_mrp/inventory/warehouses_storage/removal_strategies/closest_location.rst # advanced_operations_warehouse/* --> removal_strategies/*