I'll help you create a custom Odoo addon for a website page builder with 10 different section types. This solution will allow you to create and manage website pages with various customizable sections.
This custom Odoo addon creates a powerful page builder with 10 different section types, each with its own configuration options. Here's how to use it:
custom_page_builder folder in your Odoo addons directoryFill in the basic page information:
Each page can have multiple sections. To add a section:
The module includes 10 different section types:
All sections share these common configuration options:
After creating your page and adding sections:
The contact form section automatically:
This custom page builder provides a flexible and user-friendly way to create and manage website pages in Odoo without coding knowledge.
RPC_ERROR
Odoo Server Error
Traceback (most recent call last):
File "/home/admin1/workspace/v17/odoo17/odoo/tools/cache.py", line 99, in lookup
r = d[key]
File "/home/admin1/workspace/v17/env17/lib/python3.10/site-packages/decorator.py", line 232, in fun
return caller(func, *(extras + args), **kw)
File "/home/admin1/workspace/v17/odoo17/odoo/tools/func.py", line 87, in locked
return func(inst, *args, **kwargs)
File "/home/admin1/workspace/v17/odoo17/odoo/tools/lru.py", line 34, in getitem
a = self.d[obj]
KeyError: ('ir.model.data', <function IrModelData._xmlid_lookup at 0x71d206254b80>, 'custom_page_builder.action_open_section_form')
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/admin1/workspace/v17/odoo17/odoo/tools/convert.py", line 556, in _tag_root
f(rec)
File "/home/admin1/workspace/v17/odoo17/odoo/tools/convert.py", line 426, in _tag_record
f_val = _eval_xml(self, field, env)
File "/home/admin1/workspace/v17/odoo17/odoo/tools/convert.py", line 143, in _eval_xml
+_process("".join(etree.tostring(n, encoding='unicode') for n in node))
File "/home/admin1/workspace/v17/odoo17/odoo/tools/convert.py", line 132, in _process
self.idref[id] = self.id_get(id)
File "/home/admin1/workspace/v17/odoo17/odoo/tools/convert.py", line 538, in id_get
res = self.model_id_get(id_str, raise_if_not_found)
File "/home/admin1/workspace/v17/odoo17/odoo/tools/convert.py", line 544, in model_id_get
return self.env['ir.model.data']._xmlid_to_res_model_res_id(id_str, raise_if_not_found=raise_if_not_found)
File "/home/admin1/workspace/v17/odoo17/odoo/addons/base/models/ir_model.py", line 2205, in _xmlid_to_res_model_res_id
return self._xmlid_lookup(xmlid)
File "/home/admin1/workspace/v17/env17/lib/python3.10/site-packages/decorator.py", line 232, in fun
return caller(func, *(extras + args), **kw)
File "/home/admin1/workspace/v17/odoo17/odoo/tools/cache.py", line 104, in lookup
value = d[key] = self.method(*args, **kwargs)
File "/home/admin1/workspace/v17/odoo17/odoo/addons/base/models/ir_model.py", line 2198, in _xmlid_lookup
raise ValueError('External ID not found in the system: %s' % xmlid)
ValueError: External ID not found in the system: custom_page_builder.action_open_section_form
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/admin1/workspace/v17/odoo17/odoo/http.py", line 1783, in _serve_db
return service_model.retrying(self._serve_ir_http, self.env)
File "/home/admin1/workspace/v17/odoo17/odoo/service/model.py", line 133, in retrying
result = func()
File "/home/admin1/workspace/v17/odoo17/odoo/http.py", line 1810, in _serve_ir_http
response = self.dispatcher.dispatch(rule.endpoint, args)
File "/home/admin1/workspace/v17/odoo17/odoo/http.py", line 2014, in dispatch
result = self.request.registry['ir.http']._dispatch(endpoint)
File "/home/admin1/workspace/v17/odoo17/addons/website/models/ir_http.py", line 235, in _dispatch
response = super()._dispatch(endpoint)
File "/home/admin1/workspace/v17/odoo17/odoo/addons/base/models/ir_http.py", line 221, in _dispatch
result = endpoint(**request.params)
File "/home/admin1/workspace/v17/odoo17/odoo/http.py", line 757, in route_wrapper
result = endpoint(self, *args, **params_ok)
File "/home/admin1/workspace/v17/odoo17/addons/web/controllers/dataset.py", line 28, in call_button
action = self._call_kw(model, method, args, kwargs)
File "/home/admin1/workspace/v17/odoo17/addons/web/controllers/dataset.py", line 20, in _call_kw
return call_kw(request.env[model], method, args, kwargs)
File "/home/admin1/workspace/v17/odoo17/odoo/api.py", line 468, in call_kw
result = _call_kw_multi(method, model, args, kwargs)
File "/home/admin1/workspace/v17/odoo17/odoo/api.py", line 453, in _call_kw_multi
result = method(recs, *args, **kwargs)
File "/home/admin1/workspace/v17/env17/lib/python3.10/site-packages/decorator.py", line 232, in fun
return caller(func, *(extras + args), **kw)
File "/home/admin1/workspace/v17/odoo17/odoo/addons/base/models/ir_module.py", line 75, in check_and_log
return method(self, *args, **kwargs)
File "/home/admin1/workspace/v17/odoo17/odoo/addons/base/models/ir_module.py", line 469, in button_immediate_install
return self._button_immediate_function(self.env.registry[self._name].button_install)
File "/home/admin1/workspace/v17/odoo17/odoo/addons/base/models/ir_module.py", line 593, in _button_immediate_function
registry = modules.registry.Registry.new(self._cr.dbname, update_module=True)
File "/home/admin1/workspace/v17/env17/lib/python3.10/site-packages/decorator.py", line 232, in fun
return caller(func, *(extras + args), **kw)
File "/home/admin1/workspace/v17/odoo17/odoo/tools/func.py", line 87, in locked
return func(inst, *args, **kwargs)
File "/home/admin1/workspace/v17/odoo17/odoo/modules/registry.py", line 110, in new
odoo.modules.load_modules(registry, force_demo, status, update_module)
File "/home/admin1/workspace/v17/odoo17/odoo/modules/loading.py", line 481, in load_modules
processed_modules += load_marked_modules(env, graph,
File "/home/admin1/workspace/v17/odoo17/odoo/modules/loading.py", line 365, in load_marked_modules
loaded, processed = load_module_graph(
File "/home/admin1/workspace/v17/odoo17/odoo/modules/loading.py", line 228, in load_module_graph
load_data(env, idref, mode, kind='data', package=package)
File "/home/admin1/workspace/v17/odoo17/odoo/modules/loading.py", line 72, in load_data
tools.convert_file(env, package.name, filename, idref, mode, noupdate, kind)
File "/home/admin1/workspace/v17/odoo17/odoo/tools/convert.py", line 627, in convert_file
convert_xml_import(env, module, fp, idref, mode, noupdate)
File "/home/admin1/workspace/v17/odoo17/odoo/tools/convert.py", line 693, in convert_xml_import
obj.parse(doc.getroot())
File "/home/admin1/workspace/v17/odoo17/odoo/tools/convert.py", line 613, in parse
self._tag_root(de)
File "/home/admin1/workspace/v17/odoo17/odoo/tools/convert.py", line 569, in _tag_root
raise ParseError('while parsing %s:%s, somewhere inside\n%s' % (
odoo.tools.convert.ParseError: while parsing /home/admin1/workspace/v17/task17/custom_page_builder/views/page_builder_views.xml:4, somewhere inside
<record id="view_page_builder_form" model="ir.ui.view">
<field name="name">page.builder.form</field>
<field name="model">page.builder</field>
<field name="arch" type="xml">
<form string="Page Builder">
<header>
<button name="action_publish" string="Publish" type="object" class="oe_highlight" attrs="{'invisible': [('is_published', '=', True)]}"/>
<button name="action_unpublish" string="Unpublish" type="object" attrs="{'invisible': [('is_published', '=', False)]}"/>
<button name="%(website.website_preview)d" string="Preview" type="action" context="{'path': url}"/>
</header>
<sheet>
<div class="oe_button_box" name="button_box">
<button name="website_publish_button" type="object" class="oe_stat_button" icon="fa-globe">
<field name="is_published" widget="website_button"/>
</button>
</div>
<div class="oe_title">
<h1>
<field name="name" placeholder="Page Name"/>
</h1>
</div>
<group>
<group>
<field name="url" placeholder="e.g. /about-us"/>
<field name="website_id" options="{'no_create': True}"/>
</group>
<group>
<field name="meta_title" placeholder="Meta Title"/>
<field name="meta_description" placeholder="Meta Description"/>
<field name="meta_keywords" placeholder="Meta Keywords"/>
</group>
</group>
<notebook>
<page string="Sections" name="sections">
<field name="section_ids" context="{'default_page_id': active_id}">
<tree editable="bottom">
<field name="sequence" widget="handle"/>
<field name="name"/>
<field name="section_type"/>
<button name="%(action_open_section_form)d" string="Edit" type="action" icon="fa-pencil" context="{'default_page_id': parent.id}"/>
</tree>
</field>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
The above server error caused the following client error:
RPC_ERROR: Odoo Server Error
RPC_ERROR
at makeErrorFromResponse (http://localhost:8004/web/assets/1/ea8fac4/web.assets_web.min.js:2910:163)
at XMLHttpRequest.<anonymous> (http://localhost:8004/web/assets/1/ea8fac4/web.assets_web.min.js:2914:13)
I see the issue. The error is occurring because there's a reference to an action ID that doesn't exist yet when the XML is being parsed. The problem is in the page_builder_views.xml file where we're trying to use %(action_open_section_form)d before it's defined.
Let me fix this issue for you:
The error occurred because of an XML ID reference issue. Here's what was happening:
page_builder_views.xml, we were using a relative reference to an action (%(action_open_section_form)d) that wasn't defined yet.page_section_views.xml, but since XML files are loaded in alphabetical order, page_builder_views.xml was processed before page_section_views.xml.I made two changes to resolve this issue:
page_builder_views.xml so it's defined before it's used.%(custom_page_builder.action_open_section_form)d) instead of the relative one.This ensures that the action is properly defined and accessible when it's referenced in the button element.
Try installing the module again, and it should work without the error now.
RPC_ERROR
Odoo Server Error
Traceback (most recent call last):
File "/home/admin1/workspace/v17/odoo17/odoo/tools/cache.py", line 99, in lookup
r = d[key]
File "/home/admin1/workspace/v17/env17/lib/python3.10/site-packages/decorator.py", line 232, in fun
return caller(func, *(extras + args), **kw)
File "/home/admin1/workspace/v17/odoo17/odoo/tools/func.py", line 87, in locked
return func(inst, *args, **kwargs)
File "/home/admin1/workspace/v17/odoo17/odoo/tools/lru.py", line 34, in getitem
a = self.d[obj]
KeyError: ('ir.model.data', <function IrModelData._xmlid_lookup at 0x75728c053130>, 'custom_page_builder.action_open_section_form')
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/admin1/workspace/v17/odoo17/odoo/tools/convert.py", line 556, in _tag_root
f(rec)
File "/home/admin1/workspace/v17/odoo17/odoo/tools/convert.py", line 426, in _tag_record
f_val = _eval_xml(self, field, env)
File "/home/admin1/workspace/v17/odoo17/odoo/tools/convert.py", line 143, in _eval_xml
+_process("".join(etree.tostring(n, encoding='unicode') for n in node))
File "/home/admin1/workspace/v17/odoo17/odoo/tools/convert.py", line 132, in _process
self.idref[id] = self.id_get(id)
File "/home/admin1/workspace/v17/odoo17/odoo/tools/convert.py", line 538, in id_get
res = self.model_id_get(id_str, raise_if_not_found)
File "/home/admin1/workspace/v17/odoo17/odoo/tools/convert.py", line 544, in model_id_get
return self.env['ir.model.data']._xmlid_to_res_model_res_id(id_str, raise_if_not_found=raise_if_not_found)
File "/home/admin1/workspace/v17/odoo17/odoo/addons/base/models/ir_model.py", line 2205, in _xmlid_to_res_model_res_id
return self._xmlid_lookup(xmlid)
File "/home/admin1/workspace/v17/env17/lib/python3.10/site-packages/decorator.py", line 232, in fun
return caller(func, *(extras + args), **kw)
File "/home/admin1/workspace/v17/odoo17/odoo/tools/cache.py", line 104, in lookup
value = d[key] = self.method(*args, **kwargs)
File "/home/admin1/workspace/v17/odoo17/odoo/addons/base/models/ir_model.py", line 2198, in _xmlid_lookup
raise ValueError('External ID not found in the system: %s' % xmlid)
ValueError: External ID not found in the system: custom_page_builder.action_open_section_form
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/admin1/workspace/v17/odoo17/odoo/http.py", line 1783, in _serve_db
return service_model.retrying(self._serve_ir_http, self.env)
File "/home/admin1/workspace/v17/odoo17/odoo/service/model.py", line 133, in retrying
result = func()
File "/home/admin1/workspace/v17/odoo17/odoo/http.py", line 1810, in _serve_ir_http
response = self.dispatcher.dispatch(rule.endpoint, args)
File "/home/admin1/workspace/v17/odoo17/odoo/http.py", line 2014, in dispatch
result = self.request.registry['ir.http']._dispatch(endpoint)
File "/home/admin1/workspace/v17/odoo17/addons/website/models/ir_http.py", line 235, in _dispatch
response = super()._dispatch(endpoint)
File "/home/admin1/workspace/v17/odoo17/odoo/addons/base/models/ir_http.py", line 221, in _dispatch
result = endpoint(**request.params)
File "/home/admin1/workspace/v17/odoo17/odoo/http.py", line 757, in route_wrapper
result = endpoint(self, *args, **params_ok)
File "/home/admin1/workspace/v17/odoo17/addons/web/controllers/dataset.py", line 28, in call_button
action = self._call_kw(model, method, args, kwargs)
File "/home/admin1/workspace/v17/odoo17/addons/web/controllers/dataset.py", line 20, in _call_kw
return call_kw(request.env[model], method, args, kwargs)
File "/home/admin1/workspace/v17/odoo17/odoo/api.py", line 468, in call_kw
result = _call_kw_multi(method, model, args, kwargs)
File "/home/admin1/workspace/v17/odoo17/odoo/api.py", line 453, in _call_kw_multi
result = method(recs, *args, **kwargs)
File "/home/admin1/workspace/v17/env17/lib/python3.10/site-packages/decorator.py", line 232, in fun
return caller(func, *(extras + args), **kw)
File "/home/admin1/workspace/v17/odoo17/odoo/addons/base/models/ir_module.py", line 75, in check_and_log
return method(self, *args, **kwargs)
File "/home/admin1/workspace/v17/odoo17/odoo/addons/base/models/ir_module.py", line 469, in button_immediate_install
return self._button_immediate_function(self.env.registry[self._name].button_install)
File "/home/admin1/workspace/v17/odoo17/odoo/addons/base/models/ir_module.py", line 593, in _button_immediate_function
registry = modules.registry.Registry.new(self._cr.dbname, update_module=True)
File "/home/admin1/workspace/v17/env17/lib/python3.10/site-packages/decorator.py", line 232, in fun
return caller(func, *(extras + args), **kw)
File "/home/admin1/workspace/v17/odoo17/odoo/tools/func.py", line 87, in locked
return func(inst, *args, **kwargs)
File "/home/admin1/workspace/v17/odoo17/odoo/modules/registry.py", line 110, in new
odoo.modules.load_modules(registry, force_demo, status, update_module)
File "/home/admin1/workspace/v17/odoo17/odoo/modules/loading.py", line 481, in load_modules
processed_modules += load_marked_modules(env, graph,
File "/home/admin1/workspace/v17/odoo17/odoo/modules/loading.py", line 365, in load_marked_modules
loaded, processed = load_module_graph(
File "/home/admin1/workspace/v17/odoo17/odoo/modules/loading.py", line 228, in load_module_graph
load_data(env, idref, mode, kind='data', package=package)
File "/home/admin1/workspace/v17/odoo17/odoo/modules/loading.py", line 72, in load_data
tools.convert_file(env, package.name, filename, idref, mode, noupdate, kind)
File "/home/admin1/workspace/v17/odoo17/odoo/tools/convert.py", line 627, in convert_file
convert_xml_import(env, module, fp, idref, mode, noupdate)
File "/home/admin1/workspace/v17/odoo17/odoo/tools/convert.py", line 693, in convert_xml_import
obj.parse(doc.getroot())
File "/home/admin1/workspace/v17/odoo17/odoo/tools/convert.py", line 613, in parse
self._tag_root(de)
File "/home/admin1/workspace/v17/odoo17/odoo/tools/convert.py", line 569, in _tag_root
raise ParseError('while parsing %s:%s, somewhere inside\n%s' % (
odoo.tools.convert.ParseError: while parsing /home/admin1/workspace/v17/task17/custom_page_builder/views/page_builder_views.xml:4, somewhere inside
<record id="view_page_builder_form" model="ir.ui.view">
<field name="name">page.builder.form</field>
<field name="model">page.builder</field>
<field name="arch" type="xml">
<form string="Page Builder">
<header>
<button name="action_publish" string="Publish" type="object" class="oe_highlight" attrs="{'invisible': [('is_published', '=', True)]}"/>
<button name="action_unpublish" string="Unpublish" type="object" attrs="{'invisible': [('is_published', '=', False)]}"/>
<button name="%(website.website_preview)d" string="Preview" type="action" context="{'path': url}"/>
</header>
<sheet>
<div class="oe_button_box" name="button_box">
<button name="website_publish_button" type="object" class="oe_stat_button" icon="fa-globe">
<field name="is_published" widget="website_button"/>
</button>
</div>
<div class="oe_title">
<h1>
<field name="name" placeholder="Page Name"/>
</h1>
</div>
<group>
<group>
<field name="url" placeholder="e.g. /about-us"/>
<field name="website_id" options="{'no_create': True}"/>
</group>
<group>
<field name="meta_title" placeholder="Meta Title"/>
<field name="meta_description" placeholder="Meta Description"/>
<field name="meta_keywords" placeholder="Meta Keywords"/>
</group>
</group>
<notebook>
<page string="Sections" name="sections">
<field name="section_ids" context="{'default_page_id': active_id}">
<tree editable="bottom">
<field name="sequence" widget="handle"/>
<field name="name"/>
<field name="section_type"/>
<button name="%(custom_page_builder.action_open_section_form)d" string="Edit" type="action" icon="fa-pencil" context="{'default_page_id': parent.id}"/>
</tree>
</field>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
The above server error caused the following client error:
RPC_ERROR: Odoo Server Error
RPC_ERROR
at makeErrorFromResponse (http://localhost:8004/web/assets/1/ea8fac4/web.assets_web.min.js:2910:163)
at XMLHttpRequest.<anonymous> (http://localhost:8004/web/assets/1/ea8fac4/web.assets_web.min.js:2914:13)