[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
This commit is contained in:
Xavier Morel
2013-11-19 11:21:17 +01:00
parent 5bab419967
commit 986b4c49d1
2 changed files with 26 additions and 17 deletions
+13 -7
View File
@@ -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
+13 -10
View File
@@ -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.