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)

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