diff --git a/addons/website/controllers/main.py b/addons/website/controllers/main.py index 1959abb7ab4..8d797273077 100644 --- a/addons/website/controllers/main.py +++ b/addons/website/controllers/main.py @@ -114,13 +114,13 @@ class Website(openerp.addons.web.controllers.main.Home): def snippets(self): return request.website.render('website.snippets') - @website.route('/page/', type='http', auth="public", multilang=True) - def page(self, path, **kwargs): + @website.route('/page/', type='http', auth="public", multilang=True) + def page(self, page): values = { - 'path': path, + 'path': page, } - return request.website.render(path, values) + return request.website.render(page, values) @website.route('/website/customize_template_toggle', type='json', auth='user') def customize_template_set(self, view_id): diff --git a/addons/website/models/ir_http.py b/addons/website/models/ir_http.py index 1a29a0c0fad..8350106415d 100644 --- a/addons/website/models/ir_http.py +++ b/addons/website/models/ir_http.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +import werkzeug.routing import openerp from openerp.osv import orm from openerp.http import request @@ -13,6 +14,7 @@ class ir_http(orm.AbstractModel): return dict( super(ir_http, self)._get_converters(), model=ModelConverter, + page=PageConverter, ) def _auth_method_public(self): @@ -35,3 +37,22 @@ class ModelConverter(ir.ir_http.ModelConverter): def generate(self): for id in request.registry[self.model].search(request.cr, request.uid, [], context=request.context): yield request.registry[self.model].browse(request.cr, request.uid, id, context=request.context) + +class PageConverter(werkzeug.routing.PathConverter): + """ Only point of this converter is to bundle pages enumeration logic + + Sads got: no way to get the view's human-readable name even if one exists + """ + def generate(self): + View = request.registry['ir.ui.view'] + views = View.search_read( + request.cr, request.uid, [['page', '=', True]], + fields=[], order='name', context=request.context) + xids = View.get_external_id( + request.cr, request.uid, [view['id'] for view in views], + context=request.context) + + for view in views: + xid = xids[view['id']] + if xid: + yield xid diff --git a/addons/website/models/website.py b/addons/website/models/website.py index 99343b800cf..dbbf72f4702 100644 --- a/addons/website/models/website.py +++ b/addons/website/models/website.py @@ -285,16 +285,19 @@ class website(osv.osv): """ endpoint = rule.endpoint methods = rule.methods or ['GET'] + converters = rule._converters.values() return ( 'GET' in methods and endpoint.exposed == 'http' and endpoint.auth in ('none', 'public') and getattr(endpoint, 'cms', False) + # preclude combinatorial explosion by only allowing a single converter + and len(converters) <= 1 # ensure all converters on the rule are able to generate values for # themselves and all(hasattr(converter, 'generate') - for converter in rule._converters.itervalues()) + for converter in converters) ) and self.endpoint_is_enumerable(rule) def endpoint_is_enumerable(self, rule): @@ -345,30 +348,22 @@ class website(osv.osv): of the same. :rtype: list({name: str, url: str}) """ - # FIXME: possibility to add custom converters without editing server - # would allow the creation of a pages converter generating page - # urls on its own - View = self.pool['ir.ui.view'] - views = View.search_read(cr, uid, [['page', '=', True]], - fields=['name'], order='name', context=context) - xids = View.get_external_id(cr, uid, [view['id'] for view in views], context=context) - for view in views: - if xids[view['id']]: - yield { - 'name': view['name'], - 'url': '/page/' + xids[view['id']], - } - router = request.httprequest.app.get_db_router(request.db) for rule in router.iter_rules(): if not self.rule_is_enumerable(rule): continue - generated = map(dict, itertools.product(*( - # generate w/ pattern using name_search - itertools.izip(itertools.repeat(name), converter.generate()) - for name, converter in rule._converters.iteritems() - ))) + converters = rule._converters + if converters: + # allow single converter as decided by fp, checked by + # rule_is_enumerable + [(name, converter)] = converters.items() + generated = ({k: v} for k, v in itertools.izip( + itertools.repeat(name), + converter.generate())) + else: + # force single iteration for literal urls + generated = [{}] for values in generated: domain_part, url = rule.build(values, append_unknown=False)