A static website is like a store with its doors shut and locked-it exists, but it doesn't welcome visitors. Today, businesses want websites that respond to users, display real-time data, and adapt based on user actions. Using dynamic pages will assist with this, particularly when using Odoo 19.
The Odoo 19 Website Builder offers developers and functional users the ability to build dynamic, data-driven pages without affecting the continuity of the system. Dynamic pages will bring life and purpose to your website, whether showcasing products, blog entries, or other business-related data.
How to build dynamic webpages?
Dynamic pages do not consist of writing many individual pages but rather building a single intelligent page structure that adjusts itself. A dynamic page will take any data from the database and display it when needed; therefore, when you add a new record (product, blog post, etc.), the new record is added to your website automatically without any manual input.
For example, let's say you have a job board. Instead of creating an individual page for each job title, you would create a job template in Odoo, which would act as a job "container". Each job would have its own URL; when a user clicks the job’s URL, the job would be filled with its own data.
Defining a Dynamic Route Using Controllers
Controllers are the pieces used to build dynamic pages in Odoo. They are Python methods that control how data is retrieved and displayed on the page by the user. When a user visits a specific URL, the controller then determines what data is displayed on the page.
This is an example of a dynamic route:
from odoo import http
from odoo.http import request
class JobPortal(http.Controller):
@http.route('/jobs/<model("hr.job"):job>', type='http', auth='public', website=True)
def job_detail(self, job, **kwargs):
return request.render('your_module.job_detail_template', {
'job': job
})
In this snippet:
- The route /jobs/ dynamically fetches a job record
- Odoo automatically gets the corresponding record
- That record is passed to a template for rendering.
That’s where the real change happens. You’re not building pages anymore, you’re building systems.
Rendering Data with QWeb Templates
Once the controller has passed the data, QWeb templates take over. These templates determine the way the data is displayed on the page. They are HTML mixed with Odoo-specific directives to dynamically inject content.
Here’s a basic example of a QWeb template:
<template id="job_detail_template">
<t t-call="website.layout">
<div class="container">
<h1 t-field="job.name"/>
<p t-field="job.description"/>
<p>
<strong>Department:</strong>
<span t-field="job.department_id.name"/>
</p>
</div>
</t>
</template>
This template doesn’t hardcode anything. Instead:
- t-field dynamically pulls values from the record
- The same structure is reused for every job
- The content changes depending on the URL
It’s clean, predictable, and scalable-qualities that matter when your dataset grows.
Working with Multiple Records
Dynamic pages are not limited to detail views. You can also create listing pages that display multiple records, such as all jobs or all blog posts.
Here’s how you might handle that:
@http.route('/jobs', type='http', auth='public', website=True)
def job_list(self, **kwargs):
jobs = request.env['hr.job'].search([])
return request.render('your_module.job_list_template', {
'jobs': jobs
})And the corresponding template:
<template id="job_list_template">
<t t-call="website.layout">
<div class="container">
<h1>Current Openings</h1>
<t t-foreach="jobs" t-as="job">
<div>
<a t-att-href="'/jobs/%s' % job.id">
<h3 t-esc="job.name"/>
</a>
</div>
</t>
</div>
</t>
</template>
Here, the system loops through all records and generates a list dynamically. Each item links to its own detail page, forming a complete flow with minimal effort.
Adding a Menu for Navigation
After creating the dynamic page, the next step is adding a menu so users can access it directly from the website. In Odoo 19, menu items can be created using XML records inside the custom module.
<record id="website_menu_jobs" model="website.menu">
<field name="name">Jobs</field>
<field name="url">/jobs</field>
<field name="parent_id" ref="website.main_menu"/>
</record>
This creates a Jobs menu in the website header and redirects users to the /jobs dynamic page.
Modeling your Models for website-publishing
To ensure your dynamic web pages work properly, you must have access to a data model for your website. Odoo allows you to do this with built-in support, through fields like website_published.
To extend the example of how you would create a model:
from odoo import models, fields
class Portfolio(models.Model):
_name = 'portfolio.project'
_description = 'Portfolio Project'
name = fields.Char(required=True)
description = fields.Text()
image = fields.Binary()
website_published = fields.Boolean(default=True)
This allows for:
- Managing visibility directly from the backend.
- Publishing to/Unpublishing from a website without code.
- Differentiating between draft and live data.
Dynamic URLs and SEO Considerations
A well-organized and structured dynamic page will not only function but will also present information clearly to visitors. User-friendly URLs (slugs) are generated by Odoo automatically based on the name of the record. Instead of using the cryptic ID as part of the URL, Odoo uses a useful path for visitors to access information on your website:
/jobs/software-developer
This improves usability as well as SEO for search engines. The following must be verified to ensure the appropriate usage of slugs:
- Titles should be understandable & concise with no duplicate titles in the database.
- No duplicate content on the web page.
- Properly configured metadata (titles/descriptions) is critical for use in the title and description fields.
Dynamic pages will be easy to scale, but can create clutter when a lack of discipline exists in the development of your dynamic pages. Therefore, maintaining the correct structure of your pages is very important!
With Odoo 19's Dynamic Pages feature, there is less need for manual page creation. Once the first page has been created, Odoo can automatically create future pages that will be published in accordance with the company's growth. The dynamic page is a very powerful tool in that it will allow you to set the pace of creating new pages based on incoming data. The ongoing maintenance of the site will be minimal because the data will continue to reconnect with the pages.
To read more about How to Create a Dynamic Snippet in Odoo 19, refer to our blog How to Create a Dynamic Snippet in Odoo 19.