# HG changeset patch # User Arthur Lutz # Date 1554390674 -7200 # Node ID e2cdb1be6bd95e4524efc224c78e795f7c9cb144 # Parent 4564ecfc0134df8d1a24e77e23e55a580cd4a3f1 [doc8] D002 Trailing whitespace diff -r 4564ecfc0134 -r e2cdb1be6bd9 cubicweb/misc/cwfs/cwfs-spec.txt --- a/cubicweb/misc/cwfs/cwfs-spec.txt Fri Dec 06 13:20:05 2019 +0100 +++ b/cubicweb/misc/cwfs/cwfs-spec.txt Thu Apr 04 17:11:14 2019 +0200 @@ -19,8 +19,8 @@ ref document - annee - mois + annee + mois jour type {RAP,CLI,OFR,FCT} fichier @@ -42,9 +42,9 @@ | EDFR02 | EDF R&D | document | annee | mois | jour | type | concerne | fichier | - | 2004 | 09 | 06 | PRE | CTIA01 | depodoc/2004/09/CTIA01-040906-PRE-1-01.pdf | - | 2005 | 02 | 01 | CLI | EDFR01 | depodoc/2005/02/EDFR01-050201-CLI-1-01.pdf | - | 2005 | 03 | 22 | OFR | EDFR01 | depodoc/2005/02/EDFR01-050322-OFR-1-01.pdf | + | 2004 | 09 | 06 | PRE | CTIA01 | depodoc/2004/09/CTIA01-040906-PRE-1-01.pdf | + | 2005 | 02 | 01 | CLI | EDFR01 | depodoc/2005/02/EDFR01-050201-CLI-1-01.pdf | + | 2005 | 03 | 22 | OFR | EDFR01 | depodoc/2005/02/EDFR01-050322-OFR-1-01.pdf | Exemples de chemins/recherches @@ -62,7 +62,7 @@ $ ls /document annee/ mois/ jour/ type/ affaire/ concerne/ CTIA01-040906-PRE-1-01.pdf - EDFR01-050201-CLI-1-01.pdf EDFR01-050322-OFR-1-01.pdf + EDFR01-050201-CLI-1-01.pdf EDFR01-050322-OFR-1-01.pdf $ ls /document/annee/ 2004/ 2005/ @@ -82,7 +82,7 @@ Question: est-ce que fichier/ ne va pas nous manquer ? -Cherche documents relatifs à CTIA01; +Cherche documents relatifs à CTIA01; :: /affaire/ref/CTIA01/document/ @@ -99,7 +99,7 @@ $ ls /affaire/ref/CTIA01/ societe/ concerne/ document/ concerne_par/ - + $ ls /affaire/ref/CTIA01/document/ annee/ mois/ jour/ type/ CTIA01-040906-PRE-1-01.pdf @@ -125,7 +125,7 @@ $ ls /societe/nom/CETIAD/affaire/ ref/ societe/ concerne/ document/ - concerne_par/ CTIA01 + concerne_par/ CTIA01 $ ls /societe/nom/CETIAD/affaire/document/ annee/ mois/ jour/ type/ @@ -139,7 +139,7 @@ La logique est que si on est dans un répertoire document, il faut qu'il contienne des documents. -Cherche documents de 2002 qui concernent des affaires +Cherche documents de 2002 qui concernent des affaires qui concernent CETIAD; :: /societe/CETIAD/affaire/document/annee/2002/ diff -r 4564ecfc0134 -r e2cdb1be6bd9 cubicweb/web/wdoc/custom_view_last_update_en.rst --- a/cubicweb/web/wdoc/custom_view_last_update_en.rst Fri Dec 06 13:20:05 2019 +0100 +++ b/cubicweb/web/wdoc/custom_view_last_update_en.rst Thu Apr 04 17:11:14 2019 +0200 @@ -1,4 +1,4 @@ -Latest changes +Latest changes -------------- * table of `all latest changes`_ diff -r 4564ecfc0134 -r e2cdb1be6bd9 cubicweb/web/wdoc/custom_view_last_update_fr.rst --- a/cubicweb/web/wdoc/custom_view_last_update_fr.rst Fri Dec 06 13:20:05 2019 +0100 +++ b/cubicweb/web/wdoc/custom_view_last_update_fr.rst Thu Apr 04 17:11:14 2019 +0200 @@ -1,5 +1,5 @@ .. -*- coding: utf-8 -*- - + Dernières modifications ----------------------- diff -r 4564ecfc0134 -r e2cdb1be6bd9 cubicweb/web/wdoc/custom_view_rss_fr.rst --- a/cubicweb/web/wdoc/custom_view_rss_fr.rst Fri Dec 06 13:20:05 2019 +0100 +++ b/cubicweb/web/wdoc/custom_view_rss_fr.rst Thu Apr 04 17:11:14 2019 +0200 @@ -2,7 +2,7 @@ .. role:: raw-html(raw) :format: html - + Flux RSS -------- diff -r 4564ecfc0134 -r e2cdb1be6bd9 cubicweb/web/wdoc/search_en.rst --- a/cubicweb/web/wdoc/search_en.rst Fri Dec 06 13:20:05 2019 +0100 +++ b/cubicweb/web/wdoc/search_en.rst Thu Apr 04 17:11:14 2019 +0200 @@ -1,11 +1,11 @@ .. winclude:: search_sample_queries -You can as well type complex queries using the RQL_ query language, +You can as well type complex queries using the RQL_ query language, used every where to build dynamic pages of this site. You can use one of the following prefixes to specify which kind of search you -want: +want: * `rql` : RQL query * `text` : full text search diff -r 4564ecfc0134 -r e2cdb1be6bd9 cubicweb/web/wdoc/tut_rql_en.rst --- a/cubicweb/web/wdoc/tut_rql_en.rst Fri Dec 06 13:20:05 2019 +0100 +++ b/cubicweb/web/wdoc/tut_rql_en.rst Thu Apr 04 17:11:14 2019 +0200 @@ -55,7 +55,7 @@ * `LIKE` / `~=` permits use of the special character `%` in a string to tell the string must begin or end with a prefix or suffix (as SQL LIKE operator) :: - + Any X WHERE X name ~= 'Th%' Any X WHERE X name LIKE '%lt' @@ -69,7 +69,7 @@ [DISTINCT] V1(, V2)* [GROUPBY V1(, V2)*] [ORDERBY ] - [WHERE ] + [WHERE ] [LIMIT ] [OFFSET ] :entity type: @@ -95,28 +95,28 @@ :Person: :: - name (String, required) - birthday (Date) + name (String, required) + birthday (Date) :Company: :: - name (String) + name (String) :Note: :: - diem (Date) - type (String) + diem (Date) + type (String) And relations between those entities: :: - Person works_for Company - Person evaluated_by Note - Company evaluated_by Note + Person works_for Company + Person evaluated_by Note + Company evaluated_by Note Meta-data @@ -139,16 +139,16 @@ :CWUser: :: - login (String) not null - password (Password) - firstname (String) - surname (String) + login (String) not null + password (Password) + firstname (String) + surname (String) Basis queries ------------- 0. *Every persons* :: - + Person X or :: @@ -205,22 +205,22 @@ 7. *Every persons order by birthday from the youngest to the oldest* :: - + Person X ORDERBY D DESC WHERE X birthday D Notice you've to define a variable using the birthday relation to use it in the - sort term. + sort term. 8. *Number of persons working for each known company* :: - + Any S, COUNT(X) GROUPBY S WHERE X works_for S Notice you've that since you're writing a grouped query on S, X have to be either grouped as well or used in an aggregat function (as in this example). - + Advanced -------- 0. *Person with no name specified (i.e NULL)* :: diff -r 4564ecfc0134 -r e2cdb1be6bd9 cubicweb/web/wdoc/tut_rql_fr.rst --- a/cubicweb/web/wdoc/tut_rql_fr.rst Fri Dec 06 13:20:05 2019 +0100 +++ b/cubicweb/web/wdoc/tut_rql_fr.rst Thu Apr 04 17:11:14 2019 +0200 @@ -61,7 +61,7 @@ * L'opérateur `LIKE` / `~=` permet d'utiliser le caractère `%` dans une chaine de caractère pour indiquer que la chaîne doit commencer ou terminer par un préfix/suffixe :: - + Any X WHERE X nom ~= 'Th%' Any X WHERE X nom LIKE '%lt' @@ -75,14 +75,14 @@ [DISTINCT] V1(, V2)* [GROUPBY V1(, V2)*] [ORDERBY ] - [WHERE ] + [WHERE ] [LIMIT ] [OFFSET ] :type d'entité: - Type de la ou des variables séléctionnées. + Type de la ou des variables séléctionnées. Le type spécial `Any`, revient à ne pas spécifier de type. :restriction: - liste des relations à parcourir sous la forme + liste des relations à parcourir sous la forme `V1 relation V2|` :orderterms: Définition de l'ordre de sélection : variable ou n° de colonne suivie de la @@ -102,28 +102,28 @@ :Personne: :: - nom (String, obligatoire) - datenaiss (Date) + nom (String, obligatoire) + datenaiss (Date) :Societe: :: - nom (String) + nom (String) :Note: :: - diem (Date) - type (String) + diem (Date) + type (String) Et les relations entre elles : :: - Person travaille_pour Societe - Person evaluee_par Note - Societe evaluee_par Note + Person travaille_pour Societe + Person evaluee_par Note + Societe evaluee_par Note Méta-données @@ -136,27 +136,27 @@ * `created_by (CWUser)`, relation vers l'utilisateur ayant créé l'entité -* `owned_by (CWUser)`, relation vers le où les utilisateurs considérés comme +* `owned_by (CWUser)`, relation vers le où les utilisateurs considérés comme propriétaire de l'entité, par défaut le créateur de l'entité * `is (Eetype)`, relation spéciale permettant de spécifier le - type d'une variable. + type d'une variable. Enfin, le schéma standard d'un utilisateur est le suivant : :CWUser: :: - login (String, obligatoire) - password (Password) - firstname (String) - surname (String) + login (String, obligatoire) + password (Password) + firstname (String) + surname (String) L'essentiel ----------- 0. *Toutes les personnes* :: - + Personne X ou :: @@ -214,15 +214,15 @@ 7. *Toutes les personnes triés par date de naissance dans l'ordre antechronologique* :: - + Personne X ORDERBY D DESC WHERE X datenaiss D On note qu'il faut définir une variable et la séléctionner pour s'en - servir pour le tri. + servir pour le tri. 8. *Nombre de personne travaillant pour chaque société* :: - + Any S, COUNT(X) GROUPBY S WHERE X travaille_pour S On note qu'il faut définir une variable pour s'en servir pour le @@ -230,7 +230,7 @@ (mais les variables groupées ne doivent pas forcément être sélectionnées). - + Exemples avancés ---------------- 0. *Toutes les personnes dont le champ nom n'est pas spécifié (i.e NULL)* :: diff -r 4564ecfc0134 -r e2cdb1be6bd9 doc/api/predicates.rst --- a/doc/api/predicates.rst Fri Dec 06 13:20:05 2019 +0100 +++ b/doc/api/predicates.rst Thu Apr 04 17:11:14 2019 +0200 @@ -10,7 +10,7 @@ .. autoclass:: cubicweb.predicates.appobject_selectable .. autoclass:: cubicweb.predicates.adaptable .. autoclass:: cubicweb.predicates.configuration_values - + .. autoclass:: cubicweb.predicates.none_rset .. autoclass:: cubicweb.predicates.any_rset .. autoclass:: cubicweb.predicates.nonempty_rset @@ -22,7 +22,7 @@ .. autoclass:: cubicweb.predicates.sorted_rset .. autoclass:: cubicweb.predicates.one_etype_rset .. autoclass:: cubicweb.predicates.multi_etypes_rset - + .. autoclass:: cubicweb.predicates.non_final_entity .. autoclass:: cubicweb.predicates.is_instance .. autoclass:: cubicweb.predicates.score_entity @@ -36,9 +36,9 @@ .. autoclass:: cubicweb.predicates.has_mimetype .. autoclass:: cubicweb.predicates.is_in_state .. autofunction:: cubicweb.predicates.on_fire_transition - + .. autoclass:: cubicweb.predicates.match_user_groups - + .. autoclass:: cubicweb.predicates.no_cnx .. autoclass:: cubicweb.predicates.anonymous_user .. autoclass:: cubicweb.predicates.authenticated_user @@ -52,6 +52,6 @@ .. autoclass:: cubicweb.predicates.specified_etype_implements .. autoclass:: cubicweb.predicates.attribute_edited .. autoclass:: cubicweb.predicates.match_transition - + .. autoclass:: cubicweb.predicates.match_exception .. autoclass:: cubicweb.predicates.debug_mode diff -r 4564ecfc0134 -r e2cdb1be6bd9 doc/book/MERGE_ME-tut-create-app.en.txt --- a/doc/book/MERGE_ME-tut-create-app.en.txt Fri Dec 06 13:20:05 2019 +0100 +++ b/doc/book/MERGE_ME-tut-create-app.en.txt Thu Apr 04 17:11:14 2019 +0200 @@ -6,7 +6,7 @@ [TRANSLATE ME TO FRENCH] -This tutorial will guide you step by step to build a blog application +This tutorial will guide you step by step to build a blog application and discover the unique features of `LAX`. It assumes that you followed the :ref:`installation` guidelines and that both the `AppEngine SDK` and the `LAX` framework are setup on your computer. @@ -28,7 +28,7 @@ With `LAX`, the schema/datamodel is the core of the application. This is where you will define the type of content you have to hanlde in your application. -Let us start with something simple and improve on it iteratively. +Let us start with something simple and improve on it iteratively. In schema.py, we define two entities: ``Blog`` and ``BlogEntry``. @@ -46,7 +46,7 @@ entry_of = SubjectRelation('Blog', cardinality='?*') A Blog has a title and a description. The title is a string that is -required by the class EntityType and must be less than 50 characters. +required by the class EntityType and must be less than 50 characters. The description is a string that is not constrained. A BlogEntry has a title, a publish_date and a text. The title is a @@ -145,10 +145,10 @@ to edit the blog entry you just created, except that the form now has another section with a combobox titled ``add relation``. Chose ``entry_of`` in this menu and a second combobox appears where you pick -``MyLife``. +``MyLife``. You could also have, at the time you started to fill the form for a -new entity BlogEntry, hit ``Apply`` instead of ``Validate`` and the +new entity BlogEntry, hit ``Apply`` instead of ``Validate`` and the combobox titled ``add relation`` would have showed up. .. image:: images/lax-book.06-add-relation-entryof.en.png @@ -184,12 +184,12 @@ This menu provides you a way to adjust some navigation options depending on your needs, such as the number of entities to display by page of results. Follows the detailled list of available options: - + * navigation.combobox-limit: maximum number of entities to display in related combo box (sample format: 23) -* navigation.page-size: maximum number of objects displayed by page of results +* navigation.page-size: maximum number of objects displayed by page of results (sample format: 23) -* navigation.related-limit: maximum number of related entities to display in +* navigation.related-limit: maximum number of related entities to display in the primary view (sample format: 23) * navigation.short-line-size: maximum number of characters in short description (sample format: 23) @@ -217,17 +217,17 @@ Actions ~~~~~~~ This menu provides a way to configure the context in which you expect the actions -to be displayed to the user and if you want the action to be visible or not. -You must have notice that when you view a list of entities, an action box is -available on the left column which display some actions as well as a drop-down -menu for more actions. +to be displayed to the user and if you want the action to be visible or not. +You must have notice that when you view a list of entities, an action box is +available on the left column which display some actions as well as a drop-down +menu for more actions. The context available are: * mainactions : actions listed in the left box * moreactions : actions listed in the `more` menu of the left box * addrelated : add actions listed in the left box -* useractions : actions listed in the first section of drop-down menu +* useractions : actions listed in the first section of drop-down menu accessible from the right corner user login link * siteactions : actions listed in the second section of drop-down menu accessible from the right corner user login link @@ -235,15 +235,15 @@ Boxes ~~~~~ -The application has already a pre-defined set of boxes you can use right away. +The application has already a pre-defined set of boxes you can use right away. This configuration section allows you to place those boxes where you want in the -application interface to customize it. +application interface to customize it. The available boxes are: * actions box : box listing the applicable actions on the displayed data -* boxes_blog_archives_box : box listing the blog archives +* boxes_blog_archives_box : box listing the blog archives * possible views box : box listing the possible views for the displayed data @@ -251,7 +251,7 @@ * search box : search box -* startup views box : box listing the configuration options available for +* startup views box : box listing the configuration options available for the application site, such as `Preferences` and `Site Configuration` Components @@ -268,26 +268,26 @@ Before starting, make sure you refresh your mind by reading [link to definition_workflow chapter]. -We want to create a workflow to control the quality of the BlogEntry +We want to create a workflow to control the quality of the BlogEntry submitted on your application. When a BlogEntry is created by a user its state should be `submitted`. To be visible to all, it needs to be in the state `published`. To move from `submitted` to `published` we need a transition that we can name `approve_blogentry`. -We do not want every user to be allowed to change the state of a -BlogEntry. We need to define a group of user, `moderators`, and +We do not want every user to be allowed to change the state of a +BlogEntry. We need to define a group of user, `moderators`, and this group will have appropriate permissions to approve BlogEntry to be published and visible to all. There are two ways to create a workflow, form the user interface, and also by defining it in ``migration/postcreate.py``. This script -is executed each time a new ``./bin/laxctl db-init`` is done. +is executed each time a new ``./bin/laxctl db-init`` is done. If you create the states and transitions through the user interface this means that next time you will need to initialize the database -you will have to re-create all the entities. +you will have to re-create all the entities. We strongly recommand you create the workflow in ``migration\postcreate.py`` and we will now show you how. -The user interface would only be a reference for you to view the states +The user interface would only be a reference for you to view the states and transitions but is not the appropriate interface to define your application workflow. @@ -320,7 +320,7 @@ To define our workflow for BlogDemo, please add the following lines to ``migration/postcreate.py``:: - + _ = unicode moderators = add_entity('CWGroup', name=u"moderators") @@ -335,15 +335,15 @@ ``add_entity`` is used here to define the new group of users that we need to define the transitions, `moderators`. If this group required by the transition is not defined before the -transition is created, it will not create the relation `transition +transition is created, it will not create the relation `transition require the group moderator`. ``add_state`` expects as the first argument the name of the state you are -willing to create, then the entity type on which the state can be applied, +willing to create, then the entity type on which the state can be applied, and an optionnal argument to set if the state is the initial state of the entity type or not. -``add_transition`` expects as the first argument the name of the +``add_transition`` expects as the first argument the name of the transition, then the entity type on which we can apply the transition, then the list of possible initial states from which the transition can be applied, the target state of the transition, and the permissions @@ -374,7 +374,7 @@ ~~~~~~~~~~~~~~~ Creating a simple schema was enough to set up a new application that -can store blogs and blog entries. +can store blogs and blog entries. What is next ? ~~~~~~~~~~~~~~ diff -r 4564ecfc0134 -r e2cdb1be6bd9 doc/book/MERGE_ME-tut-create-gae-app.en.txt --- a/doc/book/MERGE_ME-tut-create-gae-app.en.txt Fri Dec 06 13:20:05 2019 +0100 +++ b/doc/book/MERGE_ME-tut-create-gae-app.en.txt Thu Apr 04 17:11:14 2019 +0200 @@ -5,7 +5,7 @@ Tutoriel : créer votre première application web pour Google AppEngine ===================================================================== -Ce tutoriel va vous guider pas à pas a construire une apllication web +Ce tutoriel va vous guider pas à pas a construire une apllication web de gestion de Blog afin de vous faire découvrir les fonctionnalités de *CubicWeb*. @@ -17,10 +17,10 @@ Nous choisissons dans ce tutoriel de développer un blog comme un exemple d'application web et nous allons expliciter toutes les étapes nécessaires -à sa réalisation. +à sa réalisation. :: - + cubicweb-ctl newgapp blogdemo `newgapp` est la commande permettant de créer une instance *CubicWeb* pour @@ -55,15 +55,15 @@ entry_of = SubjectRelation('Blog', cardinality='?*') -Un ``Blog`` a un titre et une description. Le titre est une chaîne +Un ``Blog`` a un titre et une description. Le titre est une chaîne de caractères requise par la classe parente EntityType and ne doit -pas excéder 50 caractères. La description est une chaîne de +pas excéder 50 caractères. La description est une chaîne de caractères sans contraintes. Une ``BlogEntry`` a un titre, une date de publication et du texte -étant son contenu. Le titre est une chaîne de caractères qui ne +étant son contenu. Le titre est une chaîne de caractères qui ne doit pas excéder 100 caractères. La date de publication est de type Date et a -pour valeur par défaut TODAY, ce qui signifie que lorsqu'une +pour valeur par défaut TODAY, ce qui signifie que lorsqu'une ``BlogEntry`` sera créée, sa date de publication sera la date courante a moins de modifier ce champ. Le texte est une chaîne de caractères qui sera indexée en plein texte et sans contraintes. @@ -72,18 +72,18 @@ relie à un ``Blog``. La cardinalité ``?*`` signifie que BlogEntry peut faire partie de zero a un Blog (``?`` signifie `zero ou un`) et qu'un Blog peut avoir une infinité de BlogEntry (``*`` signifie -`n'importe quel nombre incluant zero`). +`n'importe quel nombre incluant zero`). Par soucis de complétude, nous rappellerons que ``+`` signifie `un ou plus`. Lancez l'application -------------------- -Définir ce simple schéma est suffisant pour commencer. Assurez-vous +Définir ce simple schéma est suffisant pour commencer. Assurez-vous que vous avez suivi les étapes décrites dans la section installation (en particulier visitez http://localhost:8080/_load en tant qu'administrateur afin d'initialiser le datastore), puis lancez votre application avec la commande :: - + python dev_appserver.py BlogDemo puis dirigez vous vers http://localhost:8080/ (ou si c'est plus facile @@ -93,7 +93,7 @@ .. image:: images/lax-book.00-login.en.png :alt: login screen -Après vous être authentifié, vous arrivez sur la page d'accueil de votre +Après vous être authentifié, vous arrivez sur la page d'accueil de votre application. Cette page liste les types d'entités accessibles dans votre application, en l'occurrence : Blog et Articles. Si vous lisez ``blog_plural`` et ``blogentry_plural`` cela signifie que l'internationalisation (i18n) @@ -130,7 +130,7 @@ :alt: from to create blog En cliquant sur le logo situé dans le coin gauche de la fenêtre, -vous allez être redirigé vers la page d'accueil. Ensuite, si vous allez +vous allez être redirigé vers la page d'accueil. Ensuite, si vous allez sur le lien Blog, vous devriez voir la liste des entités Blog, en particulier celui que vous venez juste de créer ``Tech-Blog``. @@ -160,7 +160,7 @@ un peut de texte avant de ``Valider``. Vous venez d'ajouter un article sans avoir précisé à quel Blog il appartenait. Dans la colonne de gauche se trouve une boite intitulé ``actions``, cliquez sur le menu ``modifier``. -Vous êtes de retour sur le formulaire d'édition de l'article que vous +Vous êtes de retour sur le formulaire d'édition de l'article que vous venez de créer, à ceci près que ce formulaire a maintenant une nouvelle section intitulée ``ajouter relation``. Choisissez ``entry_of`` dans ce menu, cela va faire apparaitre une deuxième menu déroulant dans lequel vous @@ -173,7 +173,7 @@ :alt: editing a blog entry to add a relation to a blog Validez vos modifications en cliquant sur ``Valider``. L'entité article -qui est listée contient maintenant un lien vers le Blog auquel il +qui est listée contient maintenant un lien vers le Blog auquel il appartient, ``MyLife``. .. image:: images/lax-book.07-detail-one-blogentry.en.png @@ -206,7 +206,7 @@ ~~~~~~~~~~~~~~~ Creating a simple schema was enough to set up a new application that -can store blogs and blog entries. +can store blogs and blog entries. What is next ? ~~~~~~~~~~~~~~ diff -r 4564ecfc0134 -r e2cdb1be6bd9 doc/book/_maybe_to_integrate/rss-xml.rst --- a/doc/book/_maybe_to_integrate/rss-xml.rst Fri Dec 06 13:20:05 2019 +0100 +++ b/doc/book/_maybe_to_integrate/rss-xml.rst Thu Apr 04 17:11:14 2019 +0200 @@ -16,7 +16,7 @@ Enter the same query in the search box and you will see the same list, plus a box titled "possible views" in the left column. Click on -"entityview", then "RSS". +"entityview", then "RSS". You just applied the "RSS" view to the RQL selection you requested. @@ -24,7 +24,7 @@ Try again with:: - Any X ORDERBY D WHERE X is BlogEntry, X creation_date D, + Any X ORDERBY D WHERE X is BlogEntry, X creation_date D, X entry_of B, B title "MyLife" Another RSS channel, but a bit more focused. @@ -32,7 +32,7 @@ A last one for the road:: Any C ORDERBY D WHERE C is Comment, C creation_date D LIMIT 15 - + displayed with the RSS view, that's a channel for the last fifteen comments posted. diff -r 4564ecfc0134 -r e2cdb1be6bd9 doc/book/_maybe_to_integrate/template.rst --- a/doc/book/_maybe_to_integrate/template.rst Fri Dec 06 13:20:05 2019 +0100 +++ b/doc/book/_maybe_to_integrate/template.rst Thu Apr 04 17:11:14 2019 +0200 @@ -17,4 +17,4 @@ 2. identifying the view to use to render data if it is not specified 3. composing the HTML page to return -You will find out more about templates in :ref:`templates`. +You will find out more about templates in :ref:`templates`. diff -r 4564ecfc0134 -r e2cdb1be6bd9 doc/book/annexes/faq.rst --- a/doc/book/annexes/faq.rst Fri Dec 06 13:20:05 2019 +0100 +++ b/doc/book/annexes/faq.rst Thu Apr 04 17:11:14 2019 +0200 @@ -103,10 +103,10 @@ --------------------------------- The logo is managed by css. You must provide a custom css that will contain -the code below: +the code below: :: - + #logo { background-image: url("logo.jpg"); } @@ -171,7 +171,7 @@ ----------------------------------------------------------------- You just need to put the appropriate context manager around view/component -selection. One standard place for components is in cubicweb/vregistry.py: +selection. One standard place for components is in cubicweb/vregistry.py: .. sourcecode:: python diff -r 4564ecfc0134 -r e2cdb1be6bd9 doc/book/devrepo/migration.rst --- a/doc/book/devrepo/migration.rst Fri Dec 06 13:20:05 2019 +0100 +++ b/doc/book/devrepo/migration.rst Thu Apr 04 17:11:14 2019 +0200 @@ -108,7 +108,7 @@ If some of the added cubes are already used by an instance, they'll simply be silently skipped. -To remove a cube use `drop_cube(cube, removedeps=False)`. +To remove a cube use `drop_cube(cube, removedeps=False)`. Schema migration ---------------- @@ -212,7 +212,7 @@ The `config` variable is an object which can be used to access the configuration values, for reading and updating, with a dictionary-like -syntax. +syntax. Example 1: migration script changing the variable 'sender-addr' in all-in-one.conf. The script also checks that in that the instance is @@ -225,7 +225,7 @@ fixed_addr = 'cubicweb@logilab.fr' configured_addr = config.get('sender-addr') # check that the address has not been hand fixed by a sysadmin - if configured_addr == wrong_addr: + if configured_addr == wrong_addr: config['sender-addr'] = fixed-addr config.save() diff -r 4564ecfc0134 -r e2cdb1be6bd9 doc/book/devrepo/testing.rst --- a/doc/book/devrepo/testing.rst Fri Dec 06 13:20:05 2019 +0100 +++ b/doc/book/devrepo/testing.rst Thu Apr 04 17:11:14 2019 +0200 @@ -347,7 +347,7 @@ It is also possible to add a ``schema.py`` file in ``mycube/test/data``, which will be used by the testing framework, therefore making new entity types and relations available to the -tests. +tests. Literate programming -------------------- diff -r 4564ecfc0134 -r e2cdb1be6bd9 doc/book/pyramid/ctl.rst --- a/doc/book/pyramid/ctl.rst Fri Dec 06 13:20:05 2019 +0100 +++ b/doc/book/pyramid/ctl.rst Thu Apr 04 17:11:14 2019 +0200 @@ -24,7 +24,7 @@ Also force the following pyramid options: .. code-block:: ini - + pyramid.debug_authorization = yes pyramid.debug_notfound = yes pyramid.debug_routematch = yes diff -r 4564ecfc0134 -r e2cdb1be6bd9 doc/book/pyramid/settings.rst --- a/doc/book/pyramid/settings.rst Fri Dec 06 13:20:05 2019 +0100 +++ b/doc/book/pyramid/settings.rst Thu Apr 04 17:11:14 2019 +0200 @@ -98,7 +98,7 @@ (True) Add a :class:`cubicweb.pyramid.auth.UpdateLoginTimeAuthenticationPolicy` policy, that update the CWUser.login_time attribute when a user login. - + .. confval:: cubicweb.auth.authtkt (bool) (True) Enables the 2 cookie-base auth policies, which activate/deactivate diff -r 4564ecfc0134 -r e2cdb1be6bd9 doc/changes/3.20.rst --- a/doc/changes/3.20.rst Fri Dec 06 13:20:05 2019 +0100 +++ b/doc/changes/3.20.rst Thu Apr 04 17:11:14 2019 +0200 @@ -63,38 +63,38 @@ * most of 3.10 and 3.11 backward compat is gone; this includes: - CtxComponent.box_action() and CtxComponent.build_link() - + - cubicweb.devtools.htmlparser.XMLDemotingValidator - + - various methods and properties on Entities, replaced by cw_edited and cw_attr_cache - + - 'commit_event' method on hooks, replaced by 'postcommit_event' - + - server.hook.set_operation(), replaced by Operation.get_instance(...).add_data() - + - View.div_id(), View.div_class() and View.create_url() - + - `*VComponent` classes - + - in forms, Field.value() and Field.help() must take the form and the field itself as arguments - + - form.render() must get `w` as a named argument, and renderer.render() must take `w` as first argument - + - in breadcrumbs, the optional `recurs` argument must be a set, not False - + - cubicweb.web.views.idownloadable.{download_box,IDownloadableLineView} - + - primary views no longer have `render_entity_summary` and `summary` methods - + - WFHistoryVComponent's `cell_call` method is replaced by `render_body` - + - cubicweb.dataimport.ObjectStore.add(), replaced by create_entity - + - ManageView.{folders,display_folders} diff -r 4564ecfc0134 -r e2cdb1be6bd9 doc/dev/documenting.txt --- a/doc/dev/documenting.txt Fri Dec 06 13:20:05 2019 +0100 +++ b/doc/dev/documenting.txt Thu Apr 04 17:11:14 2019 +0200 @@ -49,7 +49,7 @@ Boxes ===== -- warning box: +- warning box: .. warning:: Warning content diff -r 4564ecfc0134 -r e2cdb1be6bd9 doc/index.rst --- a/doc/index.rst Fri Dec 06 13:20:05 2019 +0100 +++ b/doc/index.rst Thu Apr 04 17:11:14 2019 +0200 @@ -67,7 +67,7 @@ :maxdepth: 2 tutorials/index - + .. toctree:: :maxdepth: 3 diff -r 4564ecfc0134 -r e2cdb1be6bd9 doc/plan_formation_python_cubicweb.txt --- a/doc/plan_formation_python_cubicweb.txt Fri Dec 06 13:20:05 2019 +0100 +++ b/doc/plan_formation_python_cubicweb.txt Thu Apr 04 17:11:14 2019 +0200 @@ -72,7 +72,7 @@ La classe `appobject` La base de registres Chargement dynamique des classes - + Manipulation des données stockées ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :durée: 0.4j diff -r 4564ecfc0134 -r e2cdb1be6bd9 doc/tutorials/dataimport/index.rst --- a/doc/tutorials/dataimport/index.rst Fri Dec 06 13:20:05 2019 +0100 +++ b/doc/tutorials/dataimport/index.rst Thu Apr 04 17:11:14 2019 +0200 @@ -4,18 +4,18 @@ Introduction ~~~~~~~~~~~~ -This tutorial explains how to import data from an external source (e.g. a collection of files) +This tutorial explains how to import data from an external source (e.g. a collection of files) into a CubicWeb cube instance. -First, once we know the format of the data we wish to import, we devise a +First, once we know the format of the data we wish to import, we devise a *data model*, that is, a CubicWeb (Yams) schema which reflects the way the data is structured. This schema is implemented in the ``schema.py`` file. -In this tutorial, we will describe such a schema for a particular data set, +In this tutorial, we will describe such a schema for a particular data set, the Diseasome data (see below). -Once the schema is defined, we create a cube and an instance. -The cube is a specification of an application, whereas an instance -is the application per se. +Once the schema is defined, we create a cube and an instance. +The cube is a specification of an application, whereas an instance +is the application per se. Once the schema is defined and the instance is created, the import can be performed, via the following steps: @@ -41,18 +41,18 @@ The first thing to do when using CubicWeb for creating an application from scratch is to devise a *data model*, that is, a relational representation of the problem to be -modeled or of the structure of the data to be imported. +modeled or of the structure of the data to be imported. In such a schema, we define an entity type (``EntityType`` objects) for each type of entity to import. Each such type has several attributes. If the attributes are of known CubicWeb (Yams) types, viz. numbers, strings or characters, then they are defined as attributes, as e.g. ``attribute = Int()`` -for an attribute named ``attribute`` which is an integer. +for an attribute named ``attribute`` which is an integer. Each such type also has a set of relations, which are defined like the attributes, except that they represent, in fact, relations between the entities of the type under discussion and the objects of a type which -is specified in the relation definition. +is specified in the relation definition. For example, for the Diseasome data, we have two types of entities, genes and diseases. Thus, we create two classes which inherit from ``EntityType``:: @@ -73,27 +73,27 @@ class Gene(EntityType): ... -In this schema, there are attributes whose values are numbers or strings. Thus, they are -defined by using the CubicWeb / Yams primitive types, e.g., ``label = String(maxsize=12)``. -These types can have several constraints or attributes, such as ``maxsize``. +In this schema, there are attributes whose values are numbers or strings. Thus, they are +defined by using the CubicWeb / Yams primitive types, e.g., ``label = String(maxsize=12)``. +These types can have several constraints or attributes, such as ``maxsize``. There are also relations, either between the entity types themselves, or between them -and a CubicWeb type, ``ExternalUri``. The latter defines a class of URI objects in -CubicWeb. For instance, the ``chromosomal_location`` attribute is a relation between +and a CubicWeb type, ``ExternalUri``. The latter defines a class of URI objects in +CubicWeb. For instance, the ``chromosomal_location`` attribute is a relation between a ``Disease`` entity and an ``ExternalUri`` entity. The relation is marked by the CubicWeb / Yams ``SubjectRelation`` method. The latter can have several optional keyword arguments, such as -``cardinality`` which specifies the number of subjects and objects related by the relation type +``cardinality`` which specifies the number of subjects and objects related by the relation type specified. For example, the ``'?*'`` cardinality in the ``chromosomal_relation`` relation type says that zero or more ``Disease`` entities are related to zero or one ``ExternalUri`` entities. In other words, a ``Disease`` entity is related to at most one ``ExternalUri`` entity via the ``chromosomal_location`` relation type, and that we can have zero or more ``Disease`` entities in the -data base. +data base. For a relation between the entity types themselves, the ``associated_genes`` between a ``Disease`` entity and a ``Gene`` entity is defined, so that any number of ``Gene`` entities can be associated to a ``Disease``, and there can be any number of ``Disease`` s if a ``Gene`` exists. Of course, before being able to use the CubicWeb / Yams built-in objects, we need to import them:: - + from yams.buildobjs import EntityType, SubjectRelation, String, Int from cubicweb.schemas.base import ExternalUri @@ -101,48 +101,48 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The data we wish to import is structured in the RDF format, -as a text file containing a set of lines. -On each line, there are three fields. -The first two fields are URIs ("Universal Resource Identifiers"). +as a text file containing a set of lines. +On each line, there are three fields. +The first two fields are URIs ("Universal Resource Identifiers"). The third field is either an URI or a string. Each field bares a particular meaning: -- the leftmost field is an URI that holds the entity to be imported. - Note that the entities defined in the data model (i.e., in ``schema.py``) should +- the leftmost field is an URI that holds the entity to be imported. + Note that the entities defined in the data model (i.e., in ``schema.py``) should correspond to the entities whose URIs are specified in the import file. -- the middle field is an URI that holds a relation whose subject is the entity +- the middle field is an URI that holds a relation whose subject is the entity defined by the leftmost field. Note that this should also correspond to the definitions in the data model. -- the rightmost field is either an URI or a string. When this field is an URI, +- the rightmost field is either an URI or a string. When this field is an URI, it gives the object of the relation defined by the middle field. When the rightmost field is a string, the middle field is interpreted as an attribute of the subject (introduced by the leftmost field) and the rightmost field is interpreted as the value of the attribute. -Note however that some attributes (i.e. relations whose objects are strings) +Note however that some attributes (i.e. relations whose objects are strings) have their objects defined as strings followed by ``^^`` and by another URI; we ignore this part. Let us show some examples: - of line holding an attribute definition: - `` + `` "CYP17A1" .`` The line contains the definition of the ``label`` attribute of an entity of type ``gene``. The value of ``label`` is '``CYP17A1``'. - of line holding a relation definition: - `` - + `` + .`` The line contains the definition of the ``associatedGene`` relation between - a ``disease`` subject entity identified by ``1`` and a ``gene`` object + a ``disease`` subject entity identified by ``1`` and a ``gene`` object entity defined by ``HADH2``. Thus, for parsing the data, we can (:note: see the ``diseasome_parser`` module): -1. define a couple of regular expressions for parsing the two kinds of lines, +1. define a couple of regular expressions for parsing the two kinds of lines, ``RE_ATTS`` for parsing the attribute definitions, and ``RE_RELS`` for parsing the relation definitions. @@ -166,33 +166,33 @@ In the case of diseasome data, we can just define two dictionaries for mapping the names of the relations as extracted by the parser, to the names of the relations -as defined in the ``schema.py`` data model. In the ``diseasome_parser`` module -they are called ``MAPPING_ATTS`` and ``MAPPING_RELS``. +as defined in the ``schema.py`` data model. In the ``diseasome_parser`` module +they are called ``MAPPING_ATTS`` and ``MAPPING_RELS``. Given that the relation and attribute names are given in CamelCase in the original data, mappings are necessary if we follow the PEP08 when naming the attributes in the data model. -For example, the RDF relation ``chromosomalLocation`` is mapped into the schema relation +For example, the RDF relation ``chromosomalLocation`` is mapped into the schema relation ``chromosomal_location``. Once these mappings have been defined, we just iterate over the (subject, relation, object) tuples provided by the parser and we extract the entities, with their attributes and relations. For each entity, we thus have a dictionary with two keys, ``attributes`` and ``relations``. -The value associated to the ``attributes`` key is a dictionary containing (attribute: value) -pairs, where "value" is a string, plus the ``cwuri`` key / attribute holding the URI of +The value associated to the ``attributes`` key is a dictionary containing (attribute: value) +pairs, where "value" is a string, plus the ``cwuri`` key / attribute holding the URI of the entity itself. The value associated to the ``relations`` key is a dictionary containing (relation: value) pairs, where "value" is an URI. -This is implemented in the ``entities_from_rdf`` interface function of the module +This is implemented in the ``entities_from_rdf`` interface function of the module ``diseasome_parser``. This function provides an iterator on the dictionaries containing the ``attributes`` and ``relations`` keys for all entities. -However, this is a simple case. In real life, things can get much more complicated, and the -mapping can be far from trivial, especially when several data sources (which can follow +However, this is a simple case. In real life, things can get much more complicated, and the +mapping can be far from trivial, especially when several data sources (which can follow different formatting and even structuring conventions) must be mapped into the same data model. Importing the data ~~~~~~~~~~~~~~~~~~ -The data import code should be placed in a Python module. Let us call it +The data import code should be placed in a Python module. Let us call it ``diseasome_import.py``. Then, this module should be called via ``cubicweb-ctl``, as follows:: @@ -216,31 +216,31 @@ between them. 2. ``RQLObjectStore``: store which uses the RQL language for performing - database insertions and updates. It relies on all the CubicWeb hooks + database insertions and updates. It relies on all the CubicWeb hooks machinery, especially for dealing with security issues (database access permissions). 2. ``NoHookRQLObjectStore``: store which uses the RQL language for - performing database insertions and updates, but for which - all hooks are deactivated. This implies that - certain checks with respect to the CubicWeb / Yams schema - (data model) are not performed. However, all SQL queries + performing database insertions and updates, but for which + all hooks are deactivated. This implies that + certain checks with respect to the CubicWeb / Yams schema + (data model) are not performed. However, all SQL queries obtained from the RQL ones are executed in a sequential manner, one query per inserted entity. -4. ``SQLGenObjectStore``: store which uses the SQL language directly. - It inserts entities either sequentially, by executing an SQL query - for each entity, or directly by using one PostGRES ``COPY FROM`` - query for a set of similarly structured entities. +4. ``SQLGenObjectStore``: store which uses the SQL language directly. + It inserts entities either sequentially, by executing an SQL query + for each entity, or directly by using one PostGRES ``COPY FROM`` + query for a set of similarly structured entities. For really massive imports (millions or billions of entities), there -is a cube ``dataio`` which contains another store, called +is a cube ``dataio`` which contains another store, called ``MassiveObjectStore``. This store is similar to ``SQLGenObjectStore``, except that anything related to CubicWeb is bypassed. That is, even the CubicWeb EID entity identifiers are not handled. This store is the fastest, but has a slightly different API from the other four stores mentioned above. Moreover, it has an important limitation, in that it doesn't insert inlined [#]_ -relations in the database. +relations in the database. .. [#] An inlined relation is a relation defined in the schema with the keyword argument ``inlined=True``. Such a relation @@ -260,9 +260,9 @@ All three stores ``RQLObjectStore``, ``NoHookRQLObjectStore`` and ``SQLGenObjectStore`` provide exactly the same API for importing data, that is -entities and relations, in an SQL database. +entities and relations, in an SQL database. -Before using a store, one must import the ``dataimport`` module and then initialize +Before using a store, one must import the ``dataimport`` module and then initialize the store, with the current ``session`` as a parameter:: import cubicweb.dataimport as cwdi @@ -274,7 +274,7 @@ #. ``create_entity(Etype, **attributes)``, which allows us to add an entity of the Yams type ``Etype`` to the database. This entity's attributes - are specified in the ``attributes`` dictionary. The method returns the entity + are specified in the ``attributes`` dictionary. The method returns the entity created in the database. For example, we add two entities, a person, of ``Person`` type, and a location, of ``Location`` type:: @@ -284,21 +284,21 @@ #. ``relate(subject_eid, r_type, object_eid)``, which allows us to add a relation of the Yams type ``r_type`` to the database. The relation's subject is an entity - whose EID is ``subject_eid``; its object is another entity, whose EID is + whose EID is ``subject_eid``; its object is another entity, whose EID is ``object_eid``. For example [#]_:: store.relate(person.eid(), 'lives_in', location.eid(), **kwargs) ``kwargs`` is only used by the ``SQLGenObjectStore``'s ``relate`` method and is here to allow us to specify the type of the subject of the relation, when the relation is - defined as inlined in the schema. + defined as inlined in the schema. .. [#] The ``eid`` method of an entity defined via ``create_entity`` returns the entity identifier as assigned by CubicWeb when creating the entity. This only works for entities defined via the stores in the CubicWeb's ``dataimport`` module. - The keyword argument that is understood by ``SQLGenObjectStore`` is called + The keyword argument that is understood by ``SQLGenObjectStore`` is called ``subjtype`` and holds the type of the subject entity. For the example considered here, this comes to having [#]_:: @@ -306,26 +306,26 @@ If ``subjtype`` is not specified, then the store tries to infer the type of the subject. However, this doesn't always work, e.g. when there are several possible subject types - for a given relation type. + for a given relation type. .. [#] The ``cw_etype`` attribute of an entity defined via ``create_entity`` holds the type of the entity just created. This only works for entities defined via the stores in the CubicWeb's ``dataimport`` module. In the example considered here, ``person.cw_etype`` holds ``'Person'``. - + All the other stores but ``SQLGenObjectStore`` ignore the ``kwargs`` parameters. #. ``flush()``, which allows us to perform the actual commit into the database, along - with some cleanup operations. Ideally, this method should be called as often as + with some cleanup operations. Ideally, this method should be called as often as possible, that is after each insertion in the database, so that database sessions - are kept as atomic as possible. In practice, we usually call this method twice: + are kept as atomic as possible. In practice, we usually call this method twice: first, after all the entities have been created, second, after all relations have - been created. + been created. Note however that before each commit the database insertions have to be consistent with the schema. Thus, if, for instance, an entity has an attribute defined through a relation (viz. - a ``SubjectRelation``) with a ``"1"`` or ``"+"`` object + a ``SubjectRelation``) with a ``"1"`` or ``"+"`` object cardinality, we have to create the entity under discussion, the object entity of the relation under discussion, and the relation itself, before committing the additions to the database. @@ -343,14 +343,14 @@ to interact directly with the database server, via SQL queries. Moreover, these queries rely on PostGreSQL's ``COPY FROM`` instruction -to create several entities in a single query. This brings tremendous +to create several entities in a single query. This brings tremendous performance improvements with respect to the RQL-based data insertion procedures. However, the API of this store is slightly different from the API of the stores in CubicWeb's ``dataimport`` module. -Before using the store, one has to import the ``dataio`` cube's +Before using the store, one has to import the ``dataio`` cube's ``dataimport`` module, then initialize the store by giving it the ``session`` parameter:: @@ -375,23 +375,23 @@ they only specify their types, not their unique identifiers. #. ``create_entity(Etype, **attributes)``, which allows us to add new entities, - whose attributes are given in the ``attributes`` dictionary. - Please note however that, by default, this method does *not* return + whose attributes are given in the ``attributes`` dictionary. + Please note however that, by default, this method does *not* return the created entity. The method is called, for example, as in:: - store.create_entity('Person', name='Toto', age='18', height='190', + store.create_entity('Person', name='Toto', age='18', height='190', uri='http://link/to/person/toto_18_190') store.create_entity('Location', town='Paris', arrondissement='13', uri='http://link/to/location/paris_13') - + In order to be able to link these entities via the relations when needed, we must provide ourselves a means for uniquely identifying the entities. In general, this is done via URIs, stored in attributes like ``uri`` or ``cwuri``. The name of the attribute is irrelevant as long as its value is unique for each entity. -#. ``relate_by_iid(subject_iid, r_type, object_iid)`` allows us to actually - relate the entities uniquely identified by ``subject_iid`` and +#. ``relate_by_iid(subject_iid, r_type, object_iid)`` allows us to actually + relate the entities uniquely identified by ``subject_iid`` and ``object_iid`` via a relation of type ``r_type``. For example:: store.relate_by_iid('http://link/to/person/toto_18_190', @@ -411,11 +411,11 @@ their values are unique. For example, for inserting all relations of type ``lives_in`` between ``People`` and ``Location`` entities, we write:: - + store.convert_relations('Person', 'lives_in', 'Location', 'uri', 'uri') -#. ``flush()`` performs the actual commit in the database. It only needs - to be called after ``create_entity`` and ``relate_by_iid`` calls. +#. ``flush()`` performs the actual commit in the database. It only needs + to be called after ``create_entity`` and ``relate_by_iid`` calls. Please note that ``relate_by_iid`` does *not* perform insertions into the database, hence calling ``flush()`` for it would have no effect. @@ -437,106 +437,106 @@ We define an import function, ``diseasome_import``, which does basically four things: #. creates and initializes the store to be used, via a line such as:: - + store = cwdi.SQLGenObjectStore(session) - - where ``cwdi`` is the imported ``cubicweb.dataimport`` or + + where ``cwdi`` is the imported ``cubicweb.dataimport`` or ``cubicweb_dataio.dataimport``. -#. calls the diseasome parser, that is, the ``entities_from_rdf`` function in the +#. calls the diseasome parser, that is, the ``entities_from_rdf`` function in the ``diseasome_parser`` module and iterates on its result, in a line such as:: - + for entity, relations in parser.entities_from_rdf(filename, ('gene', 'disease')): - - where ``parser`` is the imported ``diseasome_parser`` module, and ``filename`` is the + + where ``parser`` is the imported ``diseasome_parser`` module, and ``filename`` is the name of the file containing the data (with its path), e.g. ``../data/diseasome_dump.nt``. -#. creates the entities to be inserted in the database; for Diseasome, there are two +#. creates the entities to be inserted in the database; for Diseasome, there are two kinds of entities: - + #. entities defined in the data model, viz. ``Gene`` and ``Disease`` in our case. #. entities which are built in CubicWeb / Yams, viz. ``ExternalUri`` which define URIs. - + As we are working with RDF data, each entity is defined through a series of URIs. Hence, each "relational attribute" [#]_ of an entity is defined via an URI, that is, in CubicWeb terms, via an ``ExternalUri`` entity. The entities are created, in the loop presented above, as such:: - + ent = store.create_entity(etype, **entity) - + where ``etype`` is the appropriate entity type, either ``Gene`` or ``Disease``. .. [#] By "relational attribute" we denote an attribute (of an entity) which is defined through a relation, e.g. the ``chromosomal_location`` attribute of ``Disease`` entities, which is defined through a relation between a ``Disease`` and an ``ExternalUri``. - + The ``ExternalUri`` entities are as many as URIs in the data file. For them, we define a unique attribute, ``uri``, which holds the URI under discussion:: - + extu = store.create_entity('ExternalUri', uri="http://path/of/the/uri") #. creates the relations between the entities. We have relations between: - + #. entities defined in the schema, e.g. between ``Disease`` and ``Gene`` - entities, such as the ``associated_genes`` relation defined for + entities, such as the ``associated_genes`` relation defined for ``Disease`` entities. #. entities defined in the schema and ``ExternalUri`` entities, such as ``gene_id``. - - The way relations are added to the database depends on the store: - - - for the stores in the CubicWeb ``dataimport`` module, we only use - ``store.relate``, in - another loop, on the relations (that is, a + + The way relations are added to the database depends on the store: + + - for the stores in the CubicWeb ``dataimport`` module, we only use + ``store.relate``, in + another loop, on the relations (that is, a loop inside the preceding one, mentioned at step 2):: - + for rtype, rels in relations.iteritems(): ... - + store.relate(ent.eid(), rtype, extu.eid(), **kwargs) - + where ``kwargs`` is a dictionary designed to accommodate the need for specifying the type of the subject entity of the relation, when the relation is inlined and ``SQLGenObjectStore`` is used. For example:: - + ... store.relate(ent.eid(), 'chromosomal_location', extu.eid(), subjtype='Disease') - - - for the ``MassiveObjectStore`` in the ``dataio`` cube's ``dataimport`` module, + + - for the ``MassiveObjectStore`` in the ``dataio`` cube's ``dataimport`` module, the relations are created in three steps: - + #. first, a table is created for each relation type, as in:: - + ... store.init_rtype_table(ent.cw_etype, rtype, extu.cw_etype) - + which comes down to lines such as:: - + store.init_rtype_table('Disease', 'associated_genes', 'Gene') store.init_rtype_table('Gene', 'gene_id', 'ExternalUri') - - #. second, the URI of each entity will be used as its identifier, in the + + #. second, the URI of each entity will be used as its identifier, in the ``relate_by_iid`` method, such as:: - + disease_uri = 'http://www4.wiwiss.fu-berlin.de/diseasome/resource/diseases/3' gene_uri = '