From 986b4c49d14516b7716efeb853c0656318728491 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Tue, 19 Nov 2013 11:21:17 +0100 Subject: [PATCH] [IMP] url generation & filtering * add filtering in enumerate_pages directly * make ModelConverter use name_search for generation todo: per-request name_get caching/coalescing? bzr revid: xmo@openerp.com-20131119102117-p7de3t93qex1n28q --- addons/website/models/ir_http.py | 20 +++++++++++++------- addons/website/models/website.py | 23 +++++++++++++---------- 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/addons/website/models/ir_http.py b/addons/website/models/ir_http.py index 8350106415d..d8f7f0111f9 100644 --- a/addons/website/models/ir_http.py +++ b/addons/website/models/ir_http.py @@ -31,19 +31,25 @@ class ModelConverter(ir.ir_http.ModelConverter): self.regex = r'[A-Za-z0-9-_]*?(\d+)' def to_url(self, value): - [(_, name)] = value.name_get() - return "%s-%d" % (slugify(name), value.id) + if isinstance(value, orm.browse_record): + [(id, name)] = value.name_get() + else: + # assume name_search result tuple + id, name = value + return "%s-%d" % (slugify(name), id) - 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) + def generate(self, query=None): + return request.registry[self.model].name_search( + request.cr, request.uid, + name=query or '', + 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): + def generate(self, query=None): View = request.registry['ir.ui.view'] views = View.search_read( request.cr, request.uid, [['page', '=', True]], @@ -54,5 +60,5 @@ class PageConverter(werkzeug.routing.PathConverter): for view in views: xid = xids[view['id']] - if xid: + if xid and (not query or query in xid): yield xid diff --git a/addons/website/models/website.py b/addons/website/models/website.py index dbbf72f4702..4c2f4323057 100644 --- a/addons/website/models/website.py +++ b/addons/website/models/website.py @@ -336,13 +336,15 @@ class website(osv.osv): (arg == 'self' or arg in rule._converters) for arg in args) - def enumerate_pages(self, cr, uid, ids, context=None): + def enumerate_pages(self, cr, uid, ids, query_string=None, context=None): """ Available pages in the website/CMS. This is mostly used for links generation and can be overridden by modules setting up new HTML controllers for dynamic pages (e.g. blog). By default, returns template views marked as pages. + :param str query_string: a (user-provided) string, fetches pages + matching the string :returns: a list of mappings with two keys: ``name`` is the displayable name of the resource (page), ``url`` is the absolute URL of the same. @@ -354,29 +356,30 @@ class website(osv.osv): continue converters = rule._converters + filtered = bool(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())) + converter.generate(query=query_string))) else: # force single iteration for literal urls generated = [{}] for values in generated: domain_part, url = rule.build(values, append_unknown=False) - yield {'name': url, 'url': url } + page = {'name': url, 'url': url} + + if not filtered and query_string and not self.page_matches(cr, uid, page, query_string, context=context): + continue + yield page def search_pages(self, cr, uid, ids, needle=None, limit=None, context=None): - pages = self.enumerate_pages(cr, uid, ids, context=context) - - if needle: - pages = itertools.ifilter(lambda v: self.page_matches( - cr, uid, v, needle, context=None), pages) - - return list(itertools.islice(pages, limit)) + return list(itertools.islice( + self.enumerate_pages(cr, uid, ids, query_string=needle, context=context), + limit)) def page_matches(self, cr, uid, page, needle, context=None): """ Checks that a "page" matches a user-provide search string.