# HG changeset patch # User sylvain.thenault@logilab.fr # Date 1241706802 -7200 # Node ID a721966779bec15b493b66daa409968569a34101 # Parent fd8751c3f3ee0ea17545eaf34a5b13b0cff9633a new book layout, do not compile yet diff -r fd8751c3f3ee -r a721966779be doc/book/README --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/book/README Thu May 07 16:33:22 2009 +0200 @@ -0,0 +1,43 @@ +==== +Book +==== + +---- +Part +---- + +Chapter +======= + +Level 1 section +--------------- + +Level 2 section +~~~~~~~~~~~~~~~ + +Level 3 section +``````````````` + + + +*CubicWeb* + + +inline directives: + :file: + :envvar: + :command: + + :ref:, :mod: + + +XXX +* lien vers cw.cwconfig.CW_CUBES_PATH par ex. + + +.. sourcecode:: python + + class SomePythonCode: + ... + +.. XXX a comment diff -r fd8751c3f3ee -r a721966779be doc/book/_maybe_to_integrate/D050-architecture.en.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/book/_maybe_to_integrate/D050-architecture.en.txt Thu May 07 16:33:22 2009 +0200 @@ -0,0 +1,14 @@ +.. -*- coding: utf-8 -*- + + +Server Architecture +------------------- + +.. image:: images/server-class-diagram.png + +`Diagramme ArgoUML`_ + +[FIXME] +Make a downloadable source of zargo file. + +.. _`Diagramme ArgoUML`: cubicweb.zargo diff -r fd8751c3f3ee -r a721966779be doc/book/_maybe_to_integrate/rss-xml.rst --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/book/_maybe_to_integrate/rss-xml.rst Thu May 07 16:33:22 2009 +0200 @@ -0,0 +1,45 @@ +.. -*- coding: utf-8 -*- + +RSS Channel +----------- + +Assuming you have several blog entries, click on the title of the +search box in the left column. A larger search box should appear. Enter:: + + Any X ORDERBY D WHERE X is BlogEntry, X creation_date D + +and you get a list of blog entries. + +Click on your login at the top right corner. Chose "user preferences", +then "boxes", then "possible views box" and check "visible = yes" +before validating your changes. + +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". + +You just applied the "RSS" view to the RQL selection you requested. + +That's it, you have a RSS channel for your blog. + +Try again with:: + + 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. + +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. + +[WRITE ME] + +* show that the RSS view can be used to display an ordered selection + of blog entries, thus providing a RSS channel + +* show that a different selection (by category) means a different channel + diff -r fd8751c3f3ee -r a721966779be doc/book/_maybe_to_integrate/template.rst --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/book/_maybe_to_integrate/template.rst Thu May 07 16:33:22 2009 +0200 @@ -0,0 +1,20 @@ + + +Templates +--------- + +*Templates* are specific views that do not depend on a result set. The basic +class `Template` (`cubicweb.common.view`) is derived from the class `View`. + +To build a HTML page, a *main template* is used. In general, the template of +identifier `main` is the one to use (it is not used in case an error is raised or for +the login form for example). This template uses other templates in addition +to the views which depends on the content to generate the HTML page to return. + +A *template* is responsible for: + +1. executing RQL query of data to render if necessary +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`. diff -r fd8751c3f3ee -r a721966779be doc/book/_maybe_to_integrate/treemixin.rst --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/book/_maybe_to_integrate/treemixin.rst Thu May 07 16:33:22 2009 +0200 @@ -0,0 +1,100 @@ + +Class `TreeMixIn` +----------------- + +This class provides a tree interface. This mixin has to be inherited +explicitly and configured using the tree_attribute, parent_target and +children_target class attribute to benefit from this default implementation. + +This class provides the following methods: + + * `different_type_children(entities=True)`, returns children entities + of different type as this entity. According to the `entities` parameter, + returns entity objects (if entity=True) or the equivalent result set. + + * `same_type_children(entities=True)`, returns children entities of + the same type as this entity. According to the `entities` parameter, + return entity objects (if entity=True) or the equivalent result set. + + * `iterchildren( _done=None)`, iters on the children of the entity. + + * `prefixiter( _done=None)` + + * `path()`, returns the list of eids from the root object to this object. + + * `iterparents()`, iters on the parents of the entity. + + * `notification_references(view)`, used to control References field + of email send on notification for this entity. `view` is the notification view. + Should return a list of eids which can be used to generate message ids + of previously sent email. + +`TreeMixIn` implements also the ITree interface (``cubicweb.interfaces``): + + * `parent()`, returns the parent entity if any, else None (e.g. if we are on the + root) + + * `children(entities=True, sametype=False)`, returns children entities + according to the `entities` parameter, return entity objects or the + equivalent result set. + + * `children_rql()`, returns the RQL query corresponding to the children + of the entity. + + * `is_leaf()`, returns True if the entity does not have any children. + + * `is_root()`, returns True if the entity does not have any parent. + + * `root()`, returns the root object of the tree representation of + the entity and its related entities. + +Example of use +`````````````` + +Imagine you defined three types of entities in your schema, and they +relates to each others as follows in ``schema.py``:: + + class Entity1(EntityType): + title = String() + is_related_to = SubjectRelation('Entity2', 'subject') + + class Entity2(EntityType): + title = String() + belongs_to = SubjectRelation('Entity3', 'subject') + + class Entity3(EntityType): + name = String() + +You would like to create a view that applies to both entity types +`Entity1` and `Entity2` and which lists the entities they are related to. +That means when you view `Entity1` you want to list all `Entity2`, and +when you view `Entity2` you want to list all `Entity3`. + +In ``entities.py``:: + + class Entity1(TreeMixIn, AnyEntity): + id = 'Entity1' + __implements__ = AnyEntity.__implements__ + (ITree,) + __rtags__ = {('is_related_to', 'Entity2', 'object'): 'link'} + tree_attribute = 'is_related_to' + + def children(self, entities=True): + return self.different_type_children(entities) + + class Entity2(TreeMixIn, AnyEntity): + id = 'Entity2' + __implements__ = AnyEntity.__implements__ + (ITree,) + __rtags__ = {('belongs_to', 'Entity3', 'object'): 'link'} + tree_attribute = 'belongs_to' + + def children(self, entities=True): + return self.different_type_children(entities) + +Once this is done, you can define your common view as follows:: + + class E1E2CommonView(baseviews.PrimaryView): + accepts = ('Entity11, 'Entity2') + + def render_entity_relations(self, entity, siderelations): + self.wview('list', entity.children(entities=False)) + diff -r fd8751c3f3ee -r a721966779be doc/book/en/A000-introduction.en.txt --- a/doc/book/en/A000-introduction.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,19 +0,0 @@ -.. -*- coding: utf-8 -*- - -.. _Part1: - -=================================== -Part I - Introduction to `CubicWeb` -=================================== - -This first part of the book will offer different reading path to -present you with the `CubicWeb` framework, provide a tutorial to get a quick -overview of its features and list its key concepts. - - -.. toctree:: - :maxdepth: 2 - - A010-book-map.en.txt - A020-tutorial.en.txt - A030-foundation.en.txt diff -r fd8751c3f3ee -r a721966779be doc/book/en/A010-book-map.en.txt --- a/doc/book/en/A010-book-map.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,10 +0,0 @@ -.. -*- coding: utf-8 -*- - -Book map -========= - -[WRITE ME] - -* explain how to use this book and what chapters to read in what order depending on the - objectives of the reader - diff -r fd8751c3f3ee -r a721966779be doc/book/en/A020-tutorial.en.txt --- a/doc/book/en/A020-tutorial.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,28 +0,0 @@ -.. -*- coding: utf-8 -*- - -.. _Tutorial: - -Tutorial -======== - -`CubicWeb` is a semantic web application framework that favors reuse and -object-oriented design. - -A `cube` is a component that includes a model defining the data types and a set of -views to display the data. - -An application is a `cube`, but usually an application is built by assembling -a few smaller cubes. - -An `instance` is a specific installation of an application and includes -configuration files. - - -This tutorial will show how to create a `cube` and how to use it as an -application to run an `instance`. - -.. include:: Z013-blog-less-ten-minutes.en.txt -.. include:: A02a-create-cube.en.txt -.. include:: A02b-components.en.txt -.. include:: A02c-maintemplate.en.txt -.. include:: A02d-conclusion.en.txt diff -r fd8751c3f3ee -r a721966779be doc/book/en/A02a-create-cube.en.txt --- a/doc/book/en/A02a-create-cube.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,269 +0,0 @@ -.. -*- coding: utf-8 -*- - -Create your cube ----------------- - -Once your `CubicWeb` development environment is set up, you can create a new -cube:: - - cubicweb-ctl newcube blog - -This will create in the cubes directory (``/path/to/forest/cubes`` for Mercurial -installation, ``/usr/share/cubicweb/cubes`` for debian packages installation) -a directory named ``blog`` reflecting the structure described in :ref:`cubesConcepts`. - -.. _DefineDataModel: - -Define your data model ----------------------- - -The data model or schema is the core of your `CubicWeb` application. -It defines the type of content your application will handle. - -The data model of your cube ``blog`` is defined in the file ``schema.py``: - -:: - - class Blog(EntityType): - title = String(maxsize=50, required=True) - description = String() - - class BlogEntry(EntityType): - title = String(required=True, fulltextindexed=True, maxsize=256) - publish_date = Date(default='TODAY') - content = String(required=True, fulltextindexed=True) - 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. -The description is a string that is not constrained. - -A BlogEntry has a title, a publish_date and a content. The title is a -string that is required and must be less than 100 characters. The -publish_date is a Date with a default value of TODAY, meaning that -when a BlogEntry is created, its publish_date will be the current day -unless it is modified. The content is a string that will be indexed in -the full-text index and has no constraint. - -A BlogEntry also has a relationship ``entry_of`` that links it to a -Blog. The cardinality ``?*`` means that a BlogEntry can be part of -zero or one Blog (``?`` means `zero or one`) and that a Blog can -have any number of BlogEntry (``*`` means `any number including -zero`). For completeness, remember that ``+`` means `one or more`. - - -Create your instance --------------------- - -To use this cube as an application and create a new instance named ``blogdemo``, do:: - - cubicweb-ctl create blog blogdemo - - -This command will create the corresponding database and initialize it. - -Welcome to your web application -------------------------------- - -Start your application in debug mode with the following command: :: - - cubicweb-ctl start -D blogdemo - - -You can now access your web application to create blogs and post messages -by visiting the URL http://localhost:8080/. - -A login form will appear. By default, the application will not allow anonymous -users to enter the application. To login, you need then use the admin account -you created at the time you initialized the database with ``cubicweb-ctl -create``. - -.. image:: images/login-form.png - - -Once authenticated, you can start playing with your application -and create entities. - -.. image:: images/blog-demo-first-page.png - -Please notice that so far, the `CubicWeb` franework managed all aspects of -the web application based on the schema provided at first. - - -Add entities ------------- - -We will now add entities in our web application. - -Add a Blog -~~~~~~~~~~ - -Let us create a few of these entities. Click on the `[+]` at the left of the -link Blog on the home page. Call this new Blog ``Tech-blog`` and type in -``everything about technology`` as the description, then validate the form by -clicking on ``Validate``. - -.. image:: images/cbw-create-blog.en.png - :alt: from to create blog - -Click on the logo at top left to get back to the home page, then -follow the Blog link that will list for you all the existing Blog. -You should be seeing a list with a single item ``Tech-blog`` you -just created. - -.. image:: images/cbw-list-one-blog.en.png - :alt: displaying a list of a single blog - -Clicking on this item will get you to its detailed description except -that in this case, there is not much to display besides the name and -the phrase ``everything about technology``. - -Now get back to the home page by clicking on the top-left logo, then -create a new Blog called ``MyLife`` and get back to the home page -again to follow the Blog link for the second time. The list now -has two items. - -.. image:: images/cbw-list-two-blog.en.png - :alt: displaying a list of two blogs - -Add a BlogEntry -~~~~~~~~~~~~~~~ - -Get back to the home page and click on [+] at the left of the link -BlogEntry. Call this new entry ``Hello World`` and type in some text -before clicking on ``Validate``. You added a new blog entry without -saying to what blog it belongs. There is a box on the left entitled -``actions``, click on the menu item ``modify``. You are back to the form -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``. - -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 -combobox titled ``add relation`` would have showed up. - - -.. image:: images/cbw-add-relation-entryof.en.png - :alt: editing a blog entry to add a relation to a blog - -Validate the changes by clicking ``Validate``. The entity BlogEntry -that is displayed now includes a link to the entity Blog named -``MyLife``. - -.. image:: images/cbw-detail-one-blogentry.en.png - :alt: displaying the detailed view of a blogentry - -Note that all of this was handled by the framework and that the only input -that was provided so far is the schema. To get a graphical view of the schema, -point your browser to the URL http://localhost:8080/schema - -.. image:: images/cbw-schema.en.png - :alt: graphical view of the schema (aka data-model) - - -.. _DefineViews: - -Define your entity views ------------------------- - -Each entity defined in a model inherits default views allowing -different rendering of the data. You can redefine each of them -according to your needs and preferences. So let's see how the -views are defined. - - -The view selection principle -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -A view is defined by a Python class which includes: - - - an identifier (all objects in `CubicWeb` are entered in a registry - and this identifier will be used as a key) - - - a filter to select the result sets it can be applied to - -A view has a set of methods complying -with the `View` class interface (`cubicweb.common.view`). - -`CubicWeb` provides a lot of standard views for the type `EntityView`; -for a complete list, read the code in directory ``cubicweb/web/views/``. - -A view is applied on a `result set` which contains a set of -entities we are trying to display. `CubicWeb` uses a selector -mechanism which computes for each available view a score: -the view with the highest score is then used to display the given `result set`. -The standard library of selectors is in -``cubicweb.common.selector`` and a library of methods used to -compute scores is available in ``cubicweb.vregistry.vreq``. - -It is possible to define multiple views for the same identifier -and to associate selectors and filters to allow the application -to find the best way to render the data. - -For example, the view named ``primary`` is the one used to display -a single entity. We will now show you how to customize this view. - - -View customization -~~~~~~~~~~~~~~~~~~ - -If you wish to modify the way a `BlogEntry` is rendered, you will have to -overwrite the `primary` view defined in the module ``views`` of the cube -``cubes/blog/views.py``. - -We can for example add in front of the publication date a prefix specifying -that the date we see is the publication date. - -To do so, please apply the following changes: - -:: - - from cubicweb.web.views import baseviews - - - class BlogEntryPrimaryView(baseviews.PrimaryView): - - accepts = ('BlogEntry',) - - def render_entity_title(self, entity): - self.w(u'

%s

' % html_escape(entity.dc_title())) - - def content_format(self, entity): - return entity.view('reledit', rtype='content_format') - - def cell_call(self, row, col): - entity = self.entity(row, col) - - # display entity attributes with prefixes - self.w(u'

%s

' % entity.title) - self.w(u'

published on %s

' % entity.publish_date.strftime('%Y-%m-%d')) - self.w(u'

%s

' % entity.content) - - # display relations - siderelations = [] - if self.main_related_section: - self.render_entity_relations(entity, siderelations) - -.. note:: - When a view is modified, it is not required to restart the application - server. Save the Python file and reload the page in your web browser - to view the changes. - -You can now see that the publication date has a prefix. - -.. image:: images/cbw-update-primary-view.en.png - :alt: modified primary view - - -The above source code defines a new primary view for ``BlogEntry``. - -Since views are applied to result sets and result sets can be tables of -data, we have to recover the entity from its (row,col)-coordinates. -The view has a ``self.w()`` method that is used to output data, in our -example HTML output. - -You can find more details about views and selectors in :ref:`ViewDefinition`. - - diff -r fd8751c3f3ee -r a721966779be doc/book/en/A02b-components.en.txt --- a/doc/book/en/A02b-components.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,81 +0,0 @@ -.. -*- coding: utf-8 -*- - -.. _cubes: - -Cubes ------ - -Standard library -~~~~~~~~~~~~~~~~ - -A library of standard cubes are available from `CubicWeb Forge`_ -Cubes provide entities and views. - -The available application entities are: - -* addressbook: PhoneNumber and PostalAddress - -* basket: Basket (like a shopping cart) - -* blog: Blog (a *very* basic blog) - -* classfolder: Folder (to organize things but grouping them in folders) - -* classtags: Tag (to tag anything) - -* file: File (to allow users to upload and store binary or text files) - -* link: Link (to collect links to web resources) - -* mailinglist: MailingList (to reference a mailing-list and the URLs - for its archives and its admin interface) - -* person: Person (easily mixed with addressbook) - -* task: Task (something to be done between start and stop date) - -* zone: Zone (to define places within larger places, for example a - city in a state in a country) - -The available system entities are: - -* comment: Comment (to attach comment threads to entities) - - -Adding comments to BlogDemo -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -To import a cube in your application just change the line in the -``__pkginfo__.py`` file and verify that the cube you are planning -to use is listed by the command ``cubicweb-ctl list``. -For example:: - - __use__ = ('comment',) - -will make the ``Comment`` entity available in your ``BlogDemo`` -application. - -Change the schema to add a relationship between ``BlogEntry`` and -``Comment`` and you are done. Since the comment cube defines the -``comments`` relationship, adding the line:: - - comments = ObjectRelation('Comment', cardinality='1*', composite='object') - -to the definition of a ``BlogEntry`` will be enough. - -Synchronize the data model -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Once you modified your data model, you need to synchronize the -database with your model. For this purpose, `CubicWeb` provides -a very useful command ``cubicweb-ctl shell blogdemo`` which -launches an interactive migration Python shell. (see -:ref:`cubicweb-ctl-shell` for more details)) -As you modified a relation from the `BlogEntry` schema, -run the following command: -:: - - synchronize_rschema('BlogEntry') - -You can now start your application and add comments to each -`BlogEntry`. diff -r fd8751c3f3ee -r a721966779be doc/book/en/A02c-maintemplate.en.txt --- a/doc/book/en/A02c-maintemplate.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,127 +0,0 @@ -.. -*- coding: utf-8 -*- - -Templates ---------- - -Look at ``cubicweb/web/views/basetemplates.py`` and you will -find the base templates used to generate HTML for your application. - -A page is composed as indicated on the schema below: - -.. image:: images/lax-book.06-main-template-layout.en.png - -In this section we will demonstrate a change in one of the main -interesting template from the three you will look for, -that is to say, the HTMLPageHeader, the HTMLPageFooter -and the TheMainTemplate. - - -Customize a template -~~~~~~~~~~~~~~~~~~~~ - -Based on the diagram below, each template can be overriden -by your customized template. To do so, we recommand you create -a Python module ``blog.views.templates`` to keep it organized. -In this module you will have to import the parent class you are -interested as follows: :: - - from cubicweb.web.views.basetemplates import HTMLPageHeader, \ - HTMLPageFooter, TheMainTemplate - -and then create your sub-class:: - - class MyBlogHTMLPageHeader(HTMLPageHeader): - ... - -Customize header -````````````````` - -Let's now move the search box in the header and remove the login form -from the header. We'll show how to move it to the left column of the application. - -Let's say we do not want anymore the login menu to be in the header - -First, to remove the login menu, we just need to comment out the display of the -login graphic component such as follows: :: - - class MyBlogHTMLPageHeader(HTMLPageHeader): - - def main_header(self, view): - """build the top menu with authentification info and the rql box""" - self.w(u'\n') - self.w(u'\n') - # appliname and breadcrumbs - self.w(u'') - # logged user and help - #self.w(u'') - # lastcolumn - self.w(u'\n') - self.w(u'\n') - self.template('logform', rset=self.rset, id='popupLoginBox', klass='hidden', - title=False, message=False) - - - -.. image:: images/lax-book.06-header-no-login.en.png - -Customize footer -```````````````` - -If you want to change the footer for example, look -for HTMLPageFooter and override it in your views file as in: :: - - from cubicweb.web.views.basetemplates import HTMLPageFooter - - class MyHTMLPageFooter(HTMLPageFooter): - - def call(self, **kwargs): - self.w(u'') - -Updating a view does not require any restart of the server. By reloading -the page you can see your new page footer. - - -TheMainTemplate -``````````````` - -.. _TheMainTemplate: - -The MainTemplate is a bit complex as it tries to accomodate many -different cases. We are now about to go through it and cutomize entirely -our application. - -TheMainTemplate is responsible for the general layout of the entire application. -It defines the template of ``id = main`` that is used by the application. Is -also defined in ``cubicweb/web/views/basetemplates.py`` another template that can -be used based on TheMainTemplate called SimpleMainTemplate which does not have -a top section. - -.. image:: images/lax-book.06-simple-main-template.en.png - -XXX -[WRITE ME] - -* customize MainTemplate and show that everything in the user - interface can be changed - diff -r fd8751c3f3ee -r a721966779be doc/book/en/A02d-conclusion.en.txt --- a/doc/book/en/A02d-conclusion.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,17 +0,0 @@ -.. -*- coding: utf-8 -*- - -What's next? ------------- - -We demonstrated how from a straight out of the box `CubicWeb` -installation, you can build your web-application based on a -schema. It's all already there: views, templates, permissions, -etc. The step forward is now for you to customize according -to your needs. - -More than a web application, many features are available to -extend your application, for example: RSS channel integration -(:ref:`rss`), hooks (:ref:`hooks`), support of sources such as -Google App Engine (:ref:`gaecontents`) and lots of others to -discover through our book. - diff -r fd8751c3f3ee -r a721966779be doc/book/en/A02d-rss-xml.en.txt --- a/doc/book/en/A02d-rss-xml.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -.. -*- coding: utf-8 -*- - -RSS Channel ------------ - -Assuming you have several blog entries, click on the title of the -search box in the left column. A larger search box should appear. Enter:: - - Any X ORDERBY D WHERE X is BlogEntry, X creation_date D - -and you get a list of blog entries. - -Click on your login at the top right corner. Chose "user preferences", -then "boxes", then "possible views box" and check "visible = yes" -before validating your changes. - -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". - -You just applied the "RSS" view to the RQL selection you requested. - -That's it, you have a RSS channel for your blog. - -Try again with:: - - 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. - -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. - -[WRITE ME] - -* show that the RSS view can be used to display an ordered selection - of blog entries, thus providing a RSS channel - -* show that a different selection (by category) means a different channel - diff -r fd8751c3f3ee -r a721966779be doc/book/en/A030-foundation.en.txt --- a/doc/book/en/A030-foundation.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,34 +0,0 @@ -.. -*- coding: utf-8 -*- - -`CubicWeb` Foundations -====================== - -A little history... -------------------- - -`CubicWeb` is a web application framework developped by Logilab_ since 2001. - -Entirely written in Python, `CubicWeb` publishes data from all sorts -of sources such as SQL database, LDAP directory and versioning system such -as subversion. - -`CubicWeb` user interface was designed to let the final user a huge flexibility -on how to select and how to display content. It allows to browse the knowledge -database and to display the results with the best rendering according to -the context. -This interface flexibility gives back the user the control of the -rendering parameters that are usually reserved for developpers. - - -We can list a couple of web applications developped with `CubicWeb`, an online -public phone directory (see http://www.118000.fr/), a system for managing -digital studies and simulations for a research lab, a tool for shared children -babysitting (see http://garde-partagee.atoukontact.fr/), a tool to manage -software developpment (see http://www.logilab.org), an application for -managing museums collections (see -http://collections.musees-haute-normandie.fr/collections/), etc. - -In 2008, `CubicWeb` was ported for a new type of source : the datastore -from `GoogleAppEngine`_. - -.. include:: A03a-concepts.en.txt diff -r fd8751c3f3ee -r a721966779be doc/book/en/A03a-concepts.en.txt --- a/doc/book/en/A03a-concepts.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,536 +0,0 @@ -.. -*- coding: utf-8 -*- - -Concepts --------- - -This section aims to provide you the keys of success with `CubicWeb` -by clarifying the terms specific to our framework. - -Global architecture -~~~~~~~~~~~~~~~~~~~ -.. image:: images/archi_globale.en.png - - -`CubicWeb` framework is a server/client application framework. Those two -parts communicate through RQL (`CubicWeb` query language implementation) -and ResultSet (which will be explained in :ref:`TermsVocabulary`). - -The server manages all interactions with sources. - - -.. note:: - Usually, the client and server sides are integrated in the same - process and interact directly, without the need for distant - calls using Pyro. But, it is important to note that those two - sides, client/server, are disjointed and it is possible to execute - a couple of calls in distinct processes to balance the load of - your web site on one or more machines. - -.. _TermsVocabulary: - -Terms and vocabulary -~~~~~~~~~~~~~~~~~~~~~ - -`CubicWeb` defines its own terminology. To make sure there is no confusion -while reading this book, we strongly recommand you take time to go through -the following definitions that are the basics to understand while -developing with `CubicWeb`. - -*schema* - The schema defines the data model of an application based on entities - and relations, modeled with a comprehensive language made of Python - classes based on `yams`_ library. This is the core piece - of an application. It is initially defined in the file system and is - stored in the database at the time an instance is created. `CubicWeb` - provides a certain number of system entities included automatically - (necessary for the core of `CubicWeb`) and a library of - cubes (which defined application entities) that can be explicitely - included if necessary. - -*entity type* - An entity type is a set of attributes; the essential attribute of - an entity is its key, named eid. - -*relation type* - Entities are linked to each others by relations. In `CubicWeb` - relations are binary: by convention we name the first item of - a relation the `subject` and the second the `object`. - -*final entity type* - Final types correspond to the basic types such as string of characters, - integers... Those types have a main property which is that they can - only be used as `object` of a relation. The attributes of an entity - (non final) are entities (finals). - -*final relation type* - A relation is said final if its `object` is a final type. This is equivalent - to an entity attribute. - -*relation definition* - A relation definition is a 3-uple (subject entity type, relation type, object - entity type), with an associated set of property such as cardinality, constraints... - -*repository* - This is the RQL server side of `CubicWeb`. Be carefull not to get - confused with a Mercurial repository or a debian repository. - -*source* - A data source is a container of data (SGBD, LDAP directory, `Google - App Engine`'s datastore ...) integrated in the - `CubicWeb` repository. This repository has at least one source, `system` which - contains the schema of the application, plain-text index and other - vital informations for the system. - -*configuration* - It is possible to create different configurations for an instance: - - - ``repository`` : repository only, accessible for clients using Pyro - - ``twisted`` : web interface only, access the repository using Pyro - - ``all-in-one`` : web interface and repository in a single process. - The repository could be or not accessible using Pyro. - -*cube* - A cube is a model grouping one or multiple data types and/or views - to provide a specific functionality or a complete `CubicWeb` application - potentially using other cubes. The available cubes are located in the file - system at `/path/to/forest/cubicweb/cubes` for a Mercurial forest installation. - For a debian packages installation they will be located in - `/usr/share/cubicweb/cubes`. - Larger applications can be built quite fast by importing cubes, - adding entities and relationships, overriding the - *views* that display the cubes or by editing informations not provided by - the cubes. - -*instance* - An instance is a specific installation of one or multiple cubes. All the required - configuration files necessary for the well being of your web application - are grouped in an instance. This will refer to the cube(s) your application - is based on. - For example logilab.org and our intranet are two instances of a single - cube "jpl", developped internally. - The instances are defined in the directory `/etc/cubicweb.d`. - -*application* - The term application is sometimes used to talk about an instance - and sometimes to talk of a cube depending on the context. - So we would like to avoid using this term and try to use *cube* and - *instance* instead. - -*result set* - This object contains the results of an RQL query sent to the source - and informations on the query. - -*Pyro* - `Python Remote Object`_, distributed objects system similar to Java's RMI - (Remote Method Invocation), which can be used for the dialog between the web - side of the framework and the RQL repository. - -*query language* - A full-blown query language named RQL is used to formulate requests - to the database or any sources such as LDAP or `Google App Engine`'s - datastore. - -*views* - A view is applied to a `result set` to present it as HTML, XML, - JSON, CSV, etc. Views are implemented as Python classes. There is no - templating language. - -*generated user interface* - A user interface is generated on-the-fly from the schema definition: - entities can be created, displayed, updated and deleted. As display - views are not very fancy, it is usually necessary to develop your - own. Any generated view can be overridden by defining a new one with - the same identifier. - -*rql* - Relation Query Language in order to emphasize the way of browsing relations. - This query language is inspired by SQL but is on a higher level; - its implementation generates SQL. - - -.. _`Python Remote Object`: http://pyro.sourceforge.net/ -.. _`yams`: http://www.logilab.org/project/yams/ - - -`CubicWeb` engine -~~~~~~~~~~~~~~~~~ - -The engine in `CubicWeb` is a set of classes managing a set of objects loaded -dynamically at the startup of `CubicWeb` (*appobjects*). Those dynamic objects, -based on the schema or the library, are building the final application. -The different dynamic components are for example: - -* client and server side - - - entities definition, containing the logic which enables application data manipulation - -* client side - - - *views*, or more specifically - - - boxes - - header and footer - - forms - - page templates - - - *actions* - - *controllers* - -* server side - - - notification hooks - - notification views - -The components of the engine are: - -* a frontal web (only twisted is available so far), transparent for dynamic objects -* an object that encapsulates the configuration -* a `registry` (`cubicweb.cwvreg`) containing the dynamic objects loaded automatically - -Every *appobject* may access to the instance configuration using its *config* attribute -and to the registry using its *vreg* attribute. - -API Python/RQL -~~~~~~~~~~~~~~ - -The Python API developped to interface with RQL is inspired from the standard db-api, -with a Connection object having the methods cursor, rollback and commit essentially. -The most important method is the `execute` method of a cursor : - -`execute(rqlstring, args=None, eid_key=None, build_descr=True)` - -:rqlstring: the RQL query to execute (unicode) -:args: if the query contains substitutions, a dictionary containing the values to use -:eid_key: - an implementation detail of the RQL cache implies that if a substitution - is used to introduce an eid *susceptible to raise the ambiguities in the query - type resolution*, then we have to specify the corresponding key in the dictionary - through this argument - - -The `Connection` object owns the methods `commit` and `rollback`. You *should -never need to use them* during the development of the web interface based on -the `CubicWeb` framework as it determines the end of the transaction depending -on the query execution success. - -.. note:: - While executing update queries (SET, INSERT, DELETE), if a query generates - an error related to security, a rollback is automatically done on the current - transaction. - - -The `Request` class (`cubicweb.web`) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -A request instance is created when an HTTP request is sent to the web server. -It contains informations such as form parameters, user authenticated, etc. - -**Globally, a request represents a user query, either through HTTP or not -(we also talk about RQL queries on the server side for example).** - -An instance of `Request` has the following attributes: - -* `user`, instance of `cubicweb.common.utils.User` corresponding to the authenticated - user -* `form`, dictionary containing the values of a web form -* `encoding`, character encoding to use in the response - -But also: - -:Session data handling: - * `session_data()`, returns a dictionary containing all the session data - * `get_session_data(key, default=None)`, returns a value associated to the given - key or the value `default` if the key is not defined - * `set_session_data(key, value)`, assign a value to a key - * `del_session_data(key)`, suppress the value associated to a key - - -:Cookies handling: - * `get_cookie()`, returns a dictionary containing the value of the header - HTTP 'Cookie' - * `set_cookie(cookie, key, maxage=300)`, adds a header HTTP `Set-Cookie`, - with a minimal 5 minutes length of duration by default (`maxage` = None - returns a *session* cookie which will expire when the user closes the browser - window) - * `remove_cookie(cookie, key)`, forces a value to expire - -:URL handling: - * `url()`, returns the full URL of the HTTP request - * `base_url()`, returns the root URL of the web application - * `relative_path()`, returns the relative path of the request - -:And more...: - * `set_content_type(content_type, filename=None)`, adds the header HTTP - 'Content-Type' - * `get_header(header)`, returns the value associated to an arbitrary header - of the HTTP request - * `set_header(header, value)`, adds an arbitrary header in the response - * `cursor()` returns a RQL cursor on the session - * `execute(*args, **kwargs)`, shortcut to ``.cursor().execute()`` - * `property_value(key)`, properties management (`CWProperty`) - * dictionary `data` to store data to share informations between components - *while a request is executed* - -Please note that this class is abstract and that a concrete implementation -will be provided by the *frontend* web used (in particular *twisted* as of -today). For the views or others that are executed on the server side, -most of the interface of `Request` is defined in the session associated -to the client. - -The `AppObject` class -~~~~~~~~~~~~~~~~~~~~~ - -In general: - -* we do not inherit directly from this class but from a more specific - class such as `AnyEntity`, `EntityView`, `AnyRsetView`, - `Action`... - -* to be recordable, a subclass has to define its own register (attribute - `__registry__`) and its identifier (attribute `id`). Usually we do not have - to take care of the register, only the identifier `id`. - -We can find a certain number of attributes and methods defined in this class -and common to all the application objects. - -At the recording, the following attributes are dynamically added to -the *subclasses*: - -* `vreg`, the `vregistry` of the application -* `schema`, the application schema -* `config`, the application configuration - -We also find on instances, the following attributes: - -* `req`, `Request` instance -* `rset`, the *result set* associated to the object if necessary -* `cursor`, rql cursor on the session - - -:URL handling: - * `build_url(method=None, **kwargs)`, returns an absolute URL based on - the given arguments. The *controller* supposed to handle the response, - can be specified through the special parameter `method` (the connection - is theoretically done automatically :). - - * `datadir_url()`, returns the directory of the application data - (contains static files such as images, css, js...) - - * `base_url()`, shortcut to `req.base_url()` - - * `url_quote(value)`, version *unicode safe* of the function `urllib.quote` - -:Data manipulation: - - * `etype_rset(etype, size=1)`, shortcut to `vreg.etype_rset()` - - * `eid_rset(eid, rql=None, descr=True)`, returns a *result set* object for - the given eid - * `entity(row, col=0)`, returns the entity corresponding to the data position - in the *result set* associated to the object - - * `complete_entity(row, col=0, skip_bytes=True)`, is equivalent to `entity` but - also call the method `complete()` on the entity before returning it - -:Data formatting: - * `format_date(date, date_format=None, time=False)` returns a string for a - mx date time according to application's configuration - * `format_time(time)` returns a string for a mx date time according to - application's configuration - -:And more...: - - * `external_resource(rid, default=_MARKER)`, access to a value defined in the - configuration file `external_resource` - - * `tal_render(template, variables)`, renders a precompiled page template with - variables in the given dictionary as context - -.. note:: - When we inherit from `AppObject` (even not directly), you *always* have to use - **super()** to get the methods and attributes of the superclasses, and not - use the class identifier. - For example, instead of writting: :: - - class Truc(PrimaryView): - def f(self, arg1): - PrimaryView.f(self, arg1) - - You'd better write: :: - - class Truc(PrimaryView): - def f(self, arg1): - super(Truc, self).f(arg1) - -.. _cubesConcepts: - -Cubes -~~~~~ - -What is a cube ? -```````````````` - -A cube is a model grouping one or more entity types and/or views associated -in order to provide a specific feature or even a complete application using -other cubes. - -You can decide to write your own set of cubes if you wish to re-use the -entity types you develop. Lots of cubes are available from the `CubicWeb -Forge`_ under a free software license. - -.. _`CubicWeb Forge`: http://www.cubicweb.org/project/ - -.. _foundationsCube: - -Standard structure for a cube -````````````````````````````` - -A cube is structured as follows: - -:: - - mycube/ - | - |-- data/ - | |-- cubes.mycube.css - | |-- cubes.mycube.js - | `-- external_resources - | - |-- debian/ - | |-- changelog - | |-- compat - | |-- control - | |-- copyright - | |-- cubicweb-mycube.prerm - | `-- rules - | - |-- entities.py - | - |-- i18n/ - | |-- en.po - | `-- fr.po - | - |-- __init__.py - | - |-- MANIFEST.in - | - |-- migration/ - | |-- postcreate.py - | `-- precreate.py - | - |-- __pkginfo__.py - | - |-- schema.py - | - |-- setup.py - | - |-- site_cubicweb.py - | - |-- hooks.py - | - |-- test/ - | |-- data/ - | | `-- bootstrap_cubes - | |-- pytestconf.py - | |-- realdb_test_mycube.py - | `-- test_mycube.py - | - `-- views.py - - -We can use subpackages instead of python modules for ``views.py``, ``entities.py``, -``schema.py`` or ``hooks.py``. For example, we could have: - -:: - - mycube/ - | - |-- entities.py - |-- hooks.py - `-- views/ - |-- forms.py - |-- primary.py - `-- widgets.py - - -where : - -* ``schema`` contains the schema definition (server side only) -* ``entities`` contains the entities definition (server side and web interface) -* ``sobjects`` contains hooks and/or views notifications (server side only) -* ``views`` contains the web interface components (web interface only) -* ``test`` contains tests related to the application (not installed) -* ``i18n`` contains message catalogs for supported languages (server side and - web interface) -* ``data`` contains data files for static content (images, css, javascripts) - ...(web interface only) -* ``migration`` contains initialization file for new instances (``postcreate.py``) - and a file containing dependencies of the component depending on the version - (``depends.map``) -* ``debian`` contains all the files managing debian packaging (you will find - the usual files ``control``, ``rules``, ``changelog``... not installed) -* file ``__pkginfo__.py`` provides component meta-data, especially the distribution - and the current version (server side and web interface) or sub-cubes used by - the cube. - - -At least you should have: - -* the file ``__pkginfo__.py`` -* the schema definition - XXX false, we may want to have cubes which are only adding a service, - no persistent data (eg embedding for instance) - - -Standard library -```````````````` - -A library of standard cubes are available from `CubicWeb Forge`_ -Cubes provide entities and views. - -The available application entities are: - -* addressbook_: PhoneNumber and PostalAddress - -* basket_: Basket (like a shopping cart) - -* blog_: Blog (a *very* basic blog) - -* comment_: Comment (to attach comment threads to entities) - -* event_: Event (define events, display them in calendars) - -* file_: File (to allow users to upload and store binary or text files) - -* folder_: Folder (to organize things but grouping them in folders) - -* keyword_: Keyword (to define classification schemes) - -* link_: Link (to collect links to web resources) - -* mailinglist_: MailingList (to reference a mailing-list and the URLs - for its archives and its admin interface) - -* person_: Person (easily mixed with addressbook) - -* tag_: Tag (to tag anything) - -* task_: Task (something to be done between start and stop date) - -* zone_: Zone (to define places within larger places, for example a - city in a state in a country) - -.. _addressbook: http://www.cubicweb.org/project/cubicweb-addressbook -.. _basket: http://www.cubicweb.org/project/cubicweb-basket -.. _blog: http://www.cubicweb.org/project/cubicweb-blog -.. _comment: http://www.cubicweb.org/project/cubicweb-comment -.. _event: http://www.cubicweb.org/project/cubicweb-event -.. _file: http://www.cubicweb.org/project/cubicweb-file -.. _folder: http://www.cubicweb.org/project/cubicweb-folder -.. _keyword: http://www.cubicweb.org/project/cubicweb-keyword -.. _link: http://www.cubicweb.org/project/cubicweb-link -.. _mailinglist: http://www.cubicweb.org/project/cubicweb-mailinglist -.. _person: http://www.cubicweb.org/project/cubicweb-person -.. _tag: http://www.cubicweb.org/project/cubicweb-tag -.. _task: http://www.cubicweb.org/project/cubicweb-task -.. _zone: http://www.cubicweb.org/project/cubicweb-zone diff -r fd8751c3f3ee -r a721966779be doc/book/en/B0-data-model.en.txt --- a/doc/book/en/B0-data-model.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,13 +0,0 @@ -.. -*- coding: utf-8 -*- - -The data model -++++++++++++++ - -.. toctree:: - :maxdepth: 1 - - B0010-define-schema.en.txt - B0020-define-workflows.en.txt - B0030-data-as-objects.en.txt - B0040-migration.en.txt - diff -r fd8751c3f3ee -r a721966779be doc/book/en/B0010-define-schema.en.txt --- a/doc/book/en/B0010-define-schema.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,23 +0,0 @@ -.. -*- coding: utf-8 -*- - -Data model definition: the *schema* -=================================== - -The **schema** is the core piece of a `CubicWeb` application as it defines -the handled data model. It is based on entity types that are either already -defined in the `CubicWeb` standard library; or more specific types, that -`CubicWeb` expects to find in one or more Python files under the directory -`schema`. - -At this point, it is important to make clear the difference between -*relation type* and *relation definition*: a *relation type* is only a relation -name with potentially other additionnal properties (see XXXX), whereas a -*relation definition* is a complete triplet -" ". -A relation type could have been implied if none is related to a -relation definition of the schema. - - -.. include:: B0011-schema-stdlib.en.txt -.. include:: B0012-schema-definition.en.txt - diff -r fd8751c3f3ee -r a721966779be doc/book/en/B0011-schema-stdlib.en.txt --- a/doc/book/en/B0011-schema-stdlib.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,98 +0,0 @@ -.. -*- coding: utf-8 -*- - -Pre-defined schemas in the library ----------------------------------- - -The library defines a set of entity schemas that are required by the system -or commonly used in `CubicWeb` applications. -Of course, you can extend those schemas if necessary. - - -System schemas -`````````````` -The available system entities are: - -* `CWUser`, system users -* `CWGroup`, users groups -* `CWEType`, entity type -* `CWRType`, relation type - -* `State`, workflow state -* `Transition`, workflow transition -* `TrInfo`, record of a transition trafic for an entity - -* `EmailAddress`, email address, used by the system to send notifications - to the users and also used by others optionnals schemas - -* `CWProperty`, used to configure the application -* `CWPermission`, used to configure the security of the application - -* `Card`, generic documenting card -* `Bookmark`, an entity type used to allow a user to customize his links within - the application - -(The first 'E' in some of the names is the first letter of 'Erudi', -`CubicWeb`'s old name; it might be changed/removed some day.) - -Available cubes -``````````````` - -An application is based on several basic cubes. In the set of available -basic cubes we can find for example : - -* addressbook_: PhoneNumber and PostalAddress - -* basket_: Basket (like a shopping cart) - -* blog_: Blog (a *very* basic blog) - -* comment_: Comment (to attach comment threads to entities) - -* email_: archiving management for emails (`Email`, `Emailpart`, - `Emailthread`) - -* event_: Event (define events, display them in calendars) - -* file_: File (to allow users to upload and store binary or text files) - -* folder_: Folder (to organize things but grouping them in folders) - -* keyword_: Keyword (to define classification schemes) - -* link_: Link (to collect links to web resources) - -* mailinglist_: MailingList (to reference a mailing-list and the URLs - for its archives and its admin interface) - -* person_: Person (easily mixed with addressbook) - -* tag_: Tag (to tag anything) - -* task_: Task (something to be done between start and stop date) - -* zone_: Zone (to define places within larger places, for example a - city in a state in a country) - -.. _addressbook: http://www.cubicweb.org/project/cubicweb-addressbook -.. _basket: http://www.cubicweb.org/project/cubicweb-basket -.. _blog: http://www.cubicweb.org/project/cubicweb-blog -.. _comment: http://www.cubicweb.org/project/cubicweb-comment -.. _email: http://www.cubicweb.org/project/cubicweb-email -.. _event: http://www.cubicweb.org/project/cubicweb-event -.. _file: http://www.cubicweb.org/project/cubicweb-file -.. _folder: http://www.cubicweb.org/project/cubicweb-folder -.. _keyword: http://www.cubicweb.org/project/cubicweb-keyword -.. _link: http://www.cubicweb.org/project/cubicweb-link -.. _mailinglist: http://www.cubicweb.org/project/cubicweb-mailinglist -.. _person: http://www.cubicweb.org/project/cubicweb-person -.. _tag: http://www.cubicweb.org/project/cubicweb-tag -.. _task: http://www.cubicweb.org/project/cubicweb-task -.. _zone: http://www.cubicweb.org/project/cubicweb-zone - -To declare the use of a component, once installed, add the name of the component -to the variable `__use__` in the file `__pkginfo__.py` of your own component. - -.. note:: - The listed cubes above are available as debian-packages on `CubicWeb's forge`_. - -.. _`CubicWeb's forge`: http://www.cubicweb.org/project?vtitle=All%20cubicweb%20projects diff -r fd8751c3f3ee -r a721966779be doc/book/en/B0012-schema-definition.en.txt --- a/doc/book/en/B0012-schema-definition.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,421 +0,0 @@ -.. -*- coding: utf-8 -*- - -Entity type definition ----------------------- - -An entity type is defined by a Python class which inherits from `EntityType`. -The class definition contains the description of attributes and relations -for the defined entity type. -The class name corresponds to the entity type name. It is exepected to be -defined in the module ``mycube.schema``. - - -For example :: - - class Person(EntityType): - """A person with the properties and the relations necessary for my - application""" - - last_name = String(required=True, fulltextindexed=True) - first_name = String(required=True, fulltextindexed=True) - title = String(vocabulary=('Mr', 'Mrs', 'Miss')) - date_of_birth = Date() - works_for = SubjectRelation('Company', cardinality='?*') - - -The entity described above defines three attributes of type String, -last_name, first_name and title, an attribute of type Date for the date of -birth and a relation that connects a `Person` to another entity of type -`Company` through the semantic `works_for`. - -The name of the Python attribute corresponds to the name of the attribute -or the relation in `CubicWeb` application. - -Built-in types for attributes -````````````````````````````` - -All `CubicWeb` built-in types are available : `String`, `Int`, `Float`, -`Decimal`, `Boolean`, `Date`, `Datetime`, `Time`, `Interval`, `Byte` -and `Password`. -They are implicitely imported (as well as the special the function "_" -for translation :ref:`internationalization`). - -An attribute is defined in the schema as follows:: - - attr_name = attr_type(properties*) - -where `attr_type` is one of the type listed above and `properties` is -a list of the attribute needs to statisfy (see :ref:`properties` -for more details). - - -Meta-data -````````` - -Each entity type has at least the following meta-relations : - - - `eid` (`Int`) - - - `creation_date` (`Datetime`) - - - `modification_date` (`Datetime`) - - - `created_by` (`CWUser`) (which user created the entity) - - - `owned_by` (`CWUser`) (to whom the entity belongs; by default the - creator but not necessary, and it could have multiple owners) - - - `is` (`CWEType`) (of which type the entity is) - - -* relations can be defined by using `ObjectRelation` or `SubjectRelation`. - The first argument of `SubjectRelation` or `ObjectRelation` gives respectively - the object/subject entity type of the relation. This could be : - - * a string corresponding to an entity type - - * a tuple of string corresponding to multiple entity types - - * special string such as follows : - - - "**" : all types of entities - - "*" : all types of non-meta entities - - "@" : all types of meta entities but not system entities (e.g. used for - the basic schema description) - -* it is possible to use the attribute `meta` to flag an entity type as a `meta` - (e.g. used to describe/categorize other entities) - -Optionnal properties -```````````````````` -.. _properties: - - -* optional properties for attributes and relations : - - - `description` : a string describing an attribute or a relation. By default - this string will be used in the editing form of the entity, which means - that it is supposed to help the end-user and should be flagged by the - function `_` to be properly internationalized. - - - `constraints` : a list of conditions/constraints that the relation has to - satisfy (c.f. `Contraints`_) - - - `cardinality` : a two character string which specify the cardinality of the - relation. The first character defines the cardinality of the relation on - the subject, and the second on the object. When a relation can have - multiple subjects or objects, the cardinality applies to all, - not on a one-to-one basis (so it must be consistent...). The possible - values are inspired from regular expression syntax : - - * `1`: 1..1 - * `?`: 0..1 - * `+`: 1..n - * `*`: 0..n - - - `meta` : boolean indicating that the relation is a meta-relation (false by - default) - -* optional properties for attributes : - - - `required` : boolean indicating if the attribute is required (false by default) - - - `unique` : boolean indicating if the value of the attribute has to be unique - or not within all entities of the same type (false by default) - - - `indexed` : boolean indicating if an index needs to be created for this - attribute in the database (false by default). This is useful only if - you know that you will have to run numerous searches on the value of this - attribute. - - - `default` : default value of the attribute. In case of date types, the values - which could be used correspond to the RQL keywords `TODAY` and `NOW`. - - - `vocabulary` : specify static possible values of an attribute - -* optional properties of type `String` : - - - `fulltextindexed` : boolean indicating if the attribute is part of - the full text index (false by default) (*applicable on the type `Byte` - as well*) - - - `internationalizable` : boolean indicating if the value of the attribute - is internationalizable (false by default) - - - `maxsize` : integer providing the maximum size of the string (no limit by default) - -* optional properties for relations : - - - `composite` : string indicating that the subject (composite == 'subject') - is composed of the objects of the relations. For the opposite case (when - the object is composed of the subjects of the relation), we just set - 'object' as value. The composition implies that when the relation - is deleted (so when the composite is deleted), the composed are also deleted. - -Contraints -`````````` -By default, the available constraint types are : - -* `SizeConstraint` : allows to specify a minimum and/or maximum size on - string (generic case of `maxsize`) - -* `BoundConstraint` : allows to specify a minimum and/or maximum value on - numeric types - -* `UniqueConstraint` : identical to "unique=True" - -* `StaticVocabularyConstraint` : identical to "vocabulary=(...)" - -* `RQLConstraint` : allows to specify a RQL query that has to be satisfied - by the subject and/or the object of the relation. In this query the variables - `S` and `O` are reserved for the entities subject and object of the - relation. - -* `RQLVocabularyConstraint` : similar to the previous type of constraint except - that it does not express a "strong" constraint, which means it is only used to - restrict the values listed in the drop-down menu of editing form, but it does - not prevent another entity to be selected. - - -Definition of relations ------------------------ - -XXX add note about defining relation type / definition - -A relation is defined by a Python class heriting `RelationType`. The name -of the class corresponds to the name of the type. The class then contains -a description of the properties of this type of relation, and could as well -contain a string for the subject and a string for the object. This allows to create -new definition of associated relations, (so that the class can have the -definition properties from the relation) for example :: - - class locked_by(RelationType): - """relation on all entities indicating that they are locked""" - inlined = True - cardinality = '?*' - subject = '*' - object = 'CWUser' - -In addition to the permissions, the properties of the relation types -(shared also by all definition of relation of this type) are : - - -* `inlined` : boolean handling the physical optimization for archiving - the relation in the subject entity table, instead of creating a specific - table for the relation. This applies to the relation when the cardinality - of subject->relation->object is 0..1 (`?`) or 1..1 (`1`) - -* `symmetric` : boolean indicating that the relation is symmetrical, which - means `X relation Y` implies `Y relation X` - -In the case of simultaneous relations definitions, `subject` and `object` -can both be equal to the value of the first argument of `SubjectRelation` -and `ObjectRelation`. - -When a relation is not inlined and not symmetrical, and it does not require -specific permissions, its definition (by using `SubjectRelation` and -`ObjectRelation`) is all we need. - - -The security model ------------------- - -The security model of `cubicWeb` is based on `Access Control List`. -The main principles are: - -* users and groups of users -* a user belongs to at least one group of user -* permissions (read, update, create, delete) -* permissions are assigned to groups (and not to users) - -For `CubicWeb` in particular: - -* we associate rights at the enttities/relations schema level -* for each entity, we distinguish four kind of permissions: read, - add, update and delete -* for each relation, we distinguish three king of permissions: read, - add and delete (we can not modify a relation) -* the basic groups are: Administrators, Users and Guests -* by default, users belongs to the group Users -* there is a virtual group called `Owners users` to which we - can associate only deletion and update permissions -* we can not add users to the `Owners users` group, they are - implicetely added to it according to the context of the objects - they own -* the permissions of this group are only be checked on update/deletion - actions if all the other groups the user belongs does not provide - those permissions - - -Permissions definition -`````````````````````` - -Setting permissions is done with the attribute `permissions` of entities and -relation types. It defines a dictionary where the keys are the access types -(action), and the values are the authorized groups or expressions. - -For an entity type, the possible actions are `read`, `add`, `update` and -`delete`. - -For a relation type, the possible actions are `read`, `add`, and `delete`. - -For each access type, a tuple indicates the name of the authorized groups and/or -one or multiple RQL expressions to satisfy to grant access. The access is -provided once the user is in the listed groups or one of the RQL condition is -satisfied. - -The standard groups are : - -* `guests` - -* `users` - -* `managers` - -* `owners` : virtual group corresponding to the entity's owner. - This can only be used for the actions `update` and `delete` of an entity - type. - -It is also possible to use specific groups if they are defined in the precreate -of the cube (``migration/precreate.py``). - - -Use of RQL expression for writing rights -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -It is possible to define RQL expression to provide update permission -(`add`, `delete` and `update`) on relation and entity types. - -RQL expression for entity type permission : - -* you have to use the class `ERQLExpression` - -* the used expression corresponds to the WHERE statement of an RQL query - -* in this expression, the variables X and U are pre-defined references - respectively on the current entity (on which the action is verified) and - on the user who send the request - -* it is possible to use, in this expression, a special relation - "has__permission" where the subject is the user and the - object is a any variable, meaning that the user needs to have - permission to execute the action on the entities related - to this variable - -For RQL expressions on a relation type, the principles are the same except -for the following : - -* you have to use the class `RQLExpression` in the case of a non-final relation - -* in the expression, the variables S, O and U are pre-defined references - to respectively the subject and the object of the current relation (on - which the action is being verified) and the user who executed the query - -* we can also defined rights on attributes of an entity (non-final relation), - knowing that : - - - to defines RQL expression, we have to use the class `ERQLExpression` - in which X represents the entity the attribute belongs to - - - the permissions `add` and `delete` are equivalent. Only `add`/`read` - are actually taken in consideration. - -In addition to that the entity type `CWPermission` from the standard library -allow to build very complex and dynamic security architecture. The schema of -this entity type is as follow : :: - - class CWPermission(MetaEntityType): - """entity type that may be used to construct some advanced security configuration - """ - name = String(required=True, indexed=True, internationalizable=True, maxsize=100) - require_group = SubjectRelation('CWGroup', cardinality='+*', - description=_('groups to which the permission is granted')) - require_state = SubjectRelation('State', - description=_("entity'state in which the permission is applyable")) - # can be used on any entity - require_permission = ObjectRelation('**', cardinality='*1', composite='subject', - description=_("link a permission to the entity. This " - "permission should be used in the security " - "definition of the entity's type to be useful.")) - - -Example of configuration :: - - - ... - - class Version(EntityType): - """a version is defining the content of a particular project's release""" - - permissions = {'read': ('managers', 'users', 'guests',), - 'update': ('managers', 'logilab', 'owners',), - 'delete': ('managers', ), - 'add': ('managers', 'logilab', - ERQLExpression('X version_of PROJ, U in_group G,' - 'PROJ require_permission P, P name "add_version",' - 'P require_group G'),)} - - ... - - class version_of(RelationType): - """link a version to its project. A version is necessarily linked to one and only one project. - """ - permissions = {'read': ('managers', 'users', 'guests',), - 'delete': ('managers', ), - 'add': ('managers', 'logilab', - RRQLExpression('O require_permission P, P name "add_version",' - 'U in_group G, P require_group G'),) - } - inlined = True - -This configuration indicates that an entity `CWPermission` named -"add_version" can be associated to a project and provides rights to create -new versions on this project to specific groups. It is important to notice that : - -* in such case, we have to protect both the entity type "Version" and the relation - associating a version to a project ("version_of") - -* because of the genricity of the entity type `CWPermission`, we have to execute - a unification with the groups and/or the states if necessary in the expression - ("U in_group G, P require_group G" in the above example) - -Use of RQL expression for reading rights -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The principles are the same but with the following restrictions : - -* we can not use `RRQLExpression` on relation types for reading - -* special relations "has__permission" can not be used - - -Note on the use of RQL expression for `add` permission -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Potentially, the use of an RQL expression to add an entity or a relation -can cause problems for the user interface, because if the expression uses -the entity or the relation to create, then we are not able to verify the -permissions before we actually add the entity (please note that this is -not a problem for the RQL server at all, because the permissions checks are -done after the creation). In such case, the permission check methods -(check_perm, has_perm) can indicate that the user is not allowed to create -this entity but can obtain the permission. -To compensate this problem, it is usually necessary, for such case, -to use an action that reflects the schema permissions but which enables -to check properly the permissions so that it would show up if necessary. - - -Updating your application with your new schema -`````````````````````````````````````````````` - -If you modified your schema, the update is not automatic; indeed, this is -in general not a good idea. -Instead, you call a shell on your application, which is a -an interactive python shell, with an appropriate -cubicweb environment :: - - cubicweb-ctl shell myinstance - -and type :: - - add_entity_type('Person') - -And restart your application! diff -r fd8751c3f3ee -r a721966779be doc/book/en/B0020-define-workflows.en.txt --- a/doc/book/en/B0020-define-workflows.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,159 +0,0 @@ -.. -*- coding: utf-8 -*- - -.. _Workflow: - -An Example: Workflow definition -=============================== - -General -------- - -A workflow describes how certain entities have to evolve between -different states. Hence we have a set of states, and a "transition graph", -i.e. a list of possible transitions from one state to another state. - -We will define a simple workflow for a blog, with only the following -two states: `submitted` and `published`. So first, we create a simple -`CubicWeb` in ten minutes (see :ref:`BlogTenMinutes`). - -Set-up a workflow ------------------ - -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 has to -be in the state `published`. To move it from `submitted` to `published`, -we need a transition that we can call `approve_blogentry`. - -A BlogEntry state should not be modifiable by every user. -So we have to define a group of users, `moderators`, and -this group will have appropriate permissions to publish a BlogEntry. - -There are two ways to create a workflow: from the user interface, -or by defining it in ``migration/postcreate.py``. -This script is executed each time a new ``cubicweb-ctl db-init`` is done. -We strongly recommand to create the workflow in ``migration/postcreate.py`` -and we will now show you how. Read `Under the hood`_ to understand why. - -Update the schema -~~~~~~~~~~~~~~~~~ -If we want a State for our BlogEntry, we have to define a relation -``in_state`` in the schema of BlogEntry. So we add -the line ``in_state (...)``:: - - class BlogEntry(EntityType): - title = String(maxsize=100, required=True) - publish_date = Date(default='TODAY') - text_format = String(meta=True, internationalizable=True, maxsize=50, - default='text/rest', constraints=[format_constraint]) - text = String(fulltextindexed=True) - category = String(vocabulary=('important','business')) - entry_of = SubjectRelation('Blog', cardinality='?*') - in_state = SubjectRelation('State', cardinality='1*') - -As you updated the schema, you have to re-execute ``cubicweb-ctl db-init`` -to initialize the database and migrate your existing entities. - -[WRITE ABOUT MIGRATION] - -Create states, transitions and group permissions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The ``postcreate.py`` script is executed in a special environment, adding -several `CubicWeb` primitives that can be used. -They are all defined in the ``class ServerMigrationHelper``. -We will only discuss the methods we use to create a workflow in this example. - -To define our workflow for BlogDemo, please add the following lines -to ``migration/postcreate.py``:: - - _ = unicode - - moderators = add_entity('CWGroup', name=u"moderators") - -This adds the `moderators` user group. - -:: - - submitted = add_state(_('submitted'), 'BlogEntry', initial=True) - published = add_state(_('published'), 'BlogEntry') - -``add_state`` expects as first argument the name of the state you want -to create, then the entity type on which the state can be applied, -and an optional argument to say if it is supposed to be the initial state -of the entity type. - -:: - - add_transition(_('approve_blogentry'), 'BlogEntry', (submitted,), published, ('moderators', 'managers'),) - - -``add_transition`` expects - - * as the first argument the name of the - transition, then the entity type on which the transition can be applied, - * then the list of states on which the transition can be trigged, - * the target state of the transition, - * and the permissions - (e.g. a list of user groups who can apply the transition; the user - has to belong to at least one of the listed group to perform the action). - -:: - - checkpoint() - -.. note:: - Do not forget to add the `_()` in front of all states and transitions names while creating - a workflow so that they will be identified by the i18n catalog scripts. - -In addition to the user group condition, we could have added a RQL condition. -In this case, the user can only perform the action if -the two conditions are satisfied. - -If we use a RQL condition on a transition, we can use the following -variables: - -* `%(eid)s`, object's eid -* `%(ueid)s`, user executing the query eid -* `%(seid)s`, the object's current state eid - - -.. image:: images/lax-book.03-transitions-view.en.png - -You can notice that in the action box of a BlogEntry, the state -is now listed as well as the possible transitions defined by the workflow. -The transitions will only be displayed for users having the right permissions. -In our example, the transition `approve_blogentry` will only be displayed -for the users belonging to the group `moderators` or `managers`. - - -Under the hood -~~~~~~~~~~~~~~ - -A workflow is a collection of entities of type ``State`` and of type ``Transition`` -which are standard `CubicWeb` entity types. -For instance, the following lines:: - - submitted = add_state(_('submitted'), 'BlogEntry', initial=True) - published = add_state(_('published'), 'BlogEntry') - -will create two entities of type ``State``, one with name 'submitted', and the other -with name 'published'. Whereas:: - - add_transition(_('approve_blogentry'), 'BlogEntry', (submitted,), published, ('moderators', 'managers'),) - -will create an entity of type ``Transition`` with name 'approve_blogentry' which will -be linked to the ``State`` entities created before. -As a consequence, we could use the administration interface to do these operations. -But it is not recommanded because it will be uselessly complicated -and will be only local to your instance. - - -Indeed, if you create the states and transitions through the user interface, -next time you initialize the database -you will have to re-create all the entities. -The user interface should only be a reference for you to view the states -and transitions, but is not the appropriate interface to define your -application workflow. - - diff -r fd8751c3f3ee -r a721966779be doc/book/en/B0030-data-as-objects.en.txt --- a/doc/book/en/B0030-data-as-objects.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,247 +0,0 @@ -.. -*- coding: utf-8 -*- - - -Data as objects -=============== - -In this chapter, we will introduce the objects that are used to handle -the data stored in the database. - -Class `Entity` and `AnyEntity` ------------------------------- - -To provide a specific behavior for each entity, we have to define -a class inheriting from `cubicweb.entities.AnyEntity`. In general, we -define this class in a module of `mycube.entities` package of an application -so that it will be available on both server and client side. - -The class `AnyEntity` is loaded dynamically from the class `Entity` -(`cubciweb.common.entity`). We define a sub-class to add methods or to -specialize the handling of a given entity type - -Descriptors are added when classes are registered in order to initialize the class -according to its schema: - -* we can access the defined attributes in the schema thanks to the attributes of - the same name on instances (typed value) - -* we can access the defined relations in the schema thanks to the relations of - the same name on instances (entities instances list) - -The methods defined for `AnyEntity` or `Entity` are the following ones: - -* `has_eid()`, returns true is the entity has an definitive eid (e.g. not in the - creation process) - -* `check_perm(action)`, checks if the user has the permission to execute the - requested action on the entity - -:Formatting and output generation: - - * `view(vid, **kwargs)`, applies the given view to the entity - - * `absolute_url(**kwargs)`, returns an absolute URL to access the primary view - of an entity - - * `rest_path()`, returns a relative REST URL to get the entity - - * `format(attr)`, returns the format (MIME type) of the field given un parameter - - * `printable_value(attr, value=_marker, attrtype=None, format='text/html')`, - returns a string enabling the display of an attribute value in a given format - (the value is automatically recovered if necessary) - - * `display_name(form='')`, returns a string to display the entity type by - specifying the preferred form (`plural` for a plural form) - -:Data handling: - - * `as_rset()`, converts the entity into an equivalent result set simulating the - request `Any X WHERE X eid _eid_` - - * `complete(skip_bytes=True)`, executes a request that recovers in one time - all the missing attributes of an entity - - * `get_value(name)`, returns the value associated to the attribute name given - in parameter - - * `related(rtype, x='subject', limit=None, entities=False)`, returns a list - of entities related to the current entity by the relation given in parameter - - * `unrelated(rtype, targettype, x='subject', limit=None)`, returns a result set - corresponding to the entities not related to the current entity by the - relation given in parameter and satisfying its constraints - - * `set_attributes(**kwargs)`, updates the attributes list with the corresponding - values given named parameters - - * `copy_relations(ceid)`, copies the relations of the entities having the eid - given in the parameters on the current entity - - * `last_modified(view)`, returns the date the object has been modified - (used by HTTP cache handling) - - * `delete()` allows to delete the entity - -:Standard meta-data (Dublin Core): - - * `dc_title()`, returns a unicode string corresponding to the meta-data - `Title` (used by default the first attribute non-meta of the entity - schema) - - * `dc_long_title()`, same as dc_title but can return a more - detailled title - - * `dc_description(format='text/plain')`, returns a unicode string - corresponding to the meta-data `Description` (look for a description - attribute by default) - - * `dc_authors()`, returns a unicode string corresponding to the meta-data - `Authors` (owners by default) - - * `dc_date(date_format=None)`, returns a unicode string corresponding to - the meta-data `Date` (update date by default) - -:Vocabulary control on relations: - - * `vocabulary(rtype, x='subject', limit=None)`, called by the - editing views, it returns a list of couples (label, eid) of entities - that could be related to the entity by the relation `rtype` - * `subject_relation_vocabulary(rtype, limit=None)`, called internally - by `vocabulary` in the case of a subject relation - * `object_relation_vocabulary(rtype, limit=None)`, called internally - by `vocabulary` in the case of an object relation - * `relation_vocabulary(rtype, targettype, x, limit=None)`, called - internally by `subject_relation_vocabulary` and `object_relation_vocabulary` - -Class `TreeMixIn` ------------------ - -This class provides a tree interface. This mixin has to be inherited -explicitly and configured using the tree_attribute, parent_target and -children_target class attribute to benefit from this default implementation. - -This class provides the following methods: - - * `different_type_children(entities=True)`, returns children entities - of different type as this entity. According to the `entities` parameter, - returns entity objects (if entity=True) or the equivalent result set. - - * `same_type_children(entities=True)`, returns children entities of - the same type as this entity. According to the `entities` parameter, - return entity objects (if entity=True) or the equivalent result set. - - * `iterchildren( _done=None)`, iters on the children of the entity. - - * `prefixiter( _done=None)` - - * `path()`, returns the list of eids from the root object to this object. - - * `iterparents()`, iters on the parents of the entity. - - * `notification_references(view)`, used to control References field - of email send on notification for this entity. `view` is the notification view. - Should return a list of eids which can be used to generate message ids - of previously sent email. - -`TreeMixIn` implements also the ITree interface (``cubicweb.interfaces``): - - * `parent()`, returns the parent entity if any, else None (e.g. if we are on the - root) - - * `children(entities=True, sametype=False)`, returns children entities - according to the `entities` parameter, return entity objects or the - equivalent result set. - - * `children_rql()`, returns the RQL query corresponding to the children - of the entity. - - * `is_leaf()`, returns True if the entity does not have any children. - - * `is_root()`, returns True if the entity does not have any parent. - - * `root()`, returns the root object of the tree representation of - the entity and its related entities. - -Example of use -`````````````` - -Imagine you defined three types of entities in your schema, and they -relates to each others as follows in ``schema.py``:: - - class Entity1(EntityType): - title = String() - is_related_to = SubjectRelation('Entity2', 'subject') - - class Entity2(EntityType): - title = String() - belongs_to = SubjectRelation('Entity3', 'subject') - - class Entity3(EntityType): - name = String() - -You would like to create a view that applies to both entity types -`Entity1` and `Entity2` and which lists the entities they are related to. -That means when you view `Entity1` you want to list all `Entity2`, and -when you view `Entity2` you want to list all `Entity3`. - -In ``entities.py``:: - - class Entity1(TreeMixIn, AnyEntity): - id = 'Entity1' - __implements__ = AnyEntity.__implements__ + (ITree,) - __rtags__ = {('is_related_to', 'Entity2', 'object'): 'link'} - tree_attribute = 'is_related_to' - - def children(self, entities=True): - return self.different_type_children(entities) - - class Entity2(TreeMixIn, AnyEntity): - id = 'Entity2' - __implements__ = AnyEntity.__implements__ + (ITree,) - __rtags__ = {('belongs_to', 'Entity3', 'object'): 'link'} - tree_attribute = 'belongs_to' - - def children(self, entities=True): - return self.different_type_children(entities) - -Once this is done, you can define your common view as follows:: - - class E1E2CommonView(baseviews.PrimaryView): - accepts = ('Entity11, 'Entity2') - - def render_entity_relations(self, entity, siderelations): - self.wview('list', entity.children(entities=False)) - - -*rtags* -------- - -*rtags* allow to specify certain behaviors of relations relative to a given -entity type (see later). They are defined on the entity class by the attribute -`rtags` which is a dictionary with as keys the triplets :: - - , , - -and as values a `set` or a tuple of markers defining the properties that -apply to this relation. - -It is possible to simplify this dictionary: - -* if we want to specifiy a single marker, it is not necessary to - use a tuple as value, the marker by itself (character string) - is enough -* if we only care about a single type of relation and not about the target - and the context position (or when this one is not ambigous), we can simply - use the name of the relation type as key -* if we want a marker to apply independently from the target entity type, - we have to use the string `*` as target entity type - - -Please note that this dictionary is *treated at the time the class is created*. -It is automatically merged with the parent class(es) (no need to copy the -dictionary from the parent class to modify it). Also, modifying it after the -class is created will not have any effect... - -.. include:: B0031-define-entities.en.txt - diff -r fd8751c3f3ee -r a721966779be doc/book/en/B0031-define-entities.en.txt --- a/doc/book/en/B0031-define-entities.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,178 +0,0 @@ -.. -*- coding: utf-8 -*- - -Parametrization and specific extensions ---------------------------------------- - -Dynamic default values -`````````````````````` -It is possible to define *static* default values in the schema. -It is also possible to define *dynamic* default values -by defining in the entity class a method `default_` for -a given attribute. - - -Loaded attributes and default sorting management -```````````````````````````````````````````````` - -* The class attribute `fetch_attrs` allows to defined in an entity class - a list of names of attributes or relations that should be automatically - loaded when we recover the entities of this type. In the case of relations, - we are limited to *subject of cardinality `?` or `1`* relations. - -* The class method `fetch_order(attr, var)` expects an attribute (or relation) - name as a parameter and a variable name, and it should return a string - to use in the requirement `ORDER BY` of an RQL query to automatically - sort the list of entities of such type according to this attribute, or - `None` if we do not want to sort on the attribute given in the parameter. - By default, the entities are sorted according to their creation date. - -* The class method `fetch_unrelated_order(attr, var)` is similar to the - method `fetch_order` except that it is essentially used to control - the sorting of drop-down lists enabling relations creation in - the editing view of an entity. - -The function `fetch_config(fetchattrs, mainattr=None)` simplifies the -definition of the attributes to load and the sorting by returning a -list of attributes to pre-load (considering automatically the attributes -of `AnyEntity`) and a sorting function based on the main attribute -(the second parameter if specified otherwisethe first attribute from -the list `fetchattrs`). -This function is defined in `cubicweb.entities`. - -For example: :: - - class Transition(AnyEntity): - """...""" - id = 'Transition' - fetch_attrs, fetch_order = fetch_config(['name']) - -Indicates that for the entity type "Transition", you have to pre-load -the attribute `name` and sort by default on this attribute. - - -Editing forms management -```````````````````````` -It is possible to manage attributes/relations in the simple or multiple -editing form thanks to the following *rtags*: - -* `primary`, indicates that an attribute or a relation has to be - inserted **in the simple or multiple editing forms**. In the case of - a relation, the related entity editing form will be included in the - editing form and represented as a combobox. Each item of the - combobox is a link to an existing entity. - -* `secondary`, indicates that an attribute or a relation has to be - inserted **in the simple editing form only**. In the case of a - relation, the related entity editing form will be included in the - editing form and represented as a combobox. Each item of the combobox - is a link to an existing entity. - -* `inlineview`, includes the target entity's form in the editing form - of the current entity. It allows to create the target entity in the - same time as the current entity. - -* `generic`, indicates that a relation has to be inserted in the simple - editing form, in the generic box of relation creation. - -* `generated`, indicates that an attribute is dynamically computed - or other, and that it should not be displayed in the editing form. - -If necessary, it is possible to overwrite the method -`relation_category(rtype, x='subject')` to dynamically compute -a relation editing category. - -``add_related`` box management -`````````````````````````````` - -The box ``add_related`` is an automatic box that allows to create -an entity automatically related to the initial entity (context in -which the box is displayed). By default, the links generated in this -box are computed from the schema properties of the displayed entity, -but it is possible to explicitely specify them thanks to the -following *rtags*: - -* `link`, indicates that a relation is in general created pointing - to an existing entity and that we should not to display a link - for this relation - -* `create`, indicates that a relation is in general created pointing - to new entities and that we should display a link to create a new - entity and link to it automatically - - -If necessary, it is possible to overwrite the method -`relation_mode(rtype, targettype, x='subject')` to dynamically -compute a relation creation category. - -Please note that if at least one action belongs to the `addrelated` category, -the automatic behavior is desactivated in favor of an explicit behavior -(e.g. display of `addrelated` category actions only). - - -Filtering table forms management -```````````````````````````````` - -By default, the view ``table`` manages automatically a filtering -form of its content. The algorithm is as follows: - -1. we consider that the first column contains the entities to constraint -2. we collect the first entity of the table (row 0) to represent all the - others -3. for all the other variables defined in the original request: - - 1. if the variable is related to the main variable by at least one relation - 2. we call the method ``filterform_vocabulary(rtype, x)`` on the entity, - if nothing is returned (meaning a tuple `Non`, see below), we go to the - next variable, otherwise a form filtering element is created based on - the vocabulary values returned - -4. there are no other limitations to the `RQL`, it can include sorting, grouping - conditions... JavaScript functions are used to regenerate a request based on the - initial request and on the selected values from the filtering form. - -The method ``filterform_vocabulary(rtype, x, var, rqlst, args, cachekey)`` takes -the name of a relation and the target as parameters, -[XXX what does it mean ?] -which indicates of the -entity on which we apply the method is subject or object of the relation. It -has to return: - -* a 2-uple of None if it does not know how to handle the relation - -* a type and a list containing the vocabulary - - * the list has to contain couples (value, label) - * the type indicates if the value designate an integer (`type == 'int'`), - a string (`type =='string'` or a non-final relation (`type == 'eid'`) - -For example in our application managing tickets, we want to be able to filter -them by : - -* type -* priority -* state (in_state) -* tag (tags) -* version (done_in) - -For that we define the following method: :: - - - class Ticket(AnyEntity): - - ... - - def filterform_vocabulary(self, rtype, x, var, rqlst, args, cachekey): - _ = self.req._ - if rtype == 'type': - return 'string', [(x, _(x)) for x in ('bug', 'story')] - if rtype == 'priority': - return 'string', [(x, _(x)) for x in ('minor', 'normal', 'important')] - if rtype == 'done_in': - rql = insert_attr_select_relation(rqlst, var, rtype, 'num') - return 'eid', self.req.execute(rql, args, cachekey) - return super(Ticket, self).filterform_vocabulary(rtype, x, var, rqlst, - args, cachekey) - -.. note:: - Filtering on state and tags is automatically installed, no need to handle it. - diff -r fd8751c3f3ee -r a721966779be doc/book/en/B0040-migration.en.txt --- a/doc/book/en/B0040-migration.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,213 +0,0 @@ -.. -*- coding: utf-8 -*- - -.. _migration: - -Migration -========= - -One of the main concept in `CubicWeb` is to create incremental applications. -For this purpose, multiple actions are provided to facilitate the improvement -of an application, and in particular to handle the changes to be applied -to the data model, without loosing existing data. - -The current version of an application model is provided in the file -`__pkginfo__.py` as a tuple of 3 integers. - -Migration scripts management ----------------------------- - -Migration scripts has to be located in the directory `migration` of your -application and named accordingly: - -:: - - [_]_.py - -in which : - -* X.Y.Z is the model version number to which the script enables to migrate. - -* *mode* (between the last "_" and the extension ".py") is used for - distributed installation. It indicates to which part - of the application (RQL server, web server) the script applies. - Its value could be : - - * `common`, applies to the RQL server as well as the web server and updates - files on the hard drive (configuration files migration for example). - - * `web`, applies only to the web server and updates files on the hard drive. - - * `repository`, applies only to the RQL server and updates files on the - hard drive. - - * `Any`, applies only to the RQL server and updates data in the database - (schema and data migration for example). - -Again in the directory `migration`, the file `depends.map` allows to indicate -that for the migration to a particular model version, you always have to first -migrate to a particular `CubicWeb` version. This file can contain comments (lines -starting by `#`) and a dependancy is listed as follows: :: - - : - -For example: :: - - 0.12.0: 2.26.0 - 0.13.0: 2.27.0 - # 0.14 works with 2.27 <= cubicweb <= 2.28 at least - 0.15.0: 2.28.0 - -Base context ------------- - -The following identifiers are pre-defined in migration scripts: - -* `config`, instance configuration - -* `interactive_mode`, boolean indicating that the script is executed in - an interactive mode or not - -* `appltemplversion`, application model version of the instance - -* `templversion`, installed application model version - -* `cubicwebversion`, installed cubicweb version - -* `confirm(question)`, function asking the user and returning true - if the user answers yes, false otherwise (always returns true in - non-interactive mode) - -* the function `_`, it is equivalent to `unicode` allowing to flag the strings - to internationalize in the migration scripts. - -In the `repository` scripts, the following identifiers are also defined: - -* `checkpoint`, request confirming and executing a "commit" at checking point - -* `repo_schema`, instance persisting schema (e.g. instance schema of the - current migration) - -* `newschema`, installed schema on the file system (e.g. schema of - the updated model and cubicweb) - -* `sqlcursor`, SQL cursor for very rare cases where it is really - necessary or beneficial to go through the sql - -* `repo`, repository object - - -Schema migration ----------------- -The following functions for schema migration are available in `repository` -scripts: - -* `add_attribute(etype, attrname, attrtype=None, commit=True)`, adds a new - attribute to an existing entity type. If the attribute type is not specified, - then it is extracted from the updated schema. - -* `drop_attribute(etype, attrname, commit=True)`, removes an attribute from an - existing entity type. - -* `rename_attribute(etype, oldname, newname, commit=True)`, renames an attribute - -* `add_entity_type(etype, auto=True, commit=True)`, adds a new entity type. - If `auto` is True, all the relations using this entity type and having a known - entity type on the other hand will automatically be added. - -* `drop_entity_type(etype, commit=True)`, removes an entity type and all the - relations using it. - -* `rename_entity_type(oldname, newname, commit=True)`, renames an entity type - -* `add_relation_type(rtype, addrdef=True, commit=True)`, adds a new relation - type. If `addrdef` is True, all the relations definitions of this type will - be added. - -* `drop_relation_type(rtype, commit=True)`, removes a relation type and all the - definitions of this type. - -* `rename_relation(oldname, newname, commit=True)`, renames a relation. - -* `add_relation_definition(subjtype, rtype, objtype, commit=True)`, adds a new - relation definition. - -* `drop_relation_definition(subjtype, rtype, objtype, commit=True)`, removes - a relation definition. - -* `synchronize_permissions(ertype, commit=True)`, synchronizes permissions on - an entity type or relation type. - -* `synchronize_rschema(rtype, commit=True)`, synchronizes properties and permissions - on a relation type. - -* `synchronize_eschema(etype, commit=True)`, synchronizes properties and persmissions - on an entity type. - -* `synchronize_schema(commit=True)`, synchronizes the persisting schema with the - updated schema (but without adding or removing new entity types, relations types - or even relations definitions). - -* `change_relation_props(subjtype, rtype, objtype, commit=True, **kwargs)`, changes - properties of a relation definition by using the named parameters of the properties - to change. - -* `set_widget(etype, rtype, widget, commit=True)`, changes the widget used for the - relation of entity type . - -* `set_size_constraint(etype, rtype, size, commit=True)`, changes the size constraints - for the relation of entity type . - -Data migration --------------- -The following functions for data migration are available in `repository` scripts: - -* `rql(rql, kwargs=None, cachekey=None, ask_confirm=True)`, executes an arbitrary RQL - query, either to interrogate or update. A result set object is returned. - -* `add_entity(etype, *args, **kwargs)`, adds a nes entity type of the given - type. The attribute and relation values are specified using the named and - positionned parameters. - -Workflow creation ------------------ - -The following functions for workflow creation are available in `repository` -scripts: - -* `add_state(name, stateof, initial=False, commit=False, **kwargs)`, adds a new state - in the workflow. - -* `add_transition(name, transitionof, fromstates, tostate, requiredgroups=(), commit=False, **kwargs)`, - adds a new transition in the workflow. - -You can find more details about workflows in the chapter :ref:`Workflow` . - -Configuration migration ------------------------ - -The following functions for configuration migration are available in all -scripts: - -* `option_renamed(oldname, newname)`, indicates that an option has been renamed - -* `option_group_change(option, oldgroup, newgroup)`, indicates that an option does not - belong anymore to the same group. - -* `option_added(oldname, newname)`, indicates that an option has been added. - -* `option_removed(oldname, newname)`, indicates that an option has been deleted. - - -Others migration functions --------------------------- -Those functions are only used for low level operations that could not be -accomplished otherwise or to repair damaged databases during interactive -session. They are available in `repository` scripts: - -* `sqlexec(sql, args=None, ask_confirm=True)`, executes an arbitrary SQL query -* `add_entity_type_table(etype, commit=True)` -* `add_relation_type_table(rtype, commit=True)` -* `uninline_relation(rtype, commit=True)` - - -[FIXME] Add explanation on how to use cubicweb-ctl shell diff -r fd8751c3f3ee -r a721966779be doc/book/en/B081-i18n.en.txt --- a/doc/book/en/B081-i18n.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,71 +0,0 @@ -.. -*- coding: utf-8 -*- - -.. _Internationalisation: - - -Internationalisation -==================== - -Le système d'internationalisation de l'interface web de CubicWeb est basé sur le -système `GNU gettext`_. - -.. _`GNU gettext`: http://www.gnu.org/software/gettext/ - -Messages à internationaliser ----------------------------- - -Marquage des messages à internaliser -```````````````````````````````````` -Les chaines de caractères à internationaliser sont marqués par l'appel à la -fonction `_` *OU* par la méthode équivalent de la requête dans le code python ou -dans les expressions python de template TAL. - -Dans les templates cubicweb-tal, il est également possible d'insérer une chaine à -traduire via les balises `i18n:content` et `i18n:replace`. - -De plus des messages correspondant aux entités/relations utilisés par le schéma -de l'application seront automatiquement ajoutés. - -Renvoi d'un message internationalisé lors de la construction d'une page -``````````````````````````````````````````````````````````````````````` -La fonction *built-in* `_` ne doit servir qu'**à marquer les messages à -traduire**, non pas à récupérer une traduction. Il faut pour cela utiliser la -méthode `_` de l'objet requête, sans quoi vous récupérerez l'identifiant de -message au lieu de sa traduction dans la langue propre à la requête.1 - - -Gestion des catalogues de traduction ------------------------------------- -Une fois l'application rendu internationalisable coté code, reste à gérer les -catalogues de traductions. cubicweb-ctl intègre pour cela les commandes suivantes : - -* `i18nlibupdate`, met à jour les catalogues de messages *de la librairie - cubicweb*. Sauf si vous développez sur le framework (et non votre propre - application), vous ne devriez pas avoir à utiliser cette commande - -* `i18nupdate`, met à jour les catalogues de messages *du composant* (ou de tous - les composants). A la suite de cette commande, vous devez mettre à jour les - fichiers de traduction *.po* dans le sous-répertoire "i18n" de votre - template. Évidemment les traductions précédentes toujours utilisées ont été - conservées. - -* `i18ncompile`, recompile les catalogues de messages *d'une instance* (ou de - toutes les instances) après mise à jour des catalogues de son composant. Cela - est effectué automatiquement lors d'une création ou d'une mise à jour. Les - catalogues de messages compilés se trouvent dans le répertoire - "i18n//LC_MESSAGES/cubicweb.mo" de l'application où `lang` est - l'identifiant de la langue sur 2 lettres ('en' ou 'fr' par exemple) - - -Le cas classique -```````````````` -Vous avez ajouté et/ou modifié des messages d'un composant utilisé par votre -application (en ajoutant une nouvelle vue ou en ayant modifié le schéma par -exemple) : - -1. `cubicweb-ctl i18nupdate ` -2. éditer les fichiers /xxx.po dans pour y rajouter les traductions - manquantes (`msgstr` vide) -3. `hg ci -m "updated i18n catalogs"` -4. `cubicweb-ctl i18n compile ` - diff -r fd8751c3f3ee -r a721966779be doc/book/en/B1-web-interface.en.txt --- a/doc/book/en/B1-web-interface.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,20 +0,0 @@ -.. -*- coding: utf-8 -*- - -Web interface -+++++++++++++ -.. toctree:: - :maxdepth: 1 - - B1010-request.en.txt - B1020-define-views.en.txt - B1030-form-management.en.txt - B1040-actions.en.txt - B1050-boxes.en.txt - B1060-templates.en.txt - B1070-ui-components.en.txt - B1080-ajax-json.en.txt - B1090-internationalization.en.txt - B1100-online-doc.en.txt - B1110-embedding-external-page.en.txt - B1120-urlrewrite.en.txt - B1130-css.en.txt diff -r fd8751c3f3ee -r a721966779be doc/book/en/B1010-request.en.txt --- a/doc/book/en/B1010-request.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ -.. -*- coding: utf-8 -*- - -Request -======= - -[WRITE ME] - -* the request object - diff -r fd8751c3f3ee -r a721966779be doc/book/en/B1020-define-views.en.txt --- a/doc/book/en/B1020-define-views.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,414 +0,0 @@ -.. -*- coding: utf-8 -*- - -.. _ViewDefinition: - -Views definition -================ - -This chapter aims to describe the concept of a `view` used all along -the development of a web application and how it has been implemented -in `CubicWeb`. - -We'll start with a description of the interface providing you with a basic -understanding of the classes and methods available, then detail the view -selection principle which makes `CubicWeb` web interface very flexible. - -A `View` is an object applied to another object such as an entity. - -Basic class for views ---------------------- - -Class `View` (`cubicweb.common.view`) -````````````````````````````````````` - -This class is an abstraction of a view class, used as a base class for every -renderable object such as views, templates, graphic components, etc. - -A `View` is instantiated to render a result set or part of a result set. `View` -subclasses may be parametrized using the following class attributes: - - * `templatable` indicates if the view may be embeded in a main - template or if it has to be rendered standalone (i.e. XML views - must not be embeded in the main template for HTML pages) - * if the view is not templatable, it should set the `content_type` class - attribute to the correct MIME type (text/xhtml by default) - * the `category` attribute may be used in the interface to regroup related - objects together - -At instantiation time, the standard `req`, `rset`, and `cursor` -attributes are added and the `w` attribute will be set at rendering -time. - -A view writes to its output stream thanks to its attribute `w` (`UStreamIO`). - -The basic interface for views is as follows (remember that the result set has a -tabular structure with rows and columns, hence cells): - -* `dispatch(**context)`, render the view by calling `call` or - `cell_call` depending on the given parameters -* `call(**kwargs)`, call the view for a complete result set or null (default - implementation calls `cell_call()` on each cell of the result set) -* `cell_call(row, col, **kwargs)`, call the view for a given cell of a result set -* `url()`, returns the URL enabling us to get the view with the current - result set -* `view(__vid, rset, __fallback_vid=None, **kwargs)`, call the view of identifier - `__vid` on the given result set. It is possible to give a view identifier - of fallback that will be used if the view requested is not applicable to the - result set - -* `wview(__vid, rset, __fallback_vid=None, **kwargs)`, similar to `view` except - the flow is automatically passed in the parameters - -* `html_headers()`, returns a list of HTML headers to set by the main template - -* `page_title()`, returns the title to use in the HTML header `title` - - -Other basic view classes -```````````````````````` -Here are some of the subclasses of `View` defined in `cubicweb.common.view` -that are more concrete as they relate to data rendering within the application: - -* `EntityView`, view applying to lines or cell containing an entity (e.g. an eid) -* `StartupView`, start view that does not require a result set to apply to -* `AnyRsetView`, view applied to any result set -* `EmptyRsetView`, view applied to an empty result set - - -The selection view principle ----------------------------- - -A view is essentially defined by: - -- an identifier (all objects in `CubicWeb` are entered in a registry - and this identifier will be used as a key). This is defined in the class - attribute ``id``. - -- a filter to select the result sets it can be applied to. This is defined in - the class attribute ``__selectors__``, which expects a tuple of selectors - as its value. - - -For a given identifier, multiple views can be defined. `CubicWeb` uses -a selector which computes scores to identify and select the -best view to apply in the given context. The selectors library is in -``cubicweb.common.selector`` and a library of the methods used to -compute scores is in ``cubicweb.vregistry.vreq``. - -.. include:: B1021-views-selectors.en.txt - -Registerer -`````````` -[Registerers are deprecated: they will soon disappear for explicite -registration...] - -A view is also customizable through its attribute ``__registerer__``. -This is used at the time the application is launched to manage how -objects (views, graphic components, actions, etc.) -are registered in the `cubicWeb` registry. - -A `registerer` can, for example, identify when we register an -object that is equivalent to an already registered object, which -could happen when we define two `primary` views for an entity type. - -The purpose of a `registerer` is to control object registry -at the application startup whereas `selectors` control objects -when they are selected for display. - - -.. include:: B1022-views-stdlib.en.txt - - -Examples of views class ------------------------ - -- Using the attribute `templatable` - - :: - - - class RssView(XmlView): - id = 'rss' - title = _('rss') - templatable = False - content_type = 'text/xml' - http_cache_manager = MaxAgeHTTPCacheManager - cache_max_age = 60*60*2 # stay in http cache for 2 hours by default - - - -- Using the attribute `__selectors__` - - :: - - - class SearchForAssociationView(EntityView): - """view called by the edition view when the user asks - to search for something to link to the edited eid - """ - id = 'search-associate' - title = _('search for association') - __selectors__ = (one_line_rset, match_search_state, accept_selector) - accepts = ('Any',) - search_states = ('linksearch',) - - -Rendering methods and attributes for ``PrimaryView`` ----------------------------------------------------- - -By default, `CubicWeb` provides a primary view for each new entity type -you create. The first view you might be interested in modifying. - -Let's have a quick look at the EntityView ``PrimaryView`` as well as -its rendering method:: - - class PrimaryView(EntityView): - """the full view of an non final entity""" - id = 'primary' - title = _('primary') - show_attr_label = True - show_rel_label = True - skip_none = True - skip_attrs = ('eid', 'creation_date', 'modification_date') - skip_rels = () - main_related_section = True - - ... - - def cell_call(self, row, col): - self.row = row - self.render_entity(self.complete_entity(row, col)) - - def render_entity(self, entity): - """return html to display the given entity""" - siderelations = [] - self.render_entity_title(entity) - self.render_entity_metadata(entity) - # entity's attributes and relations, excluding meta data - # if the entity isn't meta itself - self.w(u'
') - self.w(u'
') - self.render_entity_attributes(entity, siderelations) - self.w(u'
') - self.content_navigation_components('navcontenttop') - if self.main_related_section: - self.render_entity_relations(entity, siderelations) - self.w(u'
') - # side boxes - self.w(u'
') - self.render_side_related(entity, siderelations) - self.w(u'
') - self.w(u'
') - self.content_navigation_components('navcontentbottom') - - ... - -``cell_call`` is executed for each entity of a result set and apply ``render_entity``. - -The methods you want to modify while customizing a ``PrimaryView`` are: - -*render_entity_title(self, entity)* - Renders the entity title based on the assumption that the method - ``def content_title(self)`` is implemented for the given entity type. - -*render_entity_metadata(self, entity)* - Renders the entity metadata based on the assumption that the method - ``def summary(self)`` is implemented for the given entity type. - -*render_entity_attributes(self, entity, siderelations)* - Renders all the attribute of an entity with the exception of attribute - of type `Password` and `Bytes`. - -*content_navigation_components(self, context)* - This method is applicable only for entity type implementing the interface - `IPrevNext`. This interface is for entities which can be linked to a previous - and/or next entity. This methods will render the navigation links between - entities of this type, either at the top or at the bottom of the page - given the context (navcontent{top|bottom}). - -*render_entity_relations(self, entity, siderelations)* - Renders all the relations of the entity in the main section of the page. - -*render_side_related(self, entity, siderelations)* - Renders all the relations of the entity in a side box. This is equivalent - to *render_entity_relations* in addition to render the relations - in a box. - -Also, please note that by setting the following attributes in you class, -you can already customize some of the rendering: - -*show_attr_label* - Renders the attribute label next to the attribute value if set to True. - Otherwise, does only display the attribute value. - -*show_rel_label* - Renders the relation label next to the relation value if set to True. - Otherwise, does only display the relation value. - -*skip_none* - Does not render an attribute value that is None if set to True. - -*skip_attrs* - Given a list of attributes name, does not render the value of the attributes listed. - -*skip_rels* - Given a list of relations name, does not render the relations listed. - -*main_related_section* - Renders the relations of the entity if set to True. - -A good practice is for you to identify the content of your entity type for which -the default rendering does not answer your need so that you can focus on the specific -method (from the list above) that needs to be modified. We do not recommand you to -overwrite ``render_entity`` as you might potentially loose the benefits of the side -boxes handling. - -Example of a view customization -------------------------------- - -[FIXME] XXX Example needs to be rewritten as it shows how to modify cell_call which -contredicts our advise of not modifying it. - -We'll show you now an example of a ``primary`` view and how to customize it. - -If you want to change the way a ``BlogEntry`` is displayed, just override -the method ``cell_call()`` of the view ``primary`` in ``BlogDemo/views.py`` :: - - 01. from cubicweb.web.views import baseviews - 02. - 03. class BlogEntryPrimaryView(baseviews.PrimaryView): - 04. - 05. accepts = ('BlogEntry',) - 06. - 07. def cell_call(self, row, col): - 08. entity = self.entity(row, col) - 09. self.w(u'

%s

' % entity.title) - 10. self.w(u'

published on %s in category %s

' % \ - 11. (entity.publish_date.strftime('%Y-%m-%d'), entity.category)) - 12. self.w(u'

%s

' % entity.text) - -The above source code defines a new primary view (`line 03`) for -``BlogEntry`` (`line 05`). - -Since views are applied to result sets which can be tables of -data, we have to recover the entity from its (row,col)-coordinates (`line 08`). -We will get to this in more detail later. - -The view method ``self.w()`` is used to output data. Here `lines -09-12` output HTML tags and values of the entity's attributes. - -When displaying the same blog entry as before, you will notice that the -page is now looking much nicer. [FIXME: it is not clear to what this refers.] - -.. image:: images/lax-book.09-new-view-blogentry.en.png - :alt: blog entries now look much nicer - -Let us now improve the primary view of a blog :: - - 01. class BlogPrimaryView(baseviews.PrimaryView): - 02. - 03. accepts = ('Blog',) - 04. - 05. def cell_call(self, row, col): - 06. entity = self.entity(row, col) - 07. self.w(u'

%s

' % entity.title) - 08. self.w(u'

%s

' % entity.description) - 09. rset = self.req.execute('Any E WHERE E entry_of B, B eid "%s"' % entity.eid) - 10. self.wview('primary', rset) - -In the above source code, `lines 01-08` are similar to the previous -view we defined. [FIXME: defined where ?] - -At `line 09`, a simple request is made to build a result set with all -the entities linked to the current ``Blog`` entity by the relationship -``entry_of``. The part of the framework handling the request knows -about the schema and infer that such entities have to be of the -``BlogEntry`` kind and retrieves them. - -The request returns a selection of data called a result set. At -`line 10` the view 'primary' is applied to this result set to output -HTML. - -**This is to be compared to interfaces and protocols in object-oriented -languages. Applying a given view called 'a_view' to all the entities -of a result set only requires to have for each entity of this result set, -an available view called 'a_view' which accepts the entity.** - -Assuming we added entries to the blog titled `MyLife`, displaying it -now allows to read its description and all its entries. - -.. image:: images/lax-book.10-blog-with-two-entries.en.png - :alt: a blog and all its entries - -**Before we move forward, remember that the selection/view principle is -at the core of `CubicWeb`. Everywhere in the engine, data is requested -using the RQL language, then HTML/XML/text/PNG is output by applying a -view to the result set returned by the query. That is where most of the -flexibility comes from.** - -[WRITE ME] - -* implementing interfaces, calendar for blog entries -* show that a calendar view can export data to ical - -We will implement the `cubicweb.interfaces.ICalendarable` interfaces on -entities.BlogEntry and apply the OneMonthCalendar and iCalendar views -to result sets like "Any E WHERE E is BlogEntry" - -* create view "blogentry table" with title, publish_date, category - -We will show that by default the view that displays -"Any E,D,C WHERE E publish_date D, E category C" is the table view. -Of course, the same can be obtained by calling -self.wview('table',rset) - -* in view blog, select blogentries and apply view "blogentry table" -* demo ajax by filtering blogentry table on category - -we did the same with 'primary', but with tables we can turn on filters -and show that ajax comes for free. -[FILLME] - - -Templates ---------- - -*Templates* are specific views that do not depend on a result set. The basic -class `Template` (`cubicweb.common.view`) is derived from the class `View`. - -To build a HTML page, a *main template* is used. In general, the template of -identifier `main` is the one to use (it is not used in case an error is raised or for -the login form for example). This template uses other templates in addition -to the views which depends on the content to generate the HTML page to return. - -A *template* is responsible for: - -1. executing RQL query of data to render if necessary -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`. - -XML views, binaries... ----------------------- -For views generating other formats than HTML (an image generated dynamically -for example), and which can not simply be included in the HTML page generated -by the main template (see above), you have to: - -* set the attribute `templatable` of the class to `False` -* set, through the attribute `content_type` of the class, the MIME type generated - by the view to `application/octet-stream` - -For views dedicated to binary content creation (like dynamically generated -images), we have to set the attribute `binary` of the class to `True` (which -implies that `templatable == False`, so that the attribute `w` of the view could be -replaced by a binary flow instead of unicode). - -(X)HTML tricks to apply ------------------------ - -Some web browser (Firefox for example) are not happy with empty `
` -(by empty we mean that there is no content in the tag, but there -could be attributes), so we should always use `
` even if -it is empty and not use `
`. - diff -r fd8751c3f3ee -r a721966779be doc/book/en/B1021-views-selectors.en.txt --- a/doc/book/en/B1021-views-selectors.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -.. -*- coding: utf-8 -*- - -Selectors -````````` - -Selectors are scoring functions that are called by the view -dispatcher to tell whenever a view can be applied to a given result -set of a request. Selector sets are the glue that tie views to the data -model. Using them appropriately is an essential part of the -construction of well behaved cubes. - -When no score is higher than the others, an exception is raised -``NoSelectableObject`` to let you know that the engine was not able to -identify the view to apply. In such case you would need to review your -design and make sure your views are properly defined. - -`CubicWeb` provides its own set of selectors that you can use and here -is a description of some of the most common used: - -*yes* - This selector accepts everything which basically means to any result - set. - -*none_rset* - This selector accepts no result set, so it can be applied to any - object. - -*rset* - This selector accepts any result set, whatever the number of objects - in the result set. - -*nonempty_rset* - This selector accepts any non empty result set. - -*empty_rset* - This selector accepts empty (only) result set. - -*one_line_rset* - This selector accepts result set with a single line of result. - -*two_lines_rset* - This selector accepts result set with *at least* two lines of result. - -*two_cols_rset* - This selector accepts result set with *at least* one line and two columns of result. - -*anonymous_user* - This selector accepts if user is anonymous. - -*authenticated_user* - This selector accepts if user is authenticated. - - -Of course you will write your own set of selectors as you get familiar with the -framework. - diff -r fd8751c3f3ee -r a721966779be doc/book/en/B1022-views-stdlib.en.txt --- a/doc/book/en/B1022-views-stdlib.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,93 +0,0 @@ -.. -*- coding: utf-8 -*- - -Predefined views in the library -``````````````````````````````` - -`CubicWeb` provides a lot of standard views. You can find them in -``cubicweb/web/views/``. - -A certain number of views are used to build the web interface, which apply -to one or more entities. Their identifier is what distinguish them from -each others and the main ones are: - -*primary* - Primary view of an entity, this is the view called by default when a single - non final entity is in the result set and needs to be displayed. - This view is supposed to render a maximum of informations about the entity. - -*text* - This is the simplest text view for an entity. It displays the - title of an entity. It should not contain HTML. - -*oneline* - This is a hyper linked *text* view. Similar to the `secondary` view, - but called when we want the view to stand on a single line, or just - get a brief view. By default this view uses the - parameter `MAX_LINE_CHAR` to control the result size. - -*secondary* - This is a combinaison of an icon and a *oneline* view. - By default it renders the two first attributes of the entity as a - clickable link redirecting to the primary view. - -*incontext, outofcontext* - Similar to the `secondary` view, but called when an entity is considered - as in or out of context. By default it respectively returns the result of - `textincontext` and `textoutofcontext` wrapped in a link leading to - the primary view of the entity. - -*textincontext, textoutofcontext* - Similar to the `text` view, but called when an entity is considered out or - in context. By default it returns respectively the result of the - methods `.dc_title` and `.dc_long_title` of the entity. - -*list* - This view displays a list of entities by creating a HTML list (`
    `) - and call the view `listitem` for each entity of the result set. - -*listitem* - This view redirects by default to the `outofcontext` view. - -*rss* - Creates a RSS/XML view and call the view `rssitem` for each entity of - the result set. - -*rssitem* - Create a RSS/XML view for each entity based on the results of the dublin core - methods of the entity (`dc_*`) - -*sidebox* - This view displays usually a side box of some related entities - in a primary view. - - -Start view (e.g. views that don't apply to a result set): - -*index* - This view defines the home page of your application. It does not require - a result set to apply to. - -*schema* - A view dedicated to the display of the schema of the application - -Special views: - -*noresult* - This view is the default view used when no result has been found - (e.g. empty result set). - -*final* - Display the value of a cell without trasnformation (in case of a non final - entity, we see the eid). Applicable on any result set. - -*table* - Creates a HTML table (``) and call the view `cell` for each cell of - the result set. Applicable on any result set. - -*cell* - By default redirects to the `final` view if this is a final entity or - `outofcontext` view otherwise - -*null* - This view is the default view used when nothing needs to be rendered. - It is always applicable and it does not return anything diff -r fd8751c3f3ee -r a721966779be doc/book/en/B1030-form-management.en.txt --- a/doc/book/en/B1030-form-management.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,137 +0,0 @@ -.. -*- coding: utf-8 -*- - -Forms handling -============== - -Automatically generated forms management for handled entities -------------------------------------------------------------- - -XXX FILLME - -* forms ``edition`` and ``creation`` - -The form generated by default does not fit your needs? You are not -required to re-do all by hands! :) - -* rtags primary, secondary, generated, generic, - `Entity.relation_category(rtype, x='subject')` -* inline_view (now a rtag?) -* widget specification - -Editing controller behavior by default (id: `edit`) ---------------------------------------------------- - -Editing control -``````````````` - -Re-requisites: the parameters related to entities to edit are -specified as follows :: - - : - -where entity eid could be a letter in case of an entity to create. We -name those parameters as *qualified*. - -1. Retrieval of entities to edit by looking for the forms parameters - starting by `eid:` and also having a parameter `__type` associated - (also *qualified* by eid) - -2. For all the attributes and the relations of an entity to edit: - - 1. search for a parameter `edits-` or `edito-` - qualified in the case of a relation where the entity is object - 2. if found, the value returned is considered as the initial value - for this relaiton and we then look for the new value(s) in the parameter - (qualified) - 3. if the value returned is different from the initial value, an database update - request is done - -3. For each entity to edit: - - 1. if a qualified parameter `__linkto` is specified, its value has to be - a string (or a list of string) such as: :: - - :: - - where is either `subject` or `object` and each eid could be - separated from the others by a `_`. Target specifies if the *edited entity* - is subject or object of the relation and each relation specified will - be inserted. - - 2. if a qualified parameter `__clone_eid` is specified for an entity, the - relations of the specified entity passed as value of this parameter are - copied on the edited entity. - - 3. if a qualified parameter `__delete` is specified, its value must be - a string or a list of string such as follows: :: - - :: - - where each eid subject or object can be seperated from the other - by `_`. Each relation specified will be deleted. - - 4. if a qualified parameter `__insert` is specified, its value should - follow the same pattern as `__delete`, but each relation specified is - inserted. - -4. If the parameters `__insert` and/or `__delete` are found not qualified, - they are interpreted as explained above (independantly from the number - of entities edited). - -5. If no entity is edited but the form contains the parameters `__linkto` - and `eid`, this one is interpreted by using the value specified for `eid` - to designate the entity on which to add the relations. - - -.. note:: - - * If the parameter `__action_delete` is found, all the entities specified - as to be edited will be deleted. - - * If the parameter`__action_cancel` is found, no action is completed. - - * If the parameter `__action_apply` is found, the editing is applied - normally but the redirection is done on the form - (see :ref:`RedirectionControl`). - - * The parameter `__method` is also supported as for the main template - (XXX not very consistent, maybe __method should be dealed in the view - controller). - - * If no entity is found to be edited and if there is no parameter - `__action_delete`, `__action_cancel`, `__linkto`, `__delete` or - `__insert`, an error is raised. - - * Using the parameter `__message` in the form will allow to use its value - as a message to provide the user once the editing is completed. - - -.. _RedirectionControl: - -Redirection control -``````````````````` -Once editing is completed, there is still an issue left: where should we go -now? If nothing is specified, the controller will do his job but it does not -mean we will be happy with the result. We can control that by using the -following parameters: - -* `__redirectpath`: path of the URL (relative to the root URL of the site, - no form parameters - -* `__redirectparams`: forms parameters to add to the path - -* `__redirectrql`: redirection RQL request - -* `__redirectvid`: redirection view identifier - -* `__errorurl`: initial form URL, used for redirecting in case a validation - error is raised during editing. If this one is not specified, an error page - is displayed instead of going back to the form (which is, if necessary, - responsible for displaying the errors) - -* `__form_id`: initial view form identifier, used if `__action_apply` is - found - -In general we use either `__redirectpath` and `__redirectparams` or -`__redirectrql` and `__redirectvid`. - diff -r fd8751c3f3ee -r a721966779be doc/book/en/B1040-actions.en.txt --- a/doc/book/en/B1040-actions.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ -.. -*- coding: utf-8 -*- - -Actions -========= - -[WRITE ME] - -* talk about actions that appear in the action box - diff -r fd8751c3f3ee -r a721966779be doc/book/en/B1050-boxes.en.txt --- a/doc/book/en/B1050-boxes.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ -.. -*- coding: utf-8 -*- - -Boxes -========= - -[WRITE ME] - -* boxes in the web interface - diff -r fd8751c3f3ee -r a721966779be doc/book/en/B1060-templates.en.txt --- a/doc/book/en/B1060-templates.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,215 +0,0 @@ -.. -*- coding: utf-8 -*- - -.. _templates: - -Templates -========= - -[WRITE ME] - -* talk about main templates, etc. - - - -Look at ``cubicweb/web/views/basetemplates.py`` and you will -find the base templates used to generate HTML for your application. - -A page is composed as indicated on the schema below : - -.. image:: images/lax-book.06-main-template-layout.en.png - -In this section we will go through a couple of the primary templates -you must be interested in, that is to say, the HTMLPageHeader, -the HTMLPageFooter and the TheMainTemplate. - - -HTMLPageHeader --------------- - -Customize header -~~~~~~~~~~~~~~~~ - -Let's now move the search box in the header and remove the login form -from the header. We'll show how to move it to the left column of the application. - -Let's say we do not want anymore the login menu to be in the header, but we -prefer it to be in the left column just below the logo. As the left column is -rendered by ``TheMainTemplate``, we will show how to do it in TheMainTemplate_. - -First, to remove the login menu, we just need to comment out the display of the -login component such as follows : :: - - class MyHTMLPageHeader(HTMLPageHeader): - - def main_header(self, view): - """build the top menu with authentification info and the rql box""" - self.w(u'
    \n') - self.w(u'\n') - # appliname and breadcrumbs - self.w(u'') - # logged user and help - #self.w(u'') - # lastcolumn - self.w(u'\n') - self.w(u'\n') - self.template('logform', rset=self.rset, id='popupLoginBox', klass='hidden', - title=False, message=False) - - - -.. image:: images/lax-book.06-header-no-login.en.png - -Let's now move the search box in the top-right header area. To do so, we will -first create a method to get the search box display and insert it in the header -table. - -:: - - from cubicweb.web.views.basetemplates import HTMLPageHeader - class MyHTMLPageHeader(HTMLPageHeader): - def main_header(self, view): - """build the top menu with authentification info and the rql box""" - self.w(u'\n') - self.w(u'\n') - # appliname and breadcrumbs - self.w(u'') - - # logged user and help - #self.w(u'') - - self.w(u'') - # lastcolumn - self.w(u'\n') - self.w(u'\n') - self.template('logform', rset=self.rset, id='popupLoginBox', klass='hidden', - title=False, message=False) - - def get_searchbox(self, view, context): - boxes = list(self.vreg.possible_vobjects('boxes', self.req, self.rset, - view=view, context=context)) - if boxes: - for box in boxes: - if box.id == 'search_box': - box.dispatch(w=self.w, view=view) - - - - -HTMLPageFooter --------------- - -If you want to change the footer for example, look -for HTMLPageFooter and override it in your views file as in : -:: - - form cubicweb.web.views.basetemplates import HTMLPageFooter - class MyHTMLPageFooter(HTMLPageFooter): - def call(self, **kwargs): - self.w(u'') - -Updating a view does not require any restart of the server. By reloading -the page you can see your new page footer. - - -TheMainTemplate ---------------- -.. _TheMainTemplate: - -TheMainTemplate is responsible for the general layout of the entire application. -It defines the template of ``id = main`` that is used by the application. - -The default main template (`cubicweb.web.views.basetemplates.TheMainTemplate`) -builds the page based on the following pattern: - -.. image:: images/main_template_layout.png - -The rectangle containing `view.dispatch()` represents the area where the content -view has to be displayed. The others represents sub-templates called to complete -the page. A default implementation of those is provided in -`cubicweb.views.basetemplates`. You can, of course, overload those sub-templates -to implement your own customization of the HTML page. - -We can also control certain aspects of the main template thanks to the following -forms parameters: - -* `__notemplate`, if present (whatever the value assigned), only the content view - is returned -* `__force_display`, if present and its value is not null, no navigation - whatever the number of entities to display -* `__method`, if the result set to render contains only one entity and this - parameter is set, it refers to a method to call on the entity by passing it - the dictionary of the forms parameters, before going the classic way (through - step 1 and 2 described juste above) - -The MainTemplate is a bit complex as it tries to accomodate many -different cases. We are now about to go through it and cutomize entirely -our application. - - -CSS changes ------------ - -We cannot modify the order in which the application is reading the CSS. In -the case we want to create new CSS style, the best is to define it a in a new -CSS located under ``myapp/data/``. - - -.. [TRANSLATE ME FROM FRENCH] -.. 03-XX-external_resources.fr.txt - -[TODO] -Add login menu in left column - - -[WRITE ME] - -* customize MainTemplate and show that everything in the user - interface can be changed - -[TODO] -Rajouter une section pour definir la terminologie utilisee. -Dans cubicweb-doc rajouter une section pour cubciweb-ctl shell ou -on liste les commandes dispos. diff -r fd8751c3f3ee -r a721966779be doc/book/en/B1070-ui-components.en.txt --- a/doc/book/en/B1070-ui-components.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -Others web interface components -=============================== - -Actions -------- -XXXFILLME - -Component, VComponent ---------------------- -XXXFILLME - -CWProperty ---------- -XXXFILLME diff -r fd8751c3f3ee -r a721966779be doc/book/en/B1080-ajax-json.en.txt --- a/doc/book/en/B1080-ajax-json.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ -.. -*- coding: utf-8 -*- - -AJAX -==== -JSON bla bla -XXX FILLME - - -Le contrôleur 'json' --------------------- -XXX FILLME - - -API Javascript --------------- -XXX FILLME diff -r fd8751c3f3ee -r a721966779be doc/book/en/B1090-internationalization.en.txt --- a/doc/book/en/B1090-internationalization.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,100 +0,0 @@ -.. -*- coding: utf-8 -*- - -.. _internationalisation: - - -Internationalisation -==================== - -Cubicweb fully supports the internalization of it's content and interface. - -Cubicweb's interface internationalization is based on the translation project `GNU gettext`_. - -.. _`GNU gettext`: http://www.gnu.org/software/gettext/ - -Cubicweb' internalization involves two steps: - -* in your Python code and cubicweb-tal templates : mark translatable strings - -* in your application : handle the translation catalog - -String internationalization ---------------------------- - -In the Python code and cubicweb-tal templates translatable strings can be -marked in one of the following ways : - - * by using the *built-in* function `_` :: - - class PrimaryView(EntityView): - """the full view of an non final entity""" - id = 'primary' - title = _('primary') - - OR - - * by using the equivalent request's method :: - - class NoResultView(EmptyRsetView): - """default view when no result has been found""" - id = 'noresult' - - def call(self, **kwargs): - self.w(u'
    %s
    \n' - % self.req._('No result matching query')) - -The goal of the *built-in* function `_` is only **to mark the -translatable strings**, it will only return the string to translate -it-self, but not its translation. - -In the other hand the request's method `self.req._` is meant to retrieve the -proper translation of translation strings in the requested language. - -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 application's schema as they are generated - automatically. - - -Handle the translation catalog ------------------------------- - -Once the internationalization is done in your application's code, you need -to populate and update the translation catalog. Cubicweb provides the -following commands for this purpose: - - -* `i18nlibupdate` updates Cubicweb framework's translation - catalogs. Unless you work on the framework development, you don't - need to use this command. - -* `i18nupdate` updates the translation catalogs of *one particular - component* (or of all components). After this command is - executed you must update the translation files *.po* in the "i18n" - directory of your template. This command will of course not remove - existing translations still in use. - -* `i18ncompile` recompile the translation catalogs of *one particular - instance* (or of all instances) after the translation catalogs of - its components have been updated. This command is automatically - called every time you create or update your instance. The compiled - catalogs (*.mo*) are stored in the i18n//LC_MESSAGES of - application where `lang` is the language identifier ('en' or 'fr' - for exemple). - - -Example -``````` -You have added and/or modified some translation strings in your application -(after creating a new view or modifying the application's schema for exemple). -To update the translation catalogs you need to do: - -1. `cubicweb-ctl i18nupdate ` -2. Edit the /xxx.po files and add missing translations (empty `msgstr`) -3. `hg ci -m "updated i18n catalogs"` -4. `cubicweb-ctl i18ncompile ` - diff -r fd8751c3f3ee -r a721966779be doc/book/en/B1100-online-doc.en.txt --- a/doc/book/en/B1100-online-doc.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ -.. -*- coding: utf-8 -*- - -Online documentation system -=========================== - -[WRITE ME] - -* describe the on-line documentation system - diff -r fd8751c3f3ee -r a721966779be doc/book/en/B1110-embedding-external-page.en.txt --- a/doc/book/en/B1110-embedding-external-page.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ -.. -*- coding: utf-8 -*- - -Embedding external pages -======================== - -[WRITE ME] - -* including external content - diff -r fd8751c3f3ee -r a721966779be doc/book/en/B1120-urlrewrite.en.txt --- a/doc/book/en/B1120-urlrewrite.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,10 +0,0 @@ -.. -*- coding: utf-8 -*- - -URL Rewriting -============= - - -[WRITE ME] - -* show how urls are mapped to selections and views and explain URLRewriting - diff -r fd8751c3f3ee -r a721966779be doc/book/en/B1130-css.en.txt --- a/doc/book/en/B1130-css.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ -.. -*- coding: utf-8 -*- - -CSS changes -=========== - -XXX FIXME explain CSS used by cubciweb - -We cannot modify the order in which the application is reading the CSS. In -the case we want to create new CSS style, the best is to define it a in a new -CSS located under ``myapp/data/`` and use those new styles while writing -customized views and templates. - -If you want to modify an existing CSS styling property, you will have to use -``!important`` declaration to override the existing property. The application -apply a higher priority on the default CSS and you can not change that. -Customized CSS will not be read first. diff -r fd8751c3f3ee -r a721966779be doc/book/en/B2-repository-customization.en.txt --- a/doc/book/en/B2-repository-customization.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,15 +0,0 @@ -.. -*- coding: utf-8 -*- - -Repository customization -++++++++++++++++++++++++ -.. toctree:: - :maxdepth: 1 - - B2010-sessions.en.txt - B2020-hooks.en.txt - B2030-notifications.en.txt - B2040-repository-operations.en.txt - B2050-google-appengine.en.txt - B2060-repository-tasks.en.txt - - diff -r fd8751c3f3ee -r a721966779be doc/book/en/B2010-sessions.en.txt --- a/doc/book/en/B2010-sessions.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ -.. -*- coding: utf-8 -*- - -Sessions -======== - -[WRITE ME] - -* authentication and management of sessions - diff -r fd8751c3f3ee -r a721966779be doc/book/en/B2020-hooks.en.txt --- a/doc/book/en/B2020-hooks.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ -.. -*- coding: utf-8 -*- - -.. _hooks: - -Hooks -===== - -XXX FILLME - -*Hooks* are executed before or after updating an entity or a relation in the -repository. - -Their prototypes are as follows: - - * after_add_entity (session, entity) - * after_update_entity (session, entity) - * after_delete_entity (session, eid) - * before_add_entity (session, entity) - * before_update_entity (session, entity) - * before_delete_entity (session, eid) - - * after_add_relation (session, fromeid, rtype, toeid) - * after_delete_relation (session, fromeid, rtype, toeid) - * before_add_relation (session, fromeid, rtype, toeid) - * before_delete_relation (session, fromeid, rtype, toeid) - - * server_startup - * server_shutdown - - * session_open - * session_close - diff -r fd8751c3f3ee -r a721966779be doc/book/en/B2030-notifications.en.txt --- a/doc/book/en/B2030-notifications.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,6 +0,0 @@ -.. -*- coding: utf-8 -*- - -Notifications management -======================== - -XXX FILLME diff -r fd8751c3f3ee -r a721966779be doc/book/en/B2040-repository-operations.en.txt --- a/doc/book/en/B2040-repository-operations.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ -.. -*- coding: utf-8 -*- - -Repository operations -====================== - -[WRITE ME] - -* repository operations - diff -r fd8751c3f3ee -r a721966779be doc/book/en/B2050-google-appengine.en.txt --- a/doc/book/en/B2050-google-appengine.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,11 +0,0 @@ -.. -*- coding: utf-8 -*- - -.. _gaecontents: - -========================== -Google AppEngine Datastore -========================== - - -.. include:: B2051-intro.en.txt -.. include:: B2052-install.en.txt diff -r fd8751c3f3ee -r a721966779be doc/book/en/B2051-intro.en.txt --- a/doc/book/en/B2051-intro.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +0,0 @@ -.. -*- coding: utf-8 -*- - -Introduction -============ - -What is `Google AppEngine` ? ------------------------------- - -`Google AppEngine`_ is provided with a partial port of the `Django` -framework, but Google stated at Google IO 2008 that it would not -support a specific Python web framework and that all -community-supported frameworks would be more than welcome [1]_. - -Therefore `Logilab`_ ported `CubicWeb` to run on top of `Google AppEngine`'s -datastore. - -.. _`Google AppEngine`: http://code.google.com/appengine/docs/whatisgoogleappengine.html -.. _Logilab: http://www.logilab.fr/ -.. [1] for more on this matter, read our blog at http://www.logilab.org/blogentry/5216 - - -Essentials ----------- - -To build a web application for `Google App Engine`'s datastore, you -need to have a good understanding of the main concepts of our -`CubicWeb` framework. - -The main concepts are: - - - *schema* - - - *query language* - - - *result set* - - - *views* - - - *generated user interface* - - - *cube* - -You can find detailled explanation of those concepts in :ref:`TermsVocabulary`. - diff -r fd8751c3f3ee -r a721966779be doc/book/en/B2052-install.en.txt --- a/doc/book/en/B2052-install.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,219 +0,0 @@ -.. -*- coding: utf-8 -*- - -.. _installation: - -Installation -============ - -Download the source -------------------- - -- The `Google AppEngine SDK` can be downloaded from: - http://code.google.com/appengine/downloads.html - - -Please follow instructions on how to install `CubicWeb` framework -(:ref:`CubicWebInstallation`). - -Once ``cubicweb-ctl`` is installed, then you can create a Google -App Engine extension of our framework by running the command :: - - cubicweb-ctl newgapp - -This will create a directory containing :: - - `-- myapp/ - |-- app.conf - |-- app.yaml - |-- bin/ - | `-- laxctl - |-- boostrap_cubes - |-- cubes/ - | |-- addressbook/ - | .. - | |-- comment - | .. - | `-- zone/ - |-- cubicweb/ - |-- custom.py - |-- cw-cubes/ - |-- dateutil/ - |-- docutils/ - |-- fckeditor/ - |-- i18n/ - |-- index.yaml - |-- loader.py - |-- logilab/ - |-- main.py - |-- migration.py - |-- mx/ - |-- roman.py - |-- rql/ - |-- schema.py - |-- simplejson/ - |-- tools/ - |-- views.py - |-- vobject/ - |-- yams/ - `-- yapps/ - - -This skeleton directory is a working `AppEngine` application. You will -recognize the files ``app.yaml`` and ``main.py``. All the rest is the -`CubicWeb` framework and its third-party libraries. You will notice that -the directory ``cubes`` is a library of reusable cubes. - -The main directories that you should know about are: - - - ``cubes`` : this is a library of reusable yams cubes. To use - those cubes you will list them in the variable - `included-yams-cubes` of ``app.conf``. See also :ref:`cubes`. - - [WHICH OTHER ONES SHOULD BE LISTED HERE?] - -Dependencies ------------- - -Before starting anything, please make sure the following packages are installed: - - yaml : by default google appengine is providing yaml; make sure you can - import it. We recommend you create a symbolic link yaml instead of installing - and using python-yaml: - yaml -> full/path/to/google_appengine/lib/yaml/lib/yaml/ - - gettext - -Setup ------ - -Once you executed ``cubicweb-ctl newgapp ``, you can use that ``myapp/`` -as an application directory and do as follows. - -This installation directory provides a configuration for an instance of `CubicWeb` -ported for Google App Engine. It is installed with its own command ``laxctl`` -which is a port of the command tool ``cubicweb-ctl`` originally developped for -`CubicWeb`. - -You can have the details of available commands by running :: - - $ python myapp/bin/laxctl --help - - -Generating translation files -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -`CubicWeb` is fully internationalized. Translation catalogs are found in -``myapp/i18n``. To compile the translation files, use the `gettext` tools -or the ``laxctl`` command :: - - $ python myapp/bin/laxctl i18nupdate - $ python myapp/bin/laxctl i18ncompile - -Ignore the errors that print "No translation file found for domain -'cubicweb'". They disappear after the first run of i18ncompile. - -.. note:: The command myapp/bin/laxctl i18nupdate needs to be executed - only if your application is using cubes from cubicweb-apps. - Otherwise, please skip it. - -You will never need to add new entries in the translation catalog. Instead we would -recommand you to use ``self.req._("msgId")`` in your application code -to flag new message id to add to the catalog, where ``_`` refers to -xgettext that is used to collect new strings to translate. -While running ``laxctl i18nupdate``, new string will be added to the catalogs. - -Generating the data directory -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -In order to generate the ``myapp/data`` directory that holds the static -files like stylesheets and icons, you need to run the command:: - - $ python myapp/bin/laxctl populatedata - -Generating the schema diagram -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -There is a view named ``schema`` that displays a diagram of the -entity-relationship graph defined by the schema. This diagram has to -be generated from the command line:: - - $ python myapp/bin/laxctl genschema - -Application configuration -------------------------- - -Authentication -~~~~~~~~~~~~~~ - -You have the option of using or not google authentication for your application. -This has to be define in ``app.conf`` and ``app.yaml``. - -In ``app.conf`` modify the following variable:: -  - # does this application rely on google authentication service or not. - use-google-auth=no - -In ``app.yaml`` comment the `login: required` set by default in the handler:: - - - url: .* - script: main.py - # comment the line below to allow anonymous access or if you don't want to use - # google authentication service - #login: required - - - - -Quickstart : launch the application ------------------------------------ - -On Mac OS X platforms, drag that directory on the -`GoogleAppEngineLauncher`. - -On Unix and Windows platforms, run it with the dev_appserver:: - - $ python /path/to/google_appengine/dev_appserver.py /path/to/myapp/ - -Once the local server is started, visit `http://MYAPP_URL/_load `_ and sign in as administrator. -This will initialize the repository and enable you to log in into -the application and continue the installation. - -You should be redirected to a page displaying a message `content initialized`. - -Initialize the datastore -~~~~~~~~~~~~~~~~~~~~~~~~ - -You, then, want to visit `http://MYAPP_URL/?vid=authinfo `_ . -If you selected not to use google authentication, you will be prompted to a -login form where you should initialize the administrator login (recommended -to use admin/admin at first). You will then be redirected to a page providing -you the value to provide to ``./bin/laxctl --cookie``. - -If you choosed to use google authentication, then you will not need to set up -and administrator login but you will get the cookie value as well. - -This cookie values needs to be provided to ``laxctl`` commands -in order to handle datastore administration requests. - -.. image:: images/lax-book.02-cookie-values.en.png - :alt: displaying the detailed view of the cookie values returned - - -.. note:: In case you are not redirected to a page providing the - option --cookie value, please visit one more time - `http://MYAPP_URL/?vid=authinfo `_ . - -Once, you have this value, then return to the shell and execute :: - - $ python myapp/bin/laxctl db-init --cookie='dev_appserver_login=test@example.com:True; __session=7bbe973a6705bc5773a640f8cf4326cc' localhost:8080 - -.. note:: In the case you are not using google authentication, the value returned - by `http://MYAPP_URL/?vid=authinfo `_ - will look like : - --cookie='__session=2b45d1a9c36c03d2a30cedb04bc37b6d' - -Log out by clicking in the menu at the top right corner -and restart browsing from `http://MYAPP_URL/ `_ -as a normal user. - -Unless you did something to change it, http://MYAPP_URL should be -http://localhost:8080/ - - diff -r fd8751c3f3ee -r a721966779be doc/book/en/B2060-repository-tasks.en.txt --- a/doc/book/en/B2060-repository-tasks.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ -.. -*- coding: utf-8 -*- - -Tasks -========= - -[WRITE ME] - -* repository tasks - diff -r fd8751c3f3ee -r a721966779be doc/book/en/B3-test.en.txt --- a/doc/book/en/B3-test.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ -.. -*- coding: utf-8 -*- - -Tests -+++++ -.. toctree:: - :maxdepth: 1 - - B3010-tests.en.txt - diff -r fd8751c3f3ee -r a721966779be doc/book/en/B3010-tests.en.txt --- a/doc/book/en/B3010-tests.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ -.. -*- coding: utf-8 -*- - -Tests -===== - -Unit tests ----------- - -`CubicWeb` framework provides essentially two Python test classes in the -module `cubicweb.devtools.apptest`: - -* `EnvBasedTC`, to simulate a complete environment (web + repository) -* `RepositoryBasedTC`, to simulate a repository environment only - -Thos two classes almost have the same interface and offers numerous methods to -write tests rapidely and efficiently. - -XXX FILLME describe API - -In most of the cases, you will inherit `EnvBasedTC` to write Unittest or -functional tests for your entities, views, hooks, etc... - -Email notifications tests -------------------------- -When running tests potentially generated e-mails are not really -sent but is found in the list `MAILBOX` of module `cubicweb.devtools.apptest`. -This list is reset at each test *setUp* (by the setUp of classes `EnvBasedTC` -and `RepositoryBasedTC`). - - -You can test your notifications by analyzing the contents of this list, which -contains objects with two attributes: -* `recipients`, the list of recipients -* `msg`, object email.Message - -Automatic testing ------------------ -XXXFILLME diff -r fd8751c3f3ee -r a721966779be doc/book/en/B4-advanced.en.txt --- a/doc/book/en/B4-advanced.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,11 +0,0 @@ -.. -*- coding: utf-8 -*- - -Advanced -++++++++ -.. toctree:: - :maxdepth: 1 - - B4010-configuration.en.txt - B4020-dbapi.en.txt - B4030-registry.en.txt - B4040-rss-xml.en.txt diff -r fd8751c3f3ee -r a721966779be doc/book/en/B4010-configuration.en.txt --- a/doc/book/en/B4010-configuration.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ -.. -*- coding: utf-8 -*- - -Configuration -------------- - -[WRITE ME] - -* the config object. adding configuration option - diff -r fd8751c3f3ee -r a721966779be doc/book/en/B4020-dbapi.en.txt --- a/doc/book/en/B4020-dbapi.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ -.. -*- coding: utf-8 -*- - -DB-API -========= - -[WRITE ME] - -* direct connection to the repository - diff -r fd8751c3f3ee -r a721966779be doc/book/en/B4030-registry.en.txt --- a/doc/book/en/B4030-registry.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,148 +0,0 @@ -.. -*- coding: utf-8 -*- - -The Registry ------------- - -[WRITE ME] - -* talk about the vreg singleton, appobjects, registration and selection - - -Details of the recording process -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -At startup, the `registry` or registers base, inspects a number of directories -looking for compatible classes definition. After a recording process, the objects -are assigned to registers so that they can be selected dynamically while the -application is running. - -The base class of those objects is `AppRsetObject` (module `cubicweb.common.appobject`). - -XXX registers example -XXX actual details of the recording process! - -Runtime objects selection -~~~~~~~~~~~~~~~~~~~~~~~~~ - -XXX tell why it's a cw foundation! - -Application objects are stored in the registry using a two level hierarchy : - - object's `__registry__` : object's `id` : [list of app objects] - -The following rules are applied to select an object given a register and an id and an input context: -* each object has a selector which may be built from a set of basic (or not :) - - selectors using `chainall` or `chainfirst` combinators - -* a selector return a score >= 0 -* a score of 0 means the objects can't be applied to the input context -* the object with the greatest score is selected. If multiple objects have an - identical score, one of them is selected randomly (this is usually a bug) - -The object's selector is the `__select__` class method on the object's class. - -The score is used to choose the most pertinent objects where there are more than -one selectable object. For instance, if you're selecting the primary -(eg `id = 'primary'`) view (eg `__registry__ = 'view'`) for a result set containing -a `Card` entity, 2 objects will probably be selectable: - -* the default primary view (`accepts = 'Any'`) -* the specific `Card` primary view (`accepts = 'Card'`) - -This is because primary views are using the `accept_selector` which is considering the -`accepts` class attribute of the object's class. Other primary views specific to other -entity types won't be selectable in this case. And among selectable objects, the -accept selector will return a higher score the the second view since it's more -specific, so it will be selected as expected. - -Usually, you won't define it directly but by defining the `__selectors__` tuple -on the class, with :: - - __selectors__ = (sel1, sel2) - -which is equivalent to :: - - __select__ = classmethod(chainall(sel1, sel2)) - -The former is prefered since it's shorter and it's ease overriding in -subclasses (you have access to sub-selectors instead of the wrapping function). - -:chainall(selectors...): if one selector return 0, return 0, else return the sum of scores - -:chainfirst(selectors...): return the score of the first selector which has a non zero score - -XXX describe standard selector (link to generated api doc!) - -Example -```````` - -Le but final : quand on est sur un Blog, on veut que le lien rss de celui-ci pointe -vers les entrées de ce blog, non vers l'entité blog elle-même. - -L'idée générale pour résoudre ça : on définit une méthode sur les classes d'entité -qui renvoie l'url du flux rss pour l'entité en question. Avec une implémentation -par défaut sur AnyEntity et une implémentation particulière sur Blog qui fera ce -qu'on veut. - -La limitation : on est embêté dans le cas ou par ex. on a un result set qui contient -plusieurs entités Blog (ou autre chose), car on ne sait pas sur quelle entité appeler -la méthode sus-citée. Dans ce cas, on va conserver le comportement actuel (eg appel -à limited_rql) - -Donc : on veut deux cas ici, l'un pour un rset qui contient une et une seule entité, -l'autre pour un rset qui contient plusieurs entité. - -Donc... On a déja dans web/views/boxes.py la classe RSSIconBox qui fonctionne. Son -sélecteur :: - - class RSSIconBox(ExtResourcesBoxTemplate): - """just display the RSS icon on uniform result set""" - __selectors__ = ExtResourcesBoxTemplate.__selectors__ + (nfentity_selector,) - - -indique qu'il prend en compte : - -* les conditions d'apparition de la boite (faut remonter dans les classes parentes - pour voir le détail) -* nfentity_selector, qui filtre sur des rset contenant une liste d'entité non finale - -ça correspond donc à notre 2eme cas. Reste à fournir un composant plus spécifique -pour le 1er cas :: - - class EntityRSSIconBox(RSSIconBox): - """just display the RSS icon on uniform result set for a single entity""" - __selectors__ = RSSIconBox.__selectors__ + (onelinerset_selector,) - - -Ici, on ajoute onelinerset_selector, qui filtre sur des rset de taille 1. Il faut -savoir que quand on chaine des selecteurs, le score final est la somme des scores -renvoyés par chaque sélecteur (sauf si l'un renvoie zéro, auquel cas l'objet est -non sélectionnable). Donc ici, sur un rset avec plusieurs entités, onelinerset_selector -rendra la classe EntityRSSIconBox non sélectionnable, et on obtiendra bien la -classe RSSIconBox. Pour un rset avec une entité, la classe EntityRSSIconBox aura un -score supérieur à RSSIconBox et c'est donc bien elle qui sera sélectionnée. - -Voili voilou, il reste donc pour finir tout ça : - -* à définir le contenu de la méthode call de EntityRSSIconBox -* fournir l'implémentation par défaut de la méthode renvoyant l'url du flux rss sur - AnyEntity -* surcharger cette methode dans blog.Blog - - -When to use selectors? -``````````````````````` - -Il faut utiliser les sélecteurs pour faire des choses différentes en -fonction de ce qu'on a en entrée. Dès qu'on a un "if" qui teste la -nature de `self.rset` dans un objet, il faut très sérieusement se -poser la question s'il ne vaut pas mieux avoir deux objets différent -avec des sélecteurs approprié. - -If this is so fundamental, why don't I see them more often? -``````````````````````````````````````````````````````````` - -Because you're usually using base classes which are hiding the plumbing -of __registry__ (almost always), id (often when using "standard" object), -register and selector. diff -r fd8751c3f3ee -r a721966779be doc/book/en/C000-administration.en.txt --- a/doc/book/en/C000-administration.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,20 +0,0 @@ -.. -*- coding: utf-8 -*- - -.. _Part3: - -========================== -Part III - Administration -========================== - -This part is for installation and administration of the `CubicWeb` framework and -applications based on that framework. - -.. toctree:: - :maxdepth: 1 - - C010-setup.en.txt - C020-create-instance.en.txt - C030-site-config.en.txt - C040-instance-config.en.txt - C050-rql.en.txt - diff -r fd8751c3f3ee -r a721966779be doc/book/en/C010-setup.en.txt --- a/doc/book/en/C010-setup.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,207 +0,0 @@ -.. -*- coding: utf-8 -*- - -.. _SetUpEnv: - -=================================================== -Installation and set-up of a `CubicWeb` environment -=================================================== - -Installation of `Cubicweb` and its dependencies ------------------------------------------------ - -`CubicWeb` is packaged for Debian and Ubuntu, but can be installed from source -using a tarball or the Mercurial version control system. - -.. _DebianInstallation: - -Debian and Ubuntu packages -``````````````````````````` - -Depending on the distribution you are using, add the appropriate line to your list -of sources (for example by editing ``/etc/apt/sources.list``). - -For Debian Lenny:: - - deb http://ftp.logilab.org/dists/ lenny/ - -For Debian Sid:: - - deb http://ftp.logilab.org/dists/ sid/ - -For Ubuntu Hardy:: - - deb http://ftp.logilab.org/dists/ hardy/ - - -You can now install the required packages with the following command:: - - apt-get update - apt-get install cubicweb cubicweb-dev - -`cubicweb` installs the framework itself, allowing you to create -new applications. - -`cubicweb-dev` installs the development environment allowing you to -develop new cubes. - -There is also a wide variety of cubes listed on http://www.cubicweb.org/Project available as debian packages and tarball. - - -Install from source -``````````````````` - -You can download the archive containing the sources from our `ftp site`_ at:: - - http://ftp.logilab.org/pub/cubicweb/ - -.. _`ftp site`: http://ftp.logilab.org/pub/cubicweb/ - -or keep up to date with on-going development by using Mercurial and its forest -extension:: - - hg fclone http://www.logilab.org/hg/forests/cubicweb - -See :ref:`MercurialPresentation` for more details about Mercurial. - -Postgres installation -````````````````````` - -Please refer to the `Postgresql project online documentation`_. - -.. _`Postgresql project online documentation`: http://www.postgresql.org/ - -You need to install the three following packages: `postgres-8.3`, -`postgres-contrib-8.3` and `postgresql-plpython-8.3`. - - -Then you can install: - -* `pyro` if you wish the repository to be accessible through Pyro - or if the client and the server are not running on the same machine - (in which case the packages will have to be installed on both - machines) - -* `python-ldap` if you plan to use a LDAP source on the server - -.. _ConfigurationEnv: - -Environment configuration -------------------------- - -If you installed `CubicWeb` by cloning the Mercurial forest, then you -will need to update the environment variable PYTHONPATH by adding -the path to the forest ``cubicweb``: - -Add the following lines to either `.bashrc` or `.bash_profile` to configure -your development environment :: - - export PYTHONPATH=/full/path/to/cubicweb-forest - -If you installed the debian packages, no configuration is required. -Your new cubes will be placed in `/usr/share/cubicweb/cubes` and -your applications will be placed in `/etc/cubicweb.d`. - -To use others directories then you will have to configure the -following environment variables as follows:: - - export CW_CUBES_PATH=~/lib/cubes - export CW_REGISTRY=~/etc/cubicweb.d/ - export CW_INSTANCE_DATA=$CW_REGISTRY - export CW_RUNTIME=/tmp - -.. note:: - The values given above are our suggestions but of course - can be different. - - -Databases configuration ------------------------ - - - -.. _ConfigurationPostgres: - -Postgres configuration -`````````````````````` - -.. note:: - If you already have an existing cluster and postgres server - running, you do not need to execute the initilization step - of your Postgres database. - -* First, initialize the database Postgres with the command ``initdb``. - :: - - $ initdb -D /path/to/pgsql - - Once initialized, start the database server Postgres - with the command:: - - $ postgres -D /path/to/psql - - If you cannot execute this command due to permission issues, please - make sure that your username has write access on the database. - :: - - $ chown username /path/to/pgsql - -* The database authentication can be either set to `ident sameuser` - or `md5`. - If set to `md5`, make sure to use an existing user - of your database. - If set to `ident sameuser`, make sure that your - client's operating system user name has a matching user in - the database. If not, please do as follow to create a user:: - - $ su - $ su - postgres - $ createuser -s -P username - - The option `-P` (for password prompt), will encrypt the password with - the method set in the configuration file ``pg_hba.conf``. - If you do not use this option `-P`, then the default value will be null - and you will need to set it with:: - - $ su postgres -c "echo ALTER USER username WITH PASSWORD 'userpasswd' | psql" - - This login/password will be requested when you will create an - instance with `cubicweb-ctl create` to initialize the database of - your application. - -.. note:: - The authentication method can be configured in ``pg_hba.conf``. - - -.. FIXME Are these steps really necessary? It seemed to work without. - -* Installation of plain-text index extension :: - - cat /usr/share/postgresql/8.3/contrib/tsearch2.sql | psql -U username template1 - -* Installation of plpythonu language by default :: - - createlang -U pgadmin plpythonu template1 - -MySql configuration -``````````````````` -Yout must add the following lines in /etc/mysql/my.cnf file:: - - transaction-isolation = READ-COMMITTED - default-storage-engine=INNODB - default-character-set=utf8 - max_allowed_packet = 128M - -Pyro configuration ------------------- - -If you use Pyro, it is required to have a name server Pyro running on your -network (by default it is detected by a broadcast request). - -To do so, you need to : - -* launch the server manually before starting cubicweb as a server with - `pyro-nsd start` - -* edit the file ``/etc/default/pyro-nsd`` so that the name server pyro - will be launched automatically when the machine fire up - diff -r fd8751c3f3ee -r a721966779be doc/book/en/C020-create-instance.en.txt --- a/doc/book/en/C020-create-instance.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,132 +0,0 @@ -.. -*- coding: utf-8 -*- - -Creation of your first instance -=============================== - -What is an instance? --------------------- - -A `CubicWeb` instance is a directory in ``~/etc/cubicweb.d`` -which enables us to run a web application. An instance is based on -a cube. - -An instance is a container that refers to cubes and configuration -parameters for your web application. - -We recommand not to define schema, entities or views in the instance -file system itself but in the cube, in order to maintain re-usability of -entities and their views. We strongly recommand to develop cubes which -could be used in other instances (modular approach). - - -What is a cube? ---------------- - -A cube defines entities, their views, their schemas and workflows -in an independant directory located in ``/path/to/forest/cubicweb/cubes/`` -for a Mercurial installation or in ``/usr/share/cubicweb/cubes`` for -a debian package installation. - -When an instance is created, you list one or more cubes that your instance -will use. Using a cube means having the entities defined in your cube's schema -available in your instance as well as their views and workflows. - -.. note:: - The commands used below are more detailled in the section dedicated to - :ref:`cubicweb-ctl`. - - -Create a cube -------------- - -Let's start by creating the cube environment in which we will develop :: - - cd ~/hg - - cubicweb-ctl newcube mycube - - # answer questions - hg init moncube - cd mycube - hg add . - hg ci - -If all went well, you should see the cube you just create in the list -returned by `cubicweb-ctl list` in the section *Available components*, -and if it is not the case please refer to :ref:`ConfigurationEnv`. - -To use a cube, you have to list it in the variable ``__use__`` -of the file ``__pkginfo__.py`` of the instance. -This variable is used for the instance packaging (dependencies -handled by system utility tools such as APT) and the usable cubes -at the time the base is created (import_erschema('MyCube') will -not properly work otherwise). - -.. note:: - Please note that if you do not wish to use default directory - for your cubes library, then you want to use the option - --directory to specify where you would like to place - the source code of your cube: - ``cubicweb-ctl newcube --directory=/path/to/cubes/library cube_name`` - -Instance creation ------------------ - -Now that we created our cube, we can create an instance to view our -application in a web browser. To do so we will use a `all-in-on` -configuration to simplify things :: - - cubicweb-ctl create -c all-in-one mycube myinstance - -.. note:: - Please note that we created a new cube for a demo purpose but - you could have use an existing cube available in our standard library - such as blog or person for example. - -A serie of questions will be prompted to you, the default answer is usually -sufficient. You can anyway modify the configuration later on by editing -configuration files. When a user/psswd is requested to access the database -please use the login you create at the time you configured the database -(:ref:`ConfigurationPostgres`). - -It is important to distinguish here the user used to access the database and -the user used to login to the cubicweb application. When a `CubicWeb` application -starts, it uses the login/psswd for the database to get the schema and handle -low level transaction. But, when ``cubicweb-ctl create`` asks for -a manager login/psswd of `CubicWeb`, it refers to an application user you will -use during the development to administrate your web application. It will be -possible, later on, to create others users for your final web application. - -When this command is completed, the definition of your instance is -located in *~/etc/cubicweb.d/myinstance/*. To launch it, you just type :: - - cubicweb-ctl start -D myinstance - -The option `-D` specify the *debug mode* : the instance is not running in -server mode and does not disconnect from the termnial, which simplifies debugging -in case the instance is not properly launched. You can see how it looks by -visiting the URL `http://localhost:8080` (the port number depends of your -configuration). To login, please use the cubicweb administrator login/psswd you -defined when you created the instance. - -To shutdown the instance, Crtl-C in the terminal window is enough. -If you did not use the option `-D`, then type :: - - cubicweb-ctl stop myinstance - -This is it! All is settled down to start developping your data model... - - -Usage of `cubicweb-liveserver` -`````````````````````````````` - -To quickly test a new cube, you can also use the script `cubicweb-liveserver` -which allows to create an application in memory (use of SQLite database by -default) and make it accessible through a web server :: - - cubicweb-ctl live-server mycube - -or by using an existing database (SQLite or Postgres):: - - cubicweb-ctl live-server -s myfile_sources mycube - diff -r fd8751c3f3ee -r a721966779be doc/book/en/C030-site-config.en.txt --- a/doc/book/en/C030-site-config.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,94 +0,0 @@ -.. -*- coding: utf-8 -*- - -User interface for web site configuration -========================================= - -.. image:: images/lax-book.03-site-config-panel.en.png - -This panel allows you to configure the appearance of your application site. -Six menus are available and we will go through each of them to explain how -to use them. - -Navigation -~~~~~~~~~~ -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 - (sample format: 23) -* 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) - -UI -~~ -This menu provides you a way to customize the user interface settings such as -date format or encoding in the produced html. -Follows the detailled list of available options : - -* ui.date-format : how to format date in the ui ("man strftime" for format description) -* ui.datetime-format : how to format date and time in the ui ("man strftime" for format - description) -* ui.default-text-format : default text format for rich text fields. -* ui.encoding : user interface encoding -* ui.fckeditor :should html fields being edited using fckeditor (a HTML WYSIWYG editor). - You should also select text/html as default text format to actually get fckeditor. -* ui.float-format : how to format float numbers in the ui -* ui.language : language of the user interface -* ui.main-template : id of main template used to render pages -* ui.site-title : site title, which is displayed right next to the logo in the header -* ui.time-format : how to format time in the ui ("man strftime" for format description) - - -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. - -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 - 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 -* hidden : select this to hide the specific action - -Boxes -~~~~~ -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. - -The available boxes are : - -* actions box : box listing the applicable actions on the displayed data - -* boxes_blog_archives_box : box listing the blog archives - -* possible views box : box listing the possible views for the displayed data - -* rss box : RSS icon to get displayed data as a RSS thread - -* search box : search box - -* startup views box : box listing the configuration options available for - the application site, such as `Preferences` and `Site Configuration` - -Components -~~~~~~~~~~ -[WRITE ME] - -Contextual components -~~~~~~~~~~~~~~~~~~~~~ -[WRITE ME] - diff -r fd8751c3f3ee -r a721966779be doc/book/en/C040-instance-config.en.txt --- a/doc/book/en/C040-instance-config.en.txt Tue Apr 28 11:22:43 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,163 +0,0 @@ -.. -*- coding: utf-8 -*- - - -Configure an instance -===================== - -While creating an instance, a configuration file is generated in:: - - $ (CW_REGISTRY) / / .conf - -For example:: - - /etc/cubicweb.d/JPL/all-in-one.conf - -It is a simple text file format INI. In the following description, -each option name is prefixed with its own section and followed by its -default value if necessary, e.g. "`
    .