21 composite='subject') |
21 composite='subject') |
22 |
22 |
23 The two other entity types defined in the schema are `Visit` and `Agency` but we |
23 The two other entity types defined in the schema are `Visit` and `Agency` but we |
24 can also guess from the above that this application uses the two cubes |
24 can also guess from the above that this application uses the two cubes |
25 `comment`_ and |
25 `comment`_ and |
26 `addressbook`_ (remember, cubicweb is only a game where you assemble cubes !). |
26 `addressbook`_ (remember, cubicweb is only a game where you assemble cubes !). |
27 |
27 |
28 While we know that just defining the schema in enough to have a full, usable, |
28 While we know that just defining the schema in enough to have a full, usable, |
29 (testable !) application, we also know that every application needs to be |
29 (testable !) application, we also know that every application needs to be |
30 customized to fulfill the needs it was built for. So in this case, what we |
30 customized to fulfill the needs it was built for. So in this case, what we |
31 needed most was some custom filters that would let us restrict searches |
31 needed most was some custom filters that would let us restrict searches |
32 according |
32 according |
33 to surfaces, prices or zipcodes. Fortunately for us, Cubicweb provides the |
33 to surfaces, prices or zipcodes. Fortunately for us, Cubicweb provides the |
34 **facets** (image_) mechanism and a few base classes that make the task quite |
34 **facets** (image_) mechanism and a few base classes that make the task quite |
35 easy: |
35 easy: |
36 |
36 |
37 .. sourcecode:: python |
37 .. sourcecode:: python |
38 |
38 |
39 class PostalCodeFacet(RelationFacet): |
39 class PostalCodeFacet(RelationFacet): |
40 id = 'postalcode-facet' # every registered class must have an id |
40 __regid__ = 'postalcode-facet' # every registered class must have an id |
41 __select__ = implements('Office') # this facet should only be selected when |
41 __select__ = implements('Office') # this facet should only be selected when |
42 # visualizing offices |
42 # visualizing offices |
43 rtype = 'has_address' # this facet is a filter on the entity linked to |
43 rtype = 'has_address' # this facet is a filter on the entity linked to |
44 # the office thrhough the relation |
44 # the office thrhough the relation |
45 # has_address |
45 # has_address |
46 target_attr = 'postalcode' # the filter's key is the attribute "postal_code" |
46 target_attr = 'postalcode' # the filter's key is the attribute "postal_code" |
55 `Office`: |
55 `Office`: |
56 |
56 |
57 .. sourcecode:: python |
57 .. sourcecode:: python |
58 |
58 |
59 class SurfaceFacet(AttributeFacet): |
59 class SurfaceFacet(AttributeFacet): |
60 id = 'surface-facet' # every registered class must have an id |
60 __regid__ = 'surface-facet' # every registered class must have an id |
61 __select__ = implements('Office') # this facet should only be selected when |
61 __select__ = implements('Office') # this facet should only be selected when |
62 # visualizing offices |
62 # visualizing offices |
63 rtype = 'surface' # the filter's key is the attribute "surface" |
63 rtype = 'surface' # the filter's key is the attribute "surface" |
64 comparator = '>=' # override the default value of operator since |
64 comparator = '>=' # override the default value of operator since |
65 # we want to filter according to a |
65 # we want to filter according to a |
66 # minimal |
66 # minimal |
67 # value, not an exact one |
67 # value, not an exact one |
68 |
68 |
69 def rset_vocabulary(self, ___): |
69 def rset_vocabulary(self, ___): |
70 """override the default vocabulary method since we want to hard-code |
70 """override the default vocabulary method since we want to hard-code |
71 our threshold values. |
71 our threshold values. |
72 Not overriding would generate a filter box with all existing surfaces |
72 Not overriding would generate a filter box with all existing surfaces |
73 defined in the database. |
73 defined in the database. |
74 """ |
74 """ |
75 return [('> 200', '200'), ('> 250', '250'), |
75 return [('> 200', '200'), ('> 250', '250'), |
76 ('> 275', '275'), ('> 300', '300')] |
76 ('> 275', '275'), ('> 300', '300')] |
91 define restrictions `filters`_ really as easily as possible. |
91 define restrictions `filters`_ really as easily as possible. |
92 |
92 |
93 We've just added two new kind of facets in CubicWeb : |
93 We've just added two new kind of facets in CubicWeb : |
94 |
94 |
95 - The **RangeFacet** which displays a slider using `jquery`_ |
95 - The **RangeFacet** which displays a slider using `jquery`_ |
96 to choose a lower bound and an upper bound. The **RangeWidget** |
96 to choose a lower bound and an upper bound. The **RangeWidget** |
97 works with either numerical values or date values |
97 works with either numerical values or date values |
98 |
98 |
99 - The **HasRelationFacet** which displays a simple checkbox and |
99 - The **HasRelationFacet** which displays a simple checkbox and |
100 lets you refine your selection in order to get only entities |
100 lets you refine your selection in order to get only entities |
101 that actually use this relation. |
101 that actually use this relation. |
102 |
102 |
103 .. image :: http://www.cubicweb.org/Image/343498?vid=download |
103 .. image :: http://www.cubicweb.org/Image/343498?vid=download |
104 |
104 |
105 |
105 |
106 Here's an example of code that defines a facet to filter |
106 Here's an example of code that defines a facet to filter |
107 musical works according to their composition date: |
107 musical works according to their composition date: |
108 |
108 |
109 .. sourcecode:: python |
109 .. sourcecode:: python |
110 |
110 |
111 class CompositionDateFacet(DateRangeFacet): |
111 class CompositionDateFacet(DateRangeFacet): |
112 # 1. make sure this facet is displayed only on Track selection |
112 # 1. make sure this facet is displayed only on Track selection |
113 __select__ = DateRangeFacet.__select__ & implements('Track') |
113 __select__ = DateRangeFacet.__select__ & implements('Track') |
114 # 2. give the facet an id required by CubicWeb) |
114 # 2. give the facet an id required by CubicWeb) |
115 id = 'compdate-facet' |
115 __regid__ = 'compdate-facet' |
116 # 3. specify the attribute name that actually stores the date in the DB |
116 # 3. specify the attribute name that actually stores the date in the DB |
117 rtype = 'composition_date' |
117 rtype = 'composition_date' |
118 |
118 |
119 And that's it, on each page displaying tracks, you'll be able to filter them |
119 And that's it, on each page displaying tracks, you'll be able to filter them |
120 according to their composition date with a jquery slider. |
120 according to their composition date with a jquery slider. |