Source diving
Odoo is opensource and has module structure. So, for the question
– Is it possible to change /this/ in Odoo?
the only answer is:
– Yes, everything is possible to do in Odoo.
OK, but how to do that? Where to find an instruction of how to implement some particular feature?
Let's take an example. Imagine we need a custom link for product at
website shop. By default link is generated from Name field, but you
need to make it be generated from new Name SEO field.
i.e. instead of this link:
/shop/product/ipad-mini-8
there should be this one:
/shop/product/super-seo-link-for-ipad-mini-8
where product has fields:
Name: iPad Mini
Name SEO: Super SEO link for iPad Mini
How to do that? Can we find the answer in documentation? I believe, it doesn't have an answer.
So, let's try to do it ourself. We have Odoo source, so let's try to find a solution there.
In our example we can start from seaching by /shop/product/:
./addons/website_sale_options/controllers/main.py:10: @http.route(['/shop/product/<model("product.template"):product>'], type='http', auth="public", website=True)
./addons/website_sale/models/product.py:112: res[product.id] = "/shop/product/%s" % (product.id,)
./addons/website_sale/models/product.py:186: res[product.id] = "/shop/product/%s" % (product.product_tmpl_id.id,)
./addons/website_sale/controllers/main.py:230: @http.route(['/shop/product/<model("product.template"):product>'], type='http', auth="public", website=True)
./addons/website_sale/controllers/main.py:276: @http.route(['/shop/product/comment/<int:product_template_id>'], type='http', auth="public", methods=['POST'], website=True)
./addons/website_sale/controllers/main.py:850: return request.redirect("/shop/product/%s?enable_editor=1" % slug(product.product_tmpl_id))
These lines from addons/website_sale/controllers/main.py looks interesting:
@http.route(['/shop/product/<model("product.template"):product>'], type='http', auth="public", website=True)
def product(self, product, category='', search='', **kwargs):
What about <model("product.template"):product>? What is it? How it
works? There should be a way for you to find the answer in
source. Maybe you know about werkzeug library, maybe you know about
slug function, maybe you know about ir.http model. So there should
be a keyword to search. At the worst you can search by "model"
keyword OR look through whole website module.
OK, I found the answer in addons/website/models/ir_http.py. Function to_url is what we need.
from openerp.addons.website.models.website import slug, url_for, _UNSLUG_RE
#..
class ir_http(orm.AbstractModel):
_inherit = 'ir.http'
rerouting_limit = 10
geo_ip_resolver = None
def _get_converters(self):
return dict(
super(ir_http, self)._get_converters(),
model=ModelConverter,
page=PageConverter,
)
#..
class ModelConverter(ir.ir_http.ModelConverter):
def __init__(self, url_map, model=False, domain='[]'):
super(ModelConverter, self).__init__(url_map, model)
self.domain = domain
self.regex = _UNSLUG_RE.pattern
def to_url(self, value):
return slug(value)
#...addons/website/models/website.py
def slug(value):
if isinstance(value, orm.browse_record):
# [(id, name)] = value.name_get()
id, name = value.id, value.display_name
else:
# assume name_search result tuple
id, name = value
slugname = slugify(name or '').strip().strip('-')
if not slugname:
return str(id)
return "%s-%d" % (slugname, id)
So, that is. To make a custom link, we have to inherit ModelConverter
and modify to_url function. Something like that:
from openerp.addons.website.models.website import slugify
from openerp.addons.website.models.ir_http import ModelConverter
class ModelConverterCustom(ModelConverter):
def to_url(self, value):
if isinstance(value, orm.browse_record) and hasattr(value, 'name_seo'):
id, name = value.id, value.name_seo
slugname = slugify(name or '').strip().strip('-')
if slugname:
return "%s-%d" % (slugname, id)
return super(ModelConverterCustom, self).to_url(value)
class ir_http(orm.AbstractModel):
_inherit = 'ir.http'
def _get_converters(self):
res = super(ir_http, self)._get_converters()
res['model'] = ModelConverterCustom
return res
This is the way I use in odoo development:
- Dive into source
- Figure out how it works
- Create module to make changes you need