Shop /shop 20 Website Shop self /shop open Sale bg-success o_ribbon_left Sold out bg-danger o_ribbon_left New! bg-primary o_ribbon_left Products Dynamic Snippet code ProductProduct = model.env['product.product'] FieldMonetary = model.env['ir.qweb.field.monetary'] website = request.website.get_current_website() dynamic_filter = model.env.context.get('dynamic_filter') limit = model.env.context.get('limit') search_domain = model.env.context.get('search_domain') get_rendering_data_structure = model.env.context.get('get_rendering_data_structure') escape = dynamic_filter.escape_falsy_as_empty domain = [('website_published', '=', True)] + website.website_domain() + (search_domain or []) products = ProductProduct.search(domain, limit=limit) _ = products.mapped('name') monetary_options = { 'display_currency': request.website.get_current_pricelist().currency_id, } max_nb_chars = 100 res_products = [] for product in products: res_product = product._read_format(['id', 'name', 'website_url', 'description_sale'])[0] res_product.update(product._get_combination_info_variant()) if res_product['description_sale'] and len(res_product['description_sale']) > max_nb_chars: res_product['description_sale'] = "%s ..." % res_product['description_sale'][:max_nb_chars] res_product['list_price'] = FieldMonetary.value_to_html(res_product['price'], monetary_options) data = get_rendering_data_structure() for field_name in dynamic_filter.field_names.split(","): field = ProductProduct._fields.get(field_name) if field and field.type == 'binary': data['image_fields'][field_name] = escape(website.image_url(product, field_name)) elif field_name == 'list_price': data['fields'][field_name] = res_product[field_name] else: data['fields'][field_name] = escape(res_product[field_name]) data['fields']['call_to_action_url'] = escape(product['website_url']) res_products.append(data) response = res_products display_name,description_sale,image_512,list_price Products sale.order create_customer True Create a Customer res.partner