During last cubicweb sprint, I was asked if it was possible to customize the search box CubicWeb comes with. By default, you can use it to either type RQL queries, plain text queries or standard shortcuts such as <EntityType> or <EntityType> <attrname> <value>. Ultimately, all queries are translated to rql since it's the only language understood on the server (data) side. To transform the user query into RQL, CubicWeb uses the so-called magicsearch component which in turn delegates to a number of query preprocessor that are responsible of interpreting the user query and generating corresponding RQL. The code of the main processor loop is easy to understand: for proc in self.processors:
try:
return proc.process_query(uquery, req)
except (RQLSyntaxError, BadRQLQuery):
pass
The idea is simple: for each query processor, try to translate the query. If it fails, try with the next processor, if it succeeds, we're done and the RQL query will be executed. Now that the general mechanism is understood, here's an example of code that could be used in a forge-based cube to add a new search shortcut to find tickets. We'd like to use the project_name:text syntax to search for tickets of project_name containing text (e.g pylint:warning). Here's the corresponding preprocessor code: from cubicweb.web.views.magicsearch import BaseQueryProcessor
class MyCustomQueryProcessor(BaseQueryProcessor):
priority = 0 # controls order in which processors are tried
def preprocess_query(self, uquery, req):
"""
:param uqery: the query as sent by the browser
:param req: the standard, omnipresent, cubicweb's req object
"""
try:
project_name, text = uquery.split(':')
except ValueError:
return None # the shortcut doesn't apply
return (u'Any T WHERE T is Ticket, T concerns P, P name %(p)s, '
u'T has_text %(t)s', {'p': project_name, 't': text})
The code is rather self-explanatory, but here's a few additional comments:
To summarize, if you want to customize the search box, you have to:
and CubicWeb will do the rest ! |

