# HG changeset patch # User Sylvain Thénault # Date 1259851748 -3600 # Node ID 9b52725d8c534ba40877457b413077a10173bf88 # Parent dfa5138cc93826bd16885d16a2f5afea472352dd# Parent 8cf7c767b1341ad4841bacdfbe9d37f54b6b31ad merge diff -r 8cf7c767b134 -r 9b52725d8c53 .hgignore --- a/.hgignore Thu Dec 03 15:09:28 2009 +0100 +++ b/.hgignore Thu Dec 03 15:49:08 2009 +0100 @@ -8,3 +8,4 @@ \~$ \#.*?\#$ \.swp$ +^doc/book/en/apidoc$ diff -r 8cf7c767b134 -r 9b52725d8c53 __pkginfo__.py --- a/__pkginfo__.py Thu Dec 03 15:09:28 2009 +0100 +++ b/__pkginfo__.py Thu Dec 03 15:49:08 2009 +0100 @@ -7,7 +7,7 @@ distname = "cubicweb" modname = "cubicweb" -numversion = (3, 5, 9) +numversion = (3, 5, 10) version = '.'.join(str(num) for num in numversion) license = 'LGPL' diff -r 8cf7c767b134 -r 9b52725d8c53 debian/changelog --- a/debian/changelog Thu Dec 03 15:09:28 2009 +0100 +++ b/debian/changelog Thu Dec 03 15:49:08 2009 +0100 @@ -1,3 +1,9 @@ +cubicweb (3.5.10-1) unstable; urgency=low + + * new upstream release + + -- Sylvain Thénault Thu, 03 Dec 2009 15:48:38 +0100 + cubicweb (3.5.9-1) unstable; urgency=low * new upstream release diff -r 8cf7c767b134 -r 9b52725d8c53 doc/book/en/development/devweb/facets.rst --- a/doc/book/en/development/devweb/facets.rst Thu Dec 03 15:09:28 2009 +0100 +++ b/doc/book/en/development/devweb/facets.rst Thu Dec 03 15:49:08 2009 +0100 @@ -1,3 +1,129 @@ The facets system ----------------- -XXX feed me \ No newline at end of file +XXX feed me more (below is the extracted of adim blog) + + +Recently, for internal purposes, we've made a little cubicweb application to +help us +organizing visits to find new office locations. Here's an *excerpt* of the +schema: + +.. sourcecode:: python + + class Office(WorkflowableEntityType): + price = Int(description='euros / m2 / HC / HT') + surface = Int(description='m2') + description = RichString(fulltextindexed=True) + has_address = SubjectRelation('PostalAddress', cardinality='1?', composite='subject') + proposed_by = SubjectRelation('Agency') + comments = ObjectRelation('Comment', cardinality='1*', composite='object') + screenshots = SubjectRelation(('File', 'Image'), cardinality='*1', + composite='subject') + +The two other entity types defined in the schema are `Visit` and `Agency` but we +can also guess from the above that this application uses the two cubes +`comment`_ and +`addressbook`_ (remember, cubicweb is only a game where you assemble cubes !). + +While we know that just defining the schema in enough to have a full, usable, +(testable !) application, we also know that every application needs to be +customized to fulfill the needs it was built for. So in this case, what we +needed most was some custom filters that would let us restrict searches +according +to surfaces, prices or zipcodes. Fortunately for us, Cubicweb provides the +**facets** (image_) mechanism and a few base classes that make the task quite +easy: + +.. sourcecode:: python + + class PostalCodeFacet(RelationFacet): + id = 'postalcode-facet' # every registered class must have an id + __select__ = implements('Office') # this facet should only be selected when + # visualizing offices + rtype = 'has_address' # this facet is a filter on the entity linked to + # the office thrhough the relation + # has_address + target_attr = 'postalcode' # the filter's key is the attribute "postal_code" + # of the target PostalAddress entity + +This is a typical `RelationFacet`: we want to be able to filter offices +according +to the attribute `postalcode` of their associated `PostalAdress`. Each line in +the class is explained by the comment on its right. + +Now, here is the code to define a filter based on the `surface` attribute of the +`Office`: + +.. sourcecode:: python + + class SurfaceFacet(AttributeFacet): + id = 'surface-facet' # every registered class must have an id + __select__ = implements('Office') # this facet should only be selected when + # visualizing offices + rtype = 'surface' # the filter's key is the attribute "surface" + comparator = '>=' # override the default value of operator since + # we want to filter according to a + # minimal + # value, not an exact one + + def rset_vocabulary(self, ___): + """override the default vocabulary method since we want to hard-code + our threshold values. + Not overriding would generate a filter box with all existing surfaces + defined in the database. + """ + return [('> 200', '200'), ('> 250', '250'), + ('> 275', '275'), ('> 300', '300')] + + +And that's it: we have two filter boxes automatically displayed on each page +presenting more than one office. The `price` facet is basically the same as the +`surface` one but with a different vocabulary and with ``rtype = 'price'``. + +(The cube also benefits from the builtin google map views defined by +cubicweb but that's for another blog). + +.. _image: http://www.cubicweb.org/image/197646?vid=download +.. _comment: http://www.cubicweb.org/project/cubicweb-comment +.. _addressbook: http://www.cubicweb.org/project/cubicweb-addressbook + +CubicWeb has this really nice builtin `facet`_ system to +define restrictions `filters`_ really as easily as possible. + +We've just added two new kind of facets in CubicWeb : + +- The **RangeFacet** which displays a slider using `jquery`_ + to choose a lower bound and an upper bound. The **RangeWidget** + works with either numerical values or date values + +- The **HasRelationFacet** which displays a simple checkbox and + lets you refine your selection in order to get only entities + that actually use this relation. + +.. image :: http://www.cubicweb.org/Image/343498?vid=download + + +Here's an example of code that defines a facet to filter +musical works according to their composition date: + +.. sourcecode:: python + + class CompositionDateFacet(DateRangeFacet): + # 1. make sure this facet is displayed only on Track selection + __select__ = DateRangeFacet.__select__ & implements('Track') + # 2. give the facet an id (required by CubicWeb) + id = 'compdate-facet' + # 3. specify the attribute name that actually stores the date in the DB + rtype = 'composition_date' + +And that's it, on each page displaying tracks, you'll be able to filter them +according to their composition date with a jquery slider. + +All this, brought by CubicWeb (in the next 3.3 version) + +.. _facet: http://en.wikipedia.org/wiki/Faceted_browser +.. _filters: http://www.cubicweb.org/blogentry/154152 +.. _jquery: http://www.jqueryui.com/ + +To use **HasRelationFacet** on a reverse relation add ``role = 'object'`` in +it's definitions. diff -r 8cf7c767b134 -r 9b52725d8c53 doc/book/en/development/devweb/internationalization.rst --- a/doc/book/en/development/devweb/internationalization.rst Thu Dec 03 15:09:28 2009 +0100 +++ b/doc/book/en/development/devweb/internationalization.rst Thu Dec 03 15:49:08 2009 +0100 @@ -20,6 +20,9 @@ String internationalization ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +User defined string +``````````````````` + In the Python code and cubicweb-tal templates translatable strings can be marked in one of the following ways : @@ -63,15 +66,40 @@ Translations in cubicweb-tal template can also be done with TAL tags `i18n:content` and `i18n:replace`. -.. note:: - - We dont need to mark the translation strings of entities/relations - used by a particular instance's schema as they are generated - automatically. If you need to add messages on top of those that can be found in the source, you can create a file named `i18n/static-messages.pot`. +Generated string +```````````````` + +We do not need to mark the translation strings of entities/relations used by a +particular instance's schema as they are generated automatically. String for +various actions are also generated. + +For exemple the following schema :: + + Class EntityA(EntityType): + relationa2b = SubjectRelation('EntityB') + + class EntityB(EntityType): + pass + +May generate the following message :: + + creating EntityB (EntityA %(linkto)s relation_a2b EntityB) + +This message will be used in views of ``EntityA`` for creation of a new +``EntityB`` with a preset relation ``relation_a2b`` between the current +``EntityA`` and the new ``EntityB``. The opposite message :: + + creating EntityA (EntityA relation_a2b %(linkto)s EntityA) + +Is used for similar creation of an ``EntityA`` from a view of ``EntityB``. + +In the translated string you can use ``%(linkto)s`` for reference to the source +``entity``. + Handle the translation catalog ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~