174 term = nodes.SortTerm(sortfunc, sortasc) |
174 term = nodes.SortTerm(sortfunc, sortasc) |
175 rqlst.add_sort_term(term) |
175 rqlst.add_sort_term(term) |
176 |
176 |
177 def insert_attr_select_relation(rqlst, mainvar, rtype, role, attrname, |
177 def insert_attr_select_relation(rqlst, mainvar, rtype, role, attrname, |
178 sortfuncname=None, sortasc=True): |
178 sortfuncname=None, sortasc=True): |
179 """modify a syntax tree to retrieve only relevant attribute `attr` of `var`""" |
179 """modify a syntax tree to : |
|
180 * link a new variable to `mainvar` through `rtype` (where mainvar has `role`) |
|
181 * retrieve only the newly inserted variable and its `attrname` |
|
182 |
|
183 Sorting: |
|
184 * on `attrname` ascendant (`sortasc`=True) or descendant (`sortasc`=False) |
|
185 * on `sortfuncname`(`attrname`) if `sortfuncname` is specified |
|
186 * no sort if `sortasc` is None |
|
187 """ |
180 _cleanup_rqlst(rqlst, mainvar) |
188 _cleanup_rqlst(rqlst, mainvar) |
181 var = _prepare_vocabulary_rqlst(rqlst, mainvar, rtype, role) |
189 var = _prepare_vocabulary_rqlst(rqlst, mainvar, rtype, role) |
182 # not found, create one |
190 # not found, create one |
183 attrvar = rqlst.make_variable() |
191 attrvar = rqlst.make_variable() |
184 rqlst.add_relation(var, attrname, attrvar) |
192 rqlst.add_relation(var, attrname, attrvar) |
185 # if query is grouped, we have to add the attribute variable |
193 # if query is grouped, we have to add the attribute variable |
186 if rqlst.groupby: |
194 if rqlst.groupby: |
187 if not attrvar in rqlst.groupby: |
195 if not attrvar in rqlst.groupby: |
188 rqlst.add_group_var(attrvar) |
196 rqlst.add_group_var(attrvar) |
189 _set_orderby(rqlst, attrvar, sortasc, sortfuncname) |
197 if sortasc is not None: |
|
198 _set_orderby(rqlst, attrvar, sortasc, sortfuncname) |
190 # add attribute variable to selection |
199 # add attribute variable to selection |
191 rqlst.add_selected(attrvar) |
200 rqlst.add_selected(attrvar) |
192 # add is restriction if necessary |
201 # add is restriction if necessary |
193 if not mainvar.stinfo['typerels']: |
202 if not mainvar.stinfo['typerels']: |
194 etypes = frozenset(sol[mainvar.name] for sol in rqlst.solutions) |
203 etypes = frozenset(sol[mainvar.name] for sol in rqlst.solutions) |
344 # set this to a stored procedure name if you want to sort on the result of |
353 # set this to a stored procedure name if you want to sort on the result of |
345 # this function's result instead of direct value |
354 # this function's result instead of direct value |
346 sortfunc = None |
355 sortfunc = None |
347 # ascendant/descendant sorting |
356 # ascendant/descendant sorting |
348 sortasc = True |
357 sortasc = True |
|
358 # if you want to call a view on the entity instead of using `target_attr` |
|
359 label_vid = None |
349 |
360 |
350 @property |
361 @property |
351 def title(self): |
362 def title(self): |
352 return display_name(self.req, self.rtype, form=self.role) |
363 return display_name(self.req, self.rtype, form=self.role) |
353 |
364 |
354 def vocabulary(self): |
365 def vocabulary(self): |
355 """return vocabulary for this facet, eg a list of 2-uple (label, value) |
366 """return vocabulary for this facet, eg a list of 2-uple (label, value) |
356 """ |
367 """ |
357 rqlst = self.rqlst |
368 rqlst = self.rqlst |
358 rqlst.save_state() |
369 rqlst.save_state() |
|
370 if self.label_vid is not None and self.sortfunc is None: |
|
371 sort = None # will be sorted on label |
|
372 else: |
|
373 sort = self.sortasc |
359 try: |
374 try: |
360 mainvar = self.filtered_variable |
375 mainvar = self.filtered_variable |
361 insert_attr_select_relation(rqlst, mainvar, self.rtype, self.role, |
376 insert_attr_select_relation(rqlst, mainvar, self.rtype, self.role, |
362 self.target_attr, self.sortfunc, self.sortasc) |
377 self.target_attr, self.sortfunc, sort) |
363 try: |
378 try: |
364 rset = self.rqlexec(rqlst.as_string(), self.rset.args, self.rset.cachekey) |
379 rset = self.rqlexec(rqlst.as_string(), self.rset.args, self.rset.cachekey) |
365 except: |
380 except: |
366 self.exception('error while getting vocabulary for %s, rql: %s', |
381 self.exception('error while getting vocabulary for %s, rql: %s', |
367 self, rqlst.as_string()) |
382 self, rqlst.as_string()) |
382 return [str(x) for x, in self.rqlexec(rqlst.as_string())] |
397 return [str(x) for x, in self.rqlexec(rqlst.as_string())] |
383 finally: |
398 finally: |
384 rqlst.recover() |
399 rqlst.recover() |
385 |
400 |
386 def rset_vocabulary(self, rset): |
401 def rset_vocabulary(self, rset): |
387 _ = self.req._ |
402 if self.label_vid is None: |
388 return [(_(label), eid) for eid, label in rset] |
403 _ = self.req._ |
|
404 return [(_(label), eid) for eid, label in rset] |
|
405 if self.sortfunc is None: |
|
406 return sorted((entity.view(self.label_vid), entity.eid) |
|
407 for entity in rset.entities()) |
|
408 return [(entity.view(self.label_vid), entity.eid) |
|
409 for entity in rset.entities()] |
389 |
410 |
390 @cached |
411 @cached |
391 def support_and(self): |
412 def support_and(self): |
392 rschema = self.schema.rschema(self.rtype) |
413 rschema = self.schema.rschema(self.rtype) |
393 if self.role == 'subject': |
414 if self.role == 'subject': |
568 var = self.rqlst.make_variable() |
590 var = self.rqlst.make_variable() |
569 if self.role == 'subject': |
591 if self.role == 'subject': |
570 self.rqlst.add_relation(self.filtered_variable, self.rtype, var) |
592 self.rqlst.add_relation(self.filtered_variable, self.rtype, var) |
571 else: |
593 else: |
572 self.rqlst.add_relation(var, self.rtype, self.filtered_variable) |
594 self.rqlst.add_relation(var, self.rtype, self.filtered_variable) |
|
595 |
573 |
596 |
574 ## html widets ################################################################ |
597 ## html widets ################################################################ |
575 |
598 |
576 class FacetVocabularyWidget(HTMLWidget): |
599 class FacetVocabularyWidget(HTMLWidget): |
577 |
600 |
654 |
677 |
655 def _render(self): |
678 def _render(self): |
656 facet = self.facet |
679 facet = self.facet |
657 facet.req.add_js('ui.slider.js') |
680 facet.req.add_js('ui.slider.js') |
658 facet.req.add_css('ui.all.css') |
681 facet.req.add_css('ui.all.css') |
659 sliderid = make_uid('the slider') |
682 sliderid = make_uid('theslider') |
660 facetid = xml_escape(self.facet.id) |
683 facetid = xml_escape(self.facet.id) |
661 facet.req.html_headers.add_onload(self.onload % { |
684 facet.req.html_headers.add_onload(self.onload % { |
662 'sliderid': sliderid, |
685 'sliderid': sliderid, |
663 'facetid': facetid, |
686 'facetid': facetid, |
664 'minvalue': self.minvalue, |
687 'minvalue': self.minvalue, |
720 % (cssclass, xml_escape(unicode(self.value)))) |
743 % (cssclass, xml_escape(unicode(self.value)))) |
721 self.w(u'<img src="%s" alt="%s"/> ' % (imgsrc, imgalt)) |
744 self.w(u'<img src="%s" alt="%s"/> ' % (imgsrc, imgalt)) |
722 self.w(u'<a href="javascript: {}">%s</a>' % xml_escape(self.label)) |
745 self.w(u'<a href="javascript: {}">%s</a>' % xml_escape(self.label)) |
723 self.w(u'</div>') |
746 self.w(u'</div>') |
724 |
747 |
|
748 |
725 class CheckBoxFacetWidget(HTMLWidget): |
749 class CheckBoxFacetWidget(HTMLWidget): |
726 selected_img = "black-check.png" |
750 selected_img = "black-check.png" |
727 unselected_img = "black-uncheck.png" |
751 unselected_img = "black-uncheck.png" |
728 |
752 |
729 def __init__(self, req, facet, value, selected): |
753 def __init__(self, req, facet, value, selected): |