Odoo 18’s website builder offers an intuitive and powerful platform for creating dynamic, interactive websites. A key feature is the snippet system, which allows developers to create reusable, drag-and-drop components that users can customize directly in the website editor. Dynamic snippets go beyond static content by incorporating data and interactivity, allowing for a more engaging user experience. In this guide, we’ll walk through developing a dynamic website snippet in Odoo 18, covering everything from module setup to template creation and JavaScript integration.
1. Prerequisites
To follow this guide, you’ll need:
- Odoo 18 installed (locally or on a server).
- Familiarity with XML, JavaScript, and Python since dynamic snippets involve server-client interactions.
- Odoo Development Environment: You should know how to create custom modules, understand Odoo’s templating, and work with Odoo’s JavaScript assets.
2. Setting Up Your Custom Module
To manage your snippet’s files and dependencies, start by creating a new custom module in your Odoo addons directory:
- Create the Module Directory: Inside your Odoo addons folder, create a new folder named website_dynamic_snippets.
Define the Module Manifest: In this folder, create a __manifest__.py file to specify the module’s details:
{ 'name': 'Dynamic Website Snippets', 'description': 'Module for custom dynamic website snippets in Odoo 18', 'category': 'Website', 'version': '1.0', 'depends': ['website'], 'data': [ 'views/snippets.xml', 'views/snippet_registry.xml', ], 'assets': { 'web.assets_frontend': [ 'website_dynamic_snippets/static/js/snippet_dynamic.js', 'website_dynamic_snippets/static/css/snippet_dynamic.css', ], }, }
Initialize the Module: Add an empty __init__.py file to mark this directory as a module.
3. Creating the Snippet Template
Now let’s define the XML template that will render your dynamic snippet.
- Create the Views Directory: Inside website_dynamic_snippets, create a folder called views.
Define the Snippet Template: In views, create an XML file called snippets.xml:
<odoo> <template id="snippet_dynamic_carousel" name="Dynamic Carousel Snippet" inherit_id="website.snippets"> <xpath expr="//div[@id='wrap']" position="inside"> <div class="o_snippet_dynamic_carousel" contentEditable="false" data-name="Dynamic Carousel" data-snippet="o_snippet_dynamic_carousel"> <div class="carousel-inner" data-oe-model="carousel.items" data-oe-field="items"> <!-- Items will be dynamically added here --> </div> <a class="carousel-control-prev" href="#" role="button" data-slide="prev"> <span class="carousel-control-prev-icon" aria-hidden="true"></span> <span class="sr-only">Previous</span> </a> <a class="carousel-control-next" href="#" role="button" data-slide="next"> <span class="carousel-control-next-icon" aria-hidden="true"></span> <span class="sr-only">Next</span> </a> </div> </xpath> </template> </odoo>
In this code:
- o_snippet_dynamic_carousel is the container for the carousel.
- Placeholder elements represent the carousel navigation and items, which will be populated dynamically.
4. Adding CSS for Styling
- Inside website_dynamic_snippets, create a folder called static, and inside it, add a css directory.
Create a CSS file snippet_dynamic.css for basic carousel styling:
.o_snippet_dynamic_carousel { position: relative; width: 100%; overflow: hidden; } .carousel-inner { display: flex; transition: transform 0.5s ease-in-out; }
This CSS makes sure the carousel has a flexible layout, ready for dynamically added items.
5. Adding JavaScript for Interactivity
- Inside the static folder, create a js directory.
In js, create a file named snippet_dynamic.js to handle dynamic loading and carousel interactivity:
odoo.define('website_dynamic_snippets.snippet_dynamic', function (require) { "use strict"; var publicWidget = require('web.public.widget'); publicWidget.registry.DynamicCarouselSnippet = publicWidget.Widget.extend({ selector: '.o_snippet_dynamic_carousel', start: function () { this._super.apply(this, arguments); this._loadCarouselItems(); }, _loadCarouselItems: function () { var self = this; // Fetch data (simulate with static data or use an AJAX call here) var items = [ {image: "/web/image/img1.jpg", caption: "First Slide"}, {image: "/web/image/img2.jpg", caption: "Second Slide"}, {image: "/web/image/img3.jpg", caption: "Third Slide"}, ]; // Add each item to the carousel items.forEach(function (item) { var $item = $('<div class="carousel-item">').append( $('<img>').attr('src', item.image).addClass('d-block w-100'), $('<div class="carousel-caption d-none d-md-block">').text(item.caption) ); self.$('.carousel-inner').append($item); }); // Set first item as active self.$('.carousel-item').first().addClass('active'); }, }); });
Here’s what this code does:
- It defines a new widget DynamicCarouselSnippet that loads and appends carousel items.
- It uses a _loadCarouselItems function to fetch and populate items dynamically, allowing you to load from a backend or external source as needed.
6. Registering the Snippet
To make the snippet appear in the website editor, add a snippet registry XML file.
- In views, create a new file named snippet_registry.xml.
Add the following:
<odoo> <template id="assets_frontend" inherit_id="website.assets_frontend"> <xpath expr="." position="inside"> <link rel="stylesheet" href="/website_dynamic_snippets/static/css/snippet_dynamic.css"/> <script type="text/javascript" src="/website_dynamic_snippets/static/js/snippet_dynamic.js"></script> </xpath> </template> <template id="website.snippet_list" inherit_id="website.snippet_list"> <xpath expr="//div[@id='snippet_structure']/div" position="inside"> <div class="o_snippet_thumbnail" data-snippet="o_snippet_dynamic_carousel" data-name="Dynamic Carousel Snippet"> <img src="/website_dynamic_snippets/static/img/carousel_thumbnail.png"/> <span>Dynamic Carousel</span> </div> </xpath> </template> </odoo>
In this file:
- We inherit website.assets_frontend to include our CSS and JavaScript assets.
- The snippet list is updated with a thumbnail for the Dynamic Carousel Snippet so users can drag it into their websites.
7. Testing the Dynamic Snippet
- Restart Odoo: Restart the Odoo server to apply changes.
- Update the App List: In the Odoo backend, go to Apps, click "Update Apps List," and install the Dynamic Website Snippets module.
- Use the Snippet: Open the website editor, navigate to the Snippet section, and drag the "Dynamic Carousel" snippet onto a page. It should load items and enable carousel navigation.
8. Extending Functionality: Fetching Data from Backend
For a real-world application, you may want to load items dynamically from the backend. To achieve this, modify _loadCarouselItems to send an AJAX request to an Odoo controller that retrieves items from the database. Here’s an outline:
- Define a Controller: In controllers/main.py, define an endpoint to serve carousel data.
- Update JavaScript: Replace static data with an AJAX call to fetch real data.
Conclusion
Dynamic snippets in Odoo 18 offer a powerful way to create rich,
interactive components for your website. By combining XML, CSS, and
JavaScript, you can create snippets that load data dynamically, provide
interactive elements, and enhance user experience. With this guide,
you’ve built a basic dynamic snippet, and there’s a world of
customization possibilities from here.