SlideShare a Scribd company logo
2
Most read
5
Most read
8
Most read
Odoo Website - How to Develop Building Blocks
What are
Building Blocks
aka “Snippets”?
Odoo Website - How to Develop Building Blocks
Odoo Website - How to Develop Building Blocks
Snippet template
custom_snippets/views/snippets/s_cart_products.xml
<template id="s_cart_products" name="Products in Cart">
<section class="s_cart_products pt24 pb24">
<div class="container">
<h3 class="text-center mb32">Products in your Cart</h3>
<div class="dynamic_snippet_template o_not_editable"/>
</div>
</section>
</template>
custom_snippets/views/snippets/snippets.xml
<template id="snippets" inherit_id="website.snippets" name="custom snippets">
<xpath expr="//div[@id='snippet_effect']/div[@class='o_panel_body']" position="inside">
<t t-snippet="custom_snippets.s_cart_products" t-thumbnail="..."/>
</xpath>
</template>
Odoo Website - How to Develop Building Blocks
Odoo Website - How to Develop Building Blocks
Controller
custom_snippets/controllers/main.py
class CustomSnippets(http.Controller):
@http.route(['/custom_snippets/cart_content'], type='json', auth="public", website=True)
def cart(self):
products = request.website.sale_get_order().order_line.product_id
data = []
for product in products:
fields = product.read(['display_name', 'description_sale', 'list_price', 'website_url'])[0];
fields['image'] = request.env['website'].image_url(product, 'image_512')
data.append(fields)
return request.env['ir.ui.view']._render_template('custom_snippets.s_cart_products_card',
{'products': data})
Snippet template
custom_snippets/views/snippets/s_cart_products.xml
<template id="s_cart_products_card" name="Header Image Footer Card">
<t t-foreach="products" t-as="product">
<div class="card h-100" t-att-data-url="product['website_url']">
<h5 class="card-header" t-esc="product['display_name']"/>
<div class="card-body">
<img class="card-img-top p-3" loading="lazy" t-att-src="product['image']"/>
<div class="card-text">
<t t-esc="product['description_sale']"/>
</div>
</div>
<div class="card-footer d-flex align-items-center">
<div class="card-text">
<t t-raw="product['list_price']"/>
</div>
</div>
</div>
</t>
</template>
Public widget
custom_snippets/static/src/snippets/s_cart_product/000.js
const publicWidget = require('web.public.widget');
const DynamicSnippetCarousel = require('website.s_dynamic_snippet_carousel');
publicWidget.registry.dynamic_snippet_products = DynamicSnippetCarousel.extend({
selector: '.s_cart_products',
_fetchData: async function () {
const cards = await this._rpc({
route: '/custom_snippets/cart_content',
});
this.data = [...$(cards)]
.filter(node => node.nodeType === 1)
.map(el => el.outerHTML);
},
});
<template id="assets_snippet_s_cart_products_js_000" inherit_id="website.assets_frontend">
<xpath expr="//script[last()]" position="after">
<script type="text/javascript" src="/custom_snippets/static/src/snippets/s_cart_products/000.js"/>
</xpath>
</template>
custom_snippets/views/snippets/snippets.xml
Odoo Website - How to Develop Building Blocks
Snippet options
custom_snippets/views/snippets/snippets.xml
<template id="s_dynamic_snippet_options" inherit_id="website.snippet_options">
<xpath expr="." position="inside">
<div data-js="CartProductsOptions" data-selector=".s_cart_products" data-no-preview="true">
<we-button data-log-stuff="hello">Log stuff</we-button>
<we-title class="mt-2">Number of products</we-title>
<we-select string="⌙ Normal devices" data-attribute-name="numberOfElements" data-no-preview="true">
<we-button data-select-data-attribute="1">1</we-button>
<we-button data-select-data-attribute="2">2</we-button>
<we-button data-select-data-attribute="3">3</we-button>
<we-button data-select-data-attribute="4">4</we-button>
<we-button data-select-data-attribute="6">6</we-button>
</we-select>
<we-select string="⌙ Small devices" data-attribute-name="numberOfElementsSmallDevices" data-no-
preview="true">
<we-button data-select-data-attribute="1">1</we-button>
<we-button data-select-data-attribute="2">2</we-button>
<we-button data-select-data-attribute="3">3</we-button>
</we-select>
</div>
</xpath>
</template>
Snippet options
custom_snippets/static/src/snippets/s_cart_product/options.js
const options = require('web_editor.snippets.options');
options.registry.CartProductsOptions = options.Class.extend({
logStuff(previewMode, widgetValue, params) {
console.log(previewMode, widgetValue, params);
}
});
Odoo Website - How to Develop Building Blocks
Thank You
Odoo Website - How to Develop Building Blocks
Odoo Website - How to Develop Building Blocks

More Related Content

PDF
Odoo - Create themes for website
PPTX
Odoo's Test Framework - Learn Best Practices
PDF
Odoo - Business intelligence: Develop cube views for your own objects
PPTX
Angular 2.0 forms
PPTX
Owl: The New Odoo UI Framework
PDF
The Power of CSS Flexbox
PPTX
Security: Odoo Code Hardening
PDF
Nuxt.JS Introdruction
Odoo - Create themes for website
Odoo's Test Framework - Learn Best Practices
Odoo - Business intelligence: Develop cube views for your own objects
Angular 2.0 forms
Owl: The New Odoo UI Framework
The Power of CSS Flexbox
Security: Odoo Code Hardening
Nuxt.JS Introdruction

What's hot (20)

PDF
Introduction to React JS
PDF
Odoo - CMS dynamic widgets
PDF
Impact of the New ORM on Your Modules
PDF
Nuxtjs cheat-sheet
PDF
Creating Modern UI PowerBuilder Framework using native objects
PPTX
Tutorial: Develop an App with the Odoo Framework
PDF
Odoo icon smart buttons
PDF
엘라스틱서치 실무 가이드_202204.pdf
PPTX
An Introduction to the DOM
PDF
How to create sliding window hamburger menu style in Powerbuilder
PDF
react redux.pdf
PPTX
Common Performance Pitfalls in Odoo apps
PPTX
Css Display Property
PDF
CSS Day: CSS Grid Layout
PDF
Vue, vue router, vuex
PDF
Introduction to Redux
PDF
CSS3, Media Queries, and Responsive Design
PDF
All about Context API
PPTX
How to Use Constraint and SQL Constraint in Odoo 15
PDF
DDD 구현기초 (거의 Final 버전)
Introduction to React JS
Odoo - CMS dynamic widgets
Impact of the New ORM on Your Modules
Nuxtjs cheat-sheet
Creating Modern UI PowerBuilder Framework using native objects
Tutorial: Develop an App with the Odoo Framework
Odoo icon smart buttons
엘라스틱서치 실무 가이드_202204.pdf
An Introduction to the DOM
How to create sliding window hamburger menu style in Powerbuilder
react redux.pdf
Common Performance Pitfalls in Odoo apps
Css Display Property
CSS Day: CSS Grid Layout
Vue, vue router, vuex
Introduction to Redux
CSS3, Media Queries, and Responsive Design
All about Context API
How to Use Constraint and SQL Constraint in Odoo 15
DDD 구현기초 (거의 Final 버전)
Ad

Similar to Odoo Website - How to Develop Building Blocks (20)

PPTX
How to Create a Dynamic Snippet in Odoo 17
PDF
Polymer
DOC
Templates81 special document
DOC
Templates81 special document
PDF
Magento 2 - hands on MeetMagento Romania 2016
TXT
Facebook.html
TXT
Facebook.html
TXT
zynga-online.facebook.html
TXT
Private slideshow
TXT
Xxx
PDF
Technical Preview: The New Shopware Admin
PDF
Building beautiful websites with bootstrap a case study (DevelopMentor webcast)
PDF
Odoo Experience 2018 - From a Web Controller to a Full CMS
PDF
HTML5 and the dawn of rich mobile web applications pt 2
PDF
Vaadin Components @ Angular U
PDF
Your Custom WordPress Admin Pages Suck
PDF
Component Driven Design and Development
PDF
Atomic design con pattern lab
PPTX
Diseño de Sistemas de Diseño con Atomic Design y Pattern Lab
TXT
Schoology tutorial[1]
How to Create a Dynamic Snippet in Odoo 17
Polymer
Templates81 special document
Templates81 special document
Magento 2 - hands on MeetMagento Romania 2016
Facebook.html
Facebook.html
zynga-online.facebook.html
Private slideshow
Xxx
Technical Preview: The New Shopware Admin
Building beautiful websites with bootstrap a case study (DevelopMentor webcast)
Odoo Experience 2018 - From a Web Controller to a Full CMS
HTML5 and the dawn of rich mobile web applications pt 2
Vaadin Components @ Angular U
Your Custom WordPress Admin Pages Suck
Component Driven Design and Development
Atomic design con pattern lab
Diseño de Sistemas de Diseño con Atomic Design y Pattern Lab
Schoology tutorial[1]
Ad

More from Odoo (20)

PPTX
Timesheet Workshop: The Timesheet App People Love!
PPTX
Odoo 3D Product View with Google Model-Viewer
PPTX
Keynote - Vision & Strategy
PPTX
Opening Keynote - Unveilling Odoo 14
PDF
Extending Odoo with a Comprehensive Budgeting and Forecasting Capability
PDF
Managing Multi-channel Selling with Odoo
PPTX
Product Configurator: Advanced Use Case
PDF
Accounting Automation: How Much Money We Saved and How?
PPTX
Rock Your Logistics with Advanced Operations
PPTX
Transition from a cost to a flow-centric organization
PDF
Synchronization: The Supply Chain Response to Overcome the Crisis
PPTX
Running a University with Odoo
PPTX
Down Payments on Purchase Orders in Odoo
PPTX
Odoo Implementation in Phases - Success Story of a Retail Chain 3Sach food
PPTX
Migration from Salesforce to Odoo
PPTX
Preventing User Mistakes by Using Machine Learning
PPTX
Becoming an Odoo Expert: How to Prepare for the Certification
PPTX
Instant Printing of any Odoo Report or Shipping Label
PPTX
How Odoo helped an Organization Grow 3 Fold
PPTX
From Shopify to Odoo
Timesheet Workshop: The Timesheet App People Love!
Odoo 3D Product View with Google Model-Viewer
Keynote - Vision & Strategy
Opening Keynote - Unveilling Odoo 14
Extending Odoo with a Comprehensive Budgeting and Forecasting Capability
Managing Multi-channel Selling with Odoo
Product Configurator: Advanced Use Case
Accounting Automation: How Much Money We Saved and How?
Rock Your Logistics with Advanced Operations
Transition from a cost to a flow-centric organization
Synchronization: The Supply Chain Response to Overcome the Crisis
Running a University with Odoo
Down Payments on Purchase Orders in Odoo
Odoo Implementation in Phases - Success Story of a Retail Chain 3Sach food
Migration from Salesforce to Odoo
Preventing User Mistakes by Using Machine Learning
Becoming an Odoo Expert: How to Prepare for the Certification
Instant Printing of any Odoo Report or Shipping Label
How Odoo helped an Organization Grow 3 Fold
From Shopify to Odoo

Recently uploaded (20)

PDF
Outsourced Audit & Assurance in USA Why Globus Finanza is Your Trusted Choice
PPTX
Amazon (Business Studies) management studies
PPTX
job Avenue by vinith.pptxvnbvnvnvbnvbnbmnbmbh
PDF
Deliverable file - Regulatory guideline analysis.pdf
PPTX
New Microsoft PowerPoint Presentation - Copy.pptx
PDF
kom-180-proposal-for-a-directive-amending-directive-2014-45-eu-and-directive-...
PDF
How to Get Funding for Your Trucking Business
PPTX
HR Introduction Slide (1).pptx on hr intro
PDF
How to Get Business Funding for Small Business Fast
PPTX
3. HISTORICAL PERSPECTIVE UNIIT 3^..pptx
PDF
BsN 7th Sem Course GridNNNNNNNN CCN.pdf
PDF
Katrina Stoneking: Shaking Up the Alcohol Beverage Industry
PPTX
svnfcksanfskjcsnvvjknsnvsdscnsncxasxa saccacxsax
PDF
Ôn tập tiếng anh trong kinh doanh nâng cao
PPT
Chapter four Project-Preparation material
PDF
Chapter 5_Foreign Exchange Market in .pdf
DOCX
Business Management - unit 1 and 2
PPTX
ICG2025_ICG 6th steering committee 30-8-24.pptx
PDF
Laughter Yoga Basic Learning Workshop Manual
PPTX
Board-Reporting-Package-by-Umbrex-5-23-23.pptx
Outsourced Audit & Assurance in USA Why Globus Finanza is Your Trusted Choice
Amazon (Business Studies) management studies
job Avenue by vinith.pptxvnbvnvnvbnvbnbmnbmbh
Deliverable file - Regulatory guideline analysis.pdf
New Microsoft PowerPoint Presentation - Copy.pptx
kom-180-proposal-for-a-directive-amending-directive-2014-45-eu-and-directive-...
How to Get Funding for Your Trucking Business
HR Introduction Slide (1).pptx on hr intro
How to Get Business Funding for Small Business Fast
3. HISTORICAL PERSPECTIVE UNIIT 3^..pptx
BsN 7th Sem Course GridNNNNNNNN CCN.pdf
Katrina Stoneking: Shaking Up the Alcohol Beverage Industry
svnfcksanfskjcsnvvjknsnvsdscnsncxasxa saccacxsax
Ôn tập tiếng anh trong kinh doanh nâng cao
Chapter four Project-Preparation material
Chapter 5_Foreign Exchange Market in .pdf
Business Management - unit 1 and 2
ICG2025_ICG 6th steering committee 30-8-24.pptx
Laughter Yoga Basic Learning Workshop Manual
Board-Reporting-Package-by-Umbrex-5-23-23.pptx

Odoo Website - How to Develop Building Blocks

  • 5. Snippet template custom_snippets/views/snippets/s_cart_products.xml <template id="s_cart_products" name="Products in Cart"> <section class="s_cart_products pt24 pb24"> <div class="container"> <h3 class="text-center mb32">Products in your Cart</h3> <div class="dynamic_snippet_template o_not_editable"/> </div> </section> </template> custom_snippets/views/snippets/snippets.xml <template id="snippets" inherit_id="website.snippets" name="custom snippets"> <xpath expr="//div[@id='snippet_effect']/div[@class='o_panel_body']" position="inside"> <t t-snippet="custom_snippets.s_cart_products" t-thumbnail="..."/> </xpath> </template>
  • 8. Controller custom_snippets/controllers/main.py class CustomSnippets(http.Controller): @http.route(['/custom_snippets/cart_content'], type='json', auth="public", website=True) def cart(self): products = request.website.sale_get_order().order_line.product_id data = [] for product in products: fields = product.read(['display_name', 'description_sale', 'list_price', 'website_url'])[0]; fields['image'] = request.env['website'].image_url(product, 'image_512') data.append(fields) return request.env['ir.ui.view']._render_template('custom_snippets.s_cart_products_card', {'products': data})
  • 9. Snippet template custom_snippets/views/snippets/s_cart_products.xml <template id="s_cart_products_card" name="Header Image Footer Card"> <t t-foreach="products" t-as="product"> <div class="card h-100" t-att-data-url="product['website_url']"> <h5 class="card-header" t-esc="product['display_name']"/> <div class="card-body"> <img class="card-img-top p-3" loading="lazy" t-att-src="product['image']"/> <div class="card-text"> <t t-esc="product['description_sale']"/> </div> </div> <div class="card-footer d-flex align-items-center"> <div class="card-text"> <t t-raw="product['list_price']"/> </div> </div> </div> </t> </template>
  • 10. Public widget custom_snippets/static/src/snippets/s_cart_product/000.js const publicWidget = require('web.public.widget'); const DynamicSnippetCarousel = require('website.s_dynamic_snippet_carousel'); publicWidget.registry.dynamic_snippet_products = DynamicSnippetCarousel.extend({ selector: '.s_cart_products', _fetchData: async function () { const cards = await this._rpc({ route: '/custom_snippets/cart_content', }); this.data = [...$(cards)] .filter(node => node.nodeType === 1) .map(el => el.outerHTML); }, }); <template id="assets_snippet_s_cart_products_js_000" inherit_id="website.assets_frontend"> <xpath expr="//script[last()]" position="after"> <script type="text/javascript" src="/custom_snippets/static/src/snippets/s_cart_products/000.js"/> </xpath> </template> custom_snippets/views/snippets/snippets.xml
  • 12. Snippet options custom_snippets/views/snippets/snippets.xml <template id="s_dynamic_snippet_options" inherit_id="website.snippet_options"> <xpath expr="." position="inside"> <div data-js="CartProductsOptions" data-selector=".s_cart_products" data-no-preview="true"> <we-button data-log-stuff="hello">Log stuff</we-button> <we-title class="mt-2">Number of products</we-title> <we-select string="⌙ Normal devices" data-attribute-name="numberOfElements" data-no-preview="true"> <we-button data-select-data-attribute="1">1</we-button> <we-button data-select-data-attribute="2">2</we-button> <we-button data-select-data-attribute="3">3</we-button> <we-button data-select-data-attribute="4">4</we-button> <we-button data-select-data-attribute="6">6</we-button> </we-select> <we-select string="⌙ Small devices" data-attribute-name="numberOfElementsSmallDevices" data-no- preview="true"> <we-button data-select-data-attribute="1">1</we-button> <we-button data-select-data-attribute="2">2</we-button> <we-button data-select-data-attribute="3">3</we-button> </we-select> </div> </xpath> </template>
  • 13. Snippet options custom_snippets/static/src/snippets/s_cart_product/options.js const options = require('web_editor.snippets.options'); options.registry.CartProductsOptions = options.Class.extend({ logStuff(previewMode, widgetValue, params) { console.log(previewMode, widgetValue, params); } });

Editor's Notes

  • #2: Odoo logo centered w/ tagline
  • #4: Place your own screenshot Select screenshot Click ‘Replace Image’ Select ‘Upload from computer’ from dropdown menu Choose photo Adjust accordingly, without distorting (stretching) photo
  • #5: Finished product
  • #7: Place your own screenshot Select screenshot Click ‘Replace Image’ Select ‘Upload from computer’ from dropdown menu Choose photo Adjust accordingly, without distorting (stretching) photo
  • #8: Place your own screenshot Select screenshot Click ‘Replace Image’ Select ‘Upload from computer’ from dropdown menu Choose photo Adjust accordingly, without distorting (stretching) photo
  • #12: Place your own screenshot Select screenshot Click ‘Replace Image’ Select ‘Upload from computer’ from dropdown menu Choose photo Adjust accordingly, without distorting (stretching) photo
  • #15: Finished product
  • #24: Place your own screenshot Select screenshot Click ‘Replace Image’ Select ‘Upload from computer’ from dropdown menu Choose photo Adjust accordingly, without distorting (stretching) photo
  • #25: Place your own screenshot Select screenshot Click ‘Replace Image’ Select ‘Upload from computer’ from dropdown menu Choose photo Adjust accordingly, without distorting (stretching) photo
  • #26: Place your own screenshot Select screenshot Click ‘Replace Image’ Select ‘Upload from computer’ from dropdown menu Choose photo Adjust accordingly, without distorting (stretching) photo
  • #27: Place your own screenshot Select screenshot Click ‘Replace Image’ Select ‘Upload from computer’ from dropdown menu Choose photo Adjust accordingly, without distorting (stretching) photo
  • #29: And, now, we have 580 employees.