--- a/cwconfig.py Tue Nov 25 17:44:54 2008 +0100
+++ b/cwconfig.py Tue Nov 25 17:45:11 2008 +0100
@@ -264,9 +264,9 @@
cube = CW_MIGRATION_MAP.get(cube, cube)
try:
return getattr(__import__('cubes.%s.__pkginfo__' % cube), cube).__pkginfo__
- except ImportError:
+ except Exception, ex:
raise ConfigurationError('unable to find packaging information for '
- 'cube %s' % cube)
+ 'cube %s (%s: %s)' % (cube, ex.__class__.__name__, ex))
@classmethod
def cube_version(cls, cube):
--- a/debian/changelog Tue Nov 25 17:44:54 2008 +0100
+++ b/debian/changelog Tue Nov 25 17:45:11 2008 +0100
@@ -1,3 +1,9 @@
+cubicweb (2.99.2-1) DISTRIBUTION; urgency=low
+
+ * new upstream release
+
+ -- Adrien Di Mascio <adrien.dimascio@logilab.fr> Mon, 17 Nov 2008 15:02:16 +0100
+
cubicweb (2.99.1-1) DISTRIBUTION; urgency=low
* new upstream release
--- a/devtools/devctl.py Tue Nov 25 17:44:54 2008 +0100
+++ b/devtools/devctl.py Tue Nov 25 17:45:11 2008 +0100
@@ -362,7 +362,7 @@
runserver()
-class NewTemplateCommand(Command):
+class NewCubeCommand(Command):
"""Create a new cube.
<cubename>
@@ -371,6 +371,15 @@
name = 'newcube'
arguments = '<cubename>'
+ options = (
+ ("verbose",
+ {'short': 'v', 'type' : 'yn', 'metavar': '<verbose>',
+ 'default': 'n',
+ 'help': 'verbose mode: will ask all possible configuration questions',
+ }
+ ),
+ )
+
def run(self, args):
if len(args) != 1:
@@ -378,6 +387,7 @@
cubename, = args
if ServerConfiguration.mode != "dev":
self.fail("you can only create new cubes in development mode")
+ verbose = self.get('verbose')
cubedir = ServerConfiguration.CUBES_DIR
if not isdir(cubedir):
print "creating apps directory", cubedir
@@ -389,19 +399,27 @@
if exists(cubedir):
self.fail("%s already exists !" % (cubedir))
skeldir = join(BASEDIR, 'skeleton')
- distname = raw_input('Debian name for your cube (just type enter to use the cube name): ').strip()
- if not distname:
+ if verbose:
+ distname = raw_input('Debian name for your cube (just type enter to use the cube name): ').strip()
+ if not distname:
+ distname = 'cubicweb-%s' % cubename.lower()
+ elif not distname.startswith('cubicweb-'):
+ if confirm('do you mean cubicweb-%s ?' % distname):
+ distname = 'cubicweb-' + distname
+ else:
distname = 'cubicweb-%s' % cubename.lower()
- elif not distname.startswith('cubicweb-'):
- if confirm('do you mean cubicweb-%s ?' % distname):
- distname = 'cubicweb-' + distname
- shortdesc = raw_input('Enter a short description for your cube: ')
- longdesc = raw_input('Enter a long description (or nothing if you want to reuse the short one): ')
- includes = self._ask_for_dependancies()
- if len(includes) == 1:
- dependancies = '%r,' % includes[0]
+
+ longdesc = shortdesc = raw_input('Enter a short description for your cube: ')
+ if verbose:
+ longdesc = raw_input('Enter a long description (or nothing if you want to reuse the short one): ')
+ if verbose:
+ includes = self._ask_for_dependancies()
+ if len(includes) == 1:
+ dependancies = '%r,' % includes[0]
+ else:
+ dependancies = ', '.join(repr(cube) for cube in includes)
else:
- dependancies = ', '.join(repr(cube) for cube in includes)
+ dependancies = ''
from mx.DateTime import now
context = {'cubename' : cubename,
'distname' : distname,
@@ -431,5 +449,5 @@
register_commands((UpdateCubicWebCatalogCommand,
UpdateTemplateCatalogCommand,
LiveServerCommand,
- NewTemplateCommand,
+ NewCubeCommand,
))
--- a/doc/book/en/01-00-introduction.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _Overview:
-
-Quick overview of `CubicWeb`
-============================
-
-`CubicWeb` allows us to develop web applications instances based on
-one or more `cubes`.
-
-What we call a `cube` is a model defining the data types and views.
-A `cube` is a reusable component grouped with others cubes in the file
-system.
-
-An `instance` refers to a specific installation of one or more `cubes`
- where are grouped configuration files of the final web application.
-
-In this document, we will show you how to create a `cube` and how to use it
-in an `instance` for your web application.
-
-.. include:: 01-01-create-cube.en.txt
-.. include:: 01-05-components.en.txt
-.. include:: 01-06-maintemplate.en.txt
-.. include:: 01-07-rss-xml.en.txt
--- a/doc/book/en/01-01-create-cube.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,314 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Create your cube
-----------------
-
-After you installed your `CubicWeb` development environment, you can start
-to build your first cube: ::
-
- cubicweb-ctl newcube blog
-
-This will create in ``/path/to/forest/cubes`` a directory containing: ::
-
- blog/
- |
- |-- data/
- | |-- cubes.blog.css
- | |-- cubes.blog.js
- | |-- external_resources
- |
- |-- debian/
- | |-- changelog
- | |-- compat
- | |-- control
- | |-- copyright
- | |-- cubicweb-blog.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
- |
- |-- sobjects.py
- |
- |-- test/
- | |-- data/
- | |-- bootstrap_cubes
- | |-- pytestconf.py
- | |-- realdb_test_blog.py
- | |-- test_blog.py
- |
- |-- views.py
-
-Any changes applied to your data model should be done in this
-directory.
-
-
-Define your data schema
------------------------
-
-The data model or schema is hte core of your `CubicWeb` application.
-This is where is defined the type of content you application will handle.
-
-The data model is defined in the file ``schema.py`` of your cube
-``blog`` such as follows.
-
-::
-
- from cubicweb.schema import format_constraint
- 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
---------------------
-
-::
-
- cubicweb-ctl create blog blogdemo
-
-
-This command will create a directory ``~/etc/cubicweb.d/blogdemo``
-which will contain all the configuration files required to start
-you web application.
-
-The instance ``blogdemo`` is based on the cube ``blog``.
-
-
-Welcome in your web application
--------------------------------
-
-Run your application with the following command: ::
-
- cubicweb-ctl start -D blogdemo
-
-
-You can now access to your web application to create blogs and post messages
-by visitin the URL http://localhost:8080/.
-A login form will first be prompted. By default, the application will not allow
-anonymous user to get in the application. You should 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. Bravo!
-
-.. image:: images/blog-demo-first-page.png
-
-Please notice that so far, `CubicWeb` franework managed all aspects of
-the web application based in the schema provided at first.
-
-
-Create entities
----------------
-
-We will now create a couple of entities in our web application.
-
-Create a Blog
-~~~~~~~~~~~~~
-
-Let us create a few of these entities. Click on the `[+]` at the right
-of the link Blog. 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
-
-Create a BlogEntry
-~~~~~~~~~~~~~~~~~~
-
-Get back to the home page and click on [+] at the right 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)
-
-
-Define your entities views
---------------------------
-
-The views 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 resulsets it can be applied to
-
-
-`CubicWeb` provides a lot of standard views for the type
-`EntityView`, for a complete list, you
-will have to 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
-mecanism which computes a score used to identify which view
-is the best to apply for the `result set` we are trying to
-display. 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. We will see more details
-on this in :ref:`DefinitionVues`.
-
-For example, the view named ``primary`` is the one used to display
-a single entity. We will now show you hos 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 by example add in front of the pulication date a prefix specifying
-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'<h1>%s</h1>' % 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'<h1>%s</h1>' % entity.title)
- self.w(u'<p>published on %s</p>' % entity.publish_date.strftime('%Y-%m-%d'))
- self.w(u'<p>%s</p>' % 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 resultsets and resulsets can be tables of
-data, it is needed to recover the entity from its (row,col)
-coordinates. We will get to this in more detail later.
-
-The view has a ``self.w()`` method that is used to output data. In our
-example we use it to output HTML tags and values of the entity's attributes.
--- a/doc/book/en/01-05-components.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,150 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _components:
-
-Components
-----------
-
-What is a component
-~~~~~~~~~~~~~~~~~~~
-
-A component 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
-others components.
-You can decide to write your own set of components if you wish to re-use the
-entity types you develop. By default, LAX comes with its owns set of components
-that you can start using right away.
-
-
-Standard library
-~~~~~~~~~~~~~~~~
-
-A library of standard components is part of the `LAX` release (look at
-``lax/skel/ginco-apps``). Components provide entities and views. With
-``lax-0.4``, you should get a set of application entities and system
-entities you can re-use.
-
-The available application entities are:
-
-* addressbook: PhoneNumber and PostalAddress
-
-* ebasket: Basket (like a shopping cart)
-
-* eblog: Blog (a *very* basic blog)
-
-* eclassfolder: Folder (to organize things but grouping them in folders)
-
-* eclasstags: Tag (to tag anything)
-
-
-* efile: File (to allow users to upload and store binary or text files)
-
-* elink: Link (to collect links to web resources)
-
-* emailinglist: MailingList (to reference a mailing-list and the URLs
- for its archives and its admin interface)
-
-* eperson: Person (easily mixed with addressbook)
-
-* etask: Task (something to be done between start and stop date)
-
-* ezone: Zone (to define places within larger places, for example a
- city in a state in a country)
-
-The available system entities are:
-
-* ecomment: Comment (to attach comment threads to entities)
-
-
-
-Adding comments to BlogDemo
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-To import a component in your application just change the line in the
-``app.conf`` file. For example::
-
- included-yams-components=ecomment
-
-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 ecomment component defines the
-``comments`` relationship, adding the line::
-
- comments = ObjectRelation('Comment', cardinality='1*', composite='object')
-
-to the definition of a ``BlogEntry`` will be enough.
-
-Clear the datastore and restart.
-
-Component structure
-~~~~~~~~~~~~~~~~~~~
-
-A complex component is structured as follows:
-::
-
- mycomponent/
- |
- |-- schema.py
- |
- |-- entities/
- |
- |-- sobjects/
- |
- |-- views/
- |
- |-- test/
- |
- |-- i18n/
- |
- |-- data/
- |
- |-- migration/
- | |- postcreate.py
- | \- depends.map
- |
- |-- debian/
- |
- \-- __pkginfo__.py
-
-We can also define simple Python module instead of directories (packages), for example:
-::
-
- mycomponent/
- |
- |-- entities.py
- |-- hooks.py
- \-- views.py
-
-
-where:
-
-* ``schema`` contains the definition of the schema (server side only)
-* ``entities`` contains entities definition (server side and web interface)
-* ``sobjects`` contains hooks and/or notification views (server side only)
-* ``views`` contains the web interface components (web interface only)
-* ``test`` contains tests related to the application (not installed)
-* ``i18n`` contains messages 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-components used by
- the component.
-
-At least you should have:
-
-* the file ``__pkginfo__.py``
-* schema definition
-
-[WRITE ME]
-
-* explain the component architecture
-
-* add comments to the blog by importing the comments component
--- a/doc/book/en/01-06-maintemplate.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,209 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Views & Templates
------------------
-
-Look at ``lax/skel/ginco/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
-~~~~~~~~~~~~~~~
-
-Let's use a different logo than the default one provided with LAX
-and customize our header.
-
-Change logo
-```````````
-
-The easiest way to use a different logo is to replace the existing
-``logo.png`` in ``myapp/data`` by your prefered icon and refresh.
-By default all application will look for a ``logo.png`` to be
-rendered in the logo section.
-
-.. image:: images/lax-book.06-main-template-logo.en.png
-
-[ADD]
-customized external_resources in myapp/data cd crih for reference
-
-[WRITE ME]
-ADD how to use external_resources variables used in ginco/web/webconfig.py
-
-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 sat 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'<table id="header"><tr>\n')
- self.w(u'<td id="firstcolumn">')
- self.vreg.select_component('logo', self.req, self.rset).dispatch(w=self.w)
- self.w(u'</td>\n')
- # appliname and breadcrumbs
- self.w(u'<td id="headtext">')
- comp = self.vreg.select_component('appliname', self.req, self.rset)
- if comp and comp.propval('visible'):
- comp.dispatch(w=self.w)
- comp = self.vreg.select_component('breadcrumbs', self.req, self.rset, view=view)
- if comp and comp.propval('visible'):
- comp.dispatch(w=self.w, view=view)
- self.w(u'</td>')
- # logged user and help
- #self.w(u'<td>\n')
- #comp = self.vreg.select_component('loggeduserlink', self.req, self.rset)
- #comp.dispatch(w=self.w)
- #self.w(u'</td><td>')
-
- self.w(u'<td>')
- helpcomp = self.vreg.select_component('help', self.req, self.rset)
- if helpcomp: # may not be available if Card is not defined in the schema
- helpcomp.dispatch(w=self.w)
- self.w(u'</td>')
- # lastcolumn
- self.w(u'<td id="lastcolumn">')
- self.w(u'</td>\n')
- self.w(u'</tr></table>\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 ginco.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'<table id="header"><tr>\n')
- self.w(u'<td id="firstcolumn">')
- self.vreg.select_component('logo', self.req, self.rset).dispatch(w=self.w)
- self.w(u'</td>\n')
- # appliname and breadcrumbs
- self.w(u'<td id="headtext">')
- comp = self.vreg.select_component('appliname', self.req, self.rset)
- if comp and comp.propval('visible'):
- comp.dispatch(w=self.w)
- comp = self.vreg.select_component('breadcrumbs', self.req, self.rset, view=view)
- if comp and comp.propval('visible'):
- comp.dispatch(w=self.w, view=view)
- self.w(u'</td>')
-
- # logged user and help
- #self.w(u'<td>\n')
- #comp = self.vreg.select_component('loggeduserlink', self.req, self.rset)
- #comp.dispatch(w=self.w)
- #self.w(u'</td><td>')
-
- # search box
- self.w(u'<td>')
- self.get_searchbox(view, 'left')
- self.w(u'</td>')
-
- self.w(u'<td>')
- helpcomp = self.vreg.select_component('help', self.req, self.rset)
- if helpcomp: # may not be available if Card is not defined in the schema
- helpcomp.dispatch(w=self.w)
- self.w(u'</td>')
- # lastcolumn
- self.w(u'<td id="lastcolumn">')
- self.w(u'</td>\n')
- self.w(u'</tr></table>\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 ginco.web.views.basetemplates import HTMLPageFooter
- class MyHTMLPageFooter(HTMLPageFooter):
- def call(self, **kwargs):
- self.w(u'<div class="footer">')
- self.w(u'This website has been created with <a href="http://lax.logilab.org">LAX</a>.')
- self.w(u'</div>')
-
-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 ``ginco/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
-
-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/``.
-
-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.
-
-[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 ginco-doc rajouter une section pour erudi-ctl shell ou
-on liste les commandes dispos.
--- a/doc/book/en/01-07-rss-xml.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /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
-
--- a/doc/book/en/01-08-book-map.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /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
-
--- a/doc/book/en/02-00-foundation.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /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), etc.
-
-In 2008, `CubicWeb` was ported for a new type of source : the datastore
-from GoogleAppEngine_.
-
-.. include:: 02-01-concepts.en.txt
-.. include:: 02-02-registry.en.txt
-.. include:: 02-03-configuration.en.txt
--- a/doc/book/en/02-01-concepts.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,411 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Concepts
---------
-
-Global architecture
-~~~~~~~~~~~~~~~~~~~
-.. image:: images/archi_globale.png
-
-.. note::
- For real, the client and server sides are integrated in the same
- process and interact directly, without the needs for distants
- calls using Pyro. It is important to note down that those two
- sides, client/server, are disjointed and it is possible to execute
- a couple of calls in distincts processes to balance the load of
- your web site on one or more machines.
-
-.. _TermsVocabulary:
-
-Terms and vocabulary
-~~~~~~~~~~~~~~~~~~~~~
-
-*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 as
- it is necessarry for the core of `CubicWeb` and a library of
- cubes that can be explicitely included if necessary.
-
-
-*entity type*
- An entity 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 corresponds 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 others
- vital informations for the system.
-
-*configuration*
- It is possible to create differents 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 functionnality or a complete `CubicWeb` application
- potentially using other cubes. The available subes are located in the file
- system at `/path/to/forest/cubicweb/cubes`.
- Larger applications can be built faster by importing cubes,
- adding entities and relationships and overriding the
- views that need to display or edit informations not provided by
- cubes.
-
-*instance*
- An instance is a specific installation of a cube. All the required
- configuration files necessarry 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.
- By 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 sometime 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 information 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*
- XXX
-
-.. _`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 dynamics objects, based on the schema
-or the library, are building the final application. The differents dymanic components are
-by 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
-~~~~~~~~~~~~~~
-
-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 dictionnary containing the values to use
-:eid_key:
- an implementation detail of the RQL queries 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 correponding key in the dictionnary
- 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 updates 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 HTPP request is sent to the web server.
-It contains informations such as forms 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 by example)**
-
-An instance of `Request` has the following attributes:
-
-* `user`, instance of `cubicweb.common.utils.User` corresponding to the authenticated
- user
-* `form`, dictionnary containing the values of a web form
-* `encoding`, characters encoding to use in the response
-
-But also:
-
-:Session data handling:
- * `session_data()`, returns a dictinnary 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 dictionnary 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 (`EProperty`)
- * dictionnary `data` to store data to share informations between components
- *while a request is executed*
-
-Please note down 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 so 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 necessarry
-* `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)`
- * `format_time(time)`
-
-:And more...:
-
- * `external_resource(rid, default=_MARKER)`, access to a value defined in the
- configuration file `external_resource`
-
- * `tal_render(template, variables)`,
-
-
-.. 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.
- By 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)
-
-
-Standard structure for a cube
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-A complex cube is structured as follows:
-
-::
-
- mycube/
- |
- |-- schema.py
- |
- |-- entities/
- |
- |-- sobjects/
- |
- |-- views/
- |
- |-- test/
- |
- |-- i18n/
- |
- |-- data/
- |
- |-- migration/
- | |- postcreate.py
- | \- depends.map
- |
- |-- debian/
- |
- \-- __pkginfo__.py
-
-We can use simple Python module instead of packages, by example:
-
-::
-
- mycube/
- |
- |-- entities.py
- |-- hooks.py
- \-- views.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 different components of the web interface (web interface only)
-* ``test`` contains tests specifics to the application (not installed)
-* ``i18n`` contains the messages catalog for supported languages (server side and
- web interface)
-* ``data`` contains arbitrary data files served statically
- (images, css, javascripts files)... (web interface only)
-* ``migration`` contains the initialization file for new instances
- (``postcreate.py``) and in general a file containing the `CubicWeb` dependancies
- of the cube depending on its version (``depends.map``)
-* ``debian`` contains all the files that manages the debian packaging
- (you would find there the classical structure with ``control``, ``rules``,
- ``changelog``... (not installed)
-* the file ``__pkginfo__.py`` provides meta-data on the cube, especially the
- distribution name and the current version (server side and web interface) or
- also the sub-cubes used by this cube
-
-The only required files are:
-
-* 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 embeding for instance)
-
--- a/doc/book/en/02-02-registry.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,147 +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
- - its selector may be derivated 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.
--- a/doc/book/en/02-03-configuration.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /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
-
--- a/doc/book/en/03-00-definition-schema.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Data Model definition (*schema*)
-================================
-
-The schema is the main concept of `LAX` applications as it defines the
-data model we will handle. It is based on entities types already defined
-in the library and others, more specific, we would expect to find in one or
-more Python files under the `schema` directory.
-
-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 "<subject entity type> <relation type> <object entity type>". A relation
-type could have been implied if none is related to a relation definition of the
-schema.
-
-
-.. include:: 03-10-stdlib-schemas.en.txt
-.. include:: 03-11-definition-schema.en.txt
--- a/doc/book/en/03-00-setup.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _MiseEnPlaceEnv:
-
-===================================================
-Installation and set-up of a `CubicWeb` environment
-===================================================
-.. contents::
-
-.. include:: 03-01-installation.en.txt
-.. include:: 03-02-create-instance.en.txt
-.. include:: 03-03-cubicweb-ctl.en.txt
-
--- a/doc/book/en/03-01-bis-installation.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _installationGAE:
-
-Installation de `CubicWeb` pour GoogleAppEngine
-===============================================
-
-Qu'est-ce que `LAX` ?
-=======================
-
-`LAX` (Logilab Appengine eXtension) est un framework d'application
-web basé sur `Google AppEngine`.
-
-`LAX` est un portage de la partie web de la plate-forme applicative
-développée par Logilab depuis 2001. Cette plate-forme publie des
-données tirées de bases SQL, d'annuaires LDAP et de systèmes de
-gestion de version. En avril 2008, elle a été portée pour fonctionner
-sur le "datastore" de `Google AppEngine`.
-
-XXX: faire un parallèle entre Django/GAE et LAX/GAE
-
-
-Téléchargement des sources
-==========================
-
-- Les sources de `Google AppEngine` peuvent être récupérées à l'adresse
- suivante : http://code.google.com/appengine/downloads.html
-
-- Les sources de `LAX` se trouvent à l'adresse suivante :
- http://lax.logilab.org/
-
-
-Installation
-============
-
-Une fois décompactée, l'archive `lax-0.1.0-alpha.tar.gz`, on obtient
-l'arborescence suivante::
-
- .
- |-- app.yaml
- |-- custom.py
- |-- data
- |-- ginco/
- |-- i18n/
- |-- logilab/
- |-- main.py
- |-- mx/
- |-- rql/
- |-- schema.py
- |-- simplejson/
- |-- tools/
- | |-- generate_schema_img.py
- | `-- i18ncompile.py
- |-- views.py
- |-- yams/
- `-- yapps/
-
-
-On retrouve le squelette d'une application web de `Google AppEngine`
-(fichiers ``app.yaml``, ``main.py`` en particulier) avec les dépendances
-supplémentaires nécessaires à l'utilisation du framework `LAX`
-
-
-Lancement de l'application de base
-==================================
-
-Plusieurs répertoires doivent être accessibles via la variable
-d'environnement ``PYTHONPATH`` ::
-
- $ export PYTHONPATH=/path/to/google_appengine:/path/to/google_appengine/lib/yaml/lib:/path/to/myapp/
-
-Le répertoire yaml n'est nécessaire que pour le lancement des scripts
-qui se trouvent dans lax/tools et pour l'exécution des tests unitaires.
-
-Pour démarrer::
-
- $ python /path/to/google_appengine/dev_appserver.py /path/to/lax
-
-
--- a/doc/book/en/03-01-installation.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,158 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Installation
-============
-
-Installation of `Cubicweb` and its dependancies
------------------------------------------------
-
-`CubicWeb` is available as a debian package as well as an archive.
-We will detail here the two easiest way to set-up `CubciWeb`
-environment.
-
-Debian packages
-```````````````
-You need first to make sure that you added our public repository
-in the list of sources you packages manager will search in.
-
-Depending on the debian distribution you are using here are all the
-available options: ::
-
- deb http://ftp.logilab.org/dists/ lenny/
- deb http://ftp.logilab.org/dists/ hardy/
- deb http://ftp.logilab.org/dists/ sid/
-
-As we assume you are installing `CubciWeb` on a debian machine, please
-add the appropriate line from above in ``/etc/apt/sources.list``.
-
-You can now install the required packages with the follwoing command: ::
-
- apt-get install cubicweb
-
-This is it!
-
-``tar.gz`` archive
-``````````````````
-
-You can download our sources at: ::
-
- http://ftp.logilab.org/pub/cubicweb/
-
-Unpack the sources
-
-
-
-
-.. note::
- `CubicWeb` is also available as a Mercurial repository using the forest
- extension (see :ref:`MercurialForestInstall` for more details).
-
-
-Postgres installation
-`````````````````````
-
-Please refer to the project online documentation Postgres_.
-
-.. _Postgres: 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 is accessible through Pyro
- or if the client and the server are not running on the same machine
- (in suche case the packages will have to be isntalled on both
- machines)
-
-* `python-ldap` if you plan to use a LDAP source on the server
-
-.. _ConfigurationEnv:
-
-Environment configuration
--------------------------
-
-[FIXME]
-Ces variables ne sont plus requises pour le bon fonctionnement de `CubicWeb`, non?
-A part rajouter la foret dans le PYTHONPATH, rien de plus ne doit etre fait?
-
-Update the environment variable PYTHONPATH to add to it 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
-
- //deprecated??
- export ERUDI_REGISTRY=~/etc/erudi.d/
- export ERUDI_TEMPLATES=~/hg/
- export ERUDI_RUNTIME=/tmp/
-
-Cela suppose que le composant erudi que vous développez est dans un
-sous-répertoire de *~/hg/* et que vous avez créé le répertoire *~/etc/erudi.d/*
-pour que `cubicweb-ctl` y place vos instances de test.
-
-.. _ConfigurationPostgres:
-
-Postgres configuration
-----------------------
-
-* First you have to initialize the database Postgres with the command ``initdb``.
- ::
-
- $ initdb -D /path/to/pgsql
-
- Once initialized, you can launch 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
-
-* Create a superuser for `CubicWeb` instance (**root**) ::
-
- createuser -s username
-
- Initialize the password of the superuser you juste created with
- ``su - postgres`` and ``psql``.
-
- This password will be asked to you later on where you will create an
- instance with `cubicweb-ctl create`
-
-[XXX]
-Est-ce que ces etapes sont vraiment necessaires?
-sand : lors de l'installation de ma bdd cela n'a pas ete fait
-et il semble que tout aille bien. Doit etre verifie avec les experts.
-
-* 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
-
-
-Pyro configuration
-------------------
-
-If you use Pyro, it is required to have a name server Pyro runing on your
-network (by default it is identified by a broadcast request).
-
-To do so, you need to :
-
-* launch the server manually before starting cubicweb with `pyro-ns`
-
-* 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 macine fire up
-
-
--- a/doc/book/en/03-02-create-instance.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,123 +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
-one or more cubes.
-
-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 schems and workflows
-in an independant directory located in ``/path/to/forest/cubicweb/cubes/``.
-
-When an instance is created, you list one or more cubes that your instance
-will use. Use 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).
-
-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 by 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 transaction [FIXME - bas niveau]. 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/moninstance/*. 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
-
--- a/doc/book/en/03-03-cubicweb-ctl.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,123 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _cubicweb-ctl:
-
-``cubicweb-ctl`` tool
-=====================
-
-`cubicweb-ctl` is the swiss knife to manage `CubicWeb` instances.
-The general syntax is ::
-
- cubicweb-ctl <command> [options command] <arguments commands>
-
-To view available commands ::
-
- cubicweb-ctl
- cubicweb-ctl --help
-
-Please note that the commands available depends on the `CubicWeb` packages
-and cubes that have been installed.
-
-To view the help menu on specific command ::
-
- cubicweb-ctl <command> --help
-
-Command to create a cube
-------------------------
-
-* ``newcube``, create a new cube on the file system based on the name
- given in the parameters. This command create a cube from an application
- skeleton that includes default files required for debian packaging.
-
-
-Command to create an instance
------------------------------
-* ``create``, creates the files for the instance configuration
-* ``db-create``, creates the system database of an instance (tables and
- extensions only)
-* ``db-init``, initializes the system database of an instance
- (schema, groups, users, workflows...)
-
-By default, those three commandes are encapsulated in ``create`` so
-that they can be executed consecutively.
-
-Command to create an instance for Google AppEngine datastore source
--------------------------------------------------------------------
-* ``newgapp``, creates the configuration files for an instance
-
-This command needs to be followed by the commands responsible for
-the database initialization. As those are specific to the `datastore`,
-specific Google AppEgine database, they are not available for now
-in cubicweb-ctl, but they are available in the instance created.
-
-[FIXME] - add link to gae install
-For more details, please see :ref:`` .
-
-Commands to launch instance
----------------------------
-* ``start``, starts one or more or all instances
-* ``stop``, stops one or more or all instances
-* ``restart``, restarts one or more or all instances
-* ``status``, returns the status of the instance
-
-Commands to maintain instances
-------------------------------
-* ``upgrade``, launches the existing instances migration when a new version
- of `CubicWeb` or the cubes installed is available
-* ``shell``, opens a migration shell for manual maintenance of the instance
-* ``db-dump``, creates a dump of the system database
-* ``db-restore``, restores a dump of the system database
-* ``db-check``, checks data integrity of an instance. If the automatic correction
- is activated, it is recommanded to create a dump before this operation.
-* ``schema-sync``, synchronizes the persistent schema of an instance with
- the application schema. It is recommanded to create a dump before this operation.
-
-Commands to maintain i18n catalogs
-----------------------------------
-* ``i18nlibupdate``, regenerates messages catalogs of the `CubicWeb` library
-* ``i18nupdate``, regenerates the messages catalogs of a cube
-* ``i18ncompile``, recompiles the messages catalogs of an instance.
- This is automatically done while upgrading.
-
-Cf :ref:`Internationalisation`.
-
-Other commands
---------------
-* ``list``, provides a list of the available configuration, cubes
- and instances.
-* ``delete``, deletes an instance (configuration files and database)
-
-Examples
---------
-
-Create an instance from an existing cube
-````````````````````````````````````````
-
-To create an instance from an existing cube, execute the following
-command ::
-
- cubicweb-ctl create <cube_name> <instance_name>
-
-This command will create the configuration files of an instance in
-``~/etc/cubicweb.d/<instance_name>``.
-The tool ``cubicweb-ctl`` allows you to execute the command ``db-create``
-and ``db-init`` when you run ``create`` so that you can complete an
-instance creation in a single command.
-
-If you decide not to execut those commands while ``cubicweb-ctl create``,
-then you will have to execute them seperately(``cubicweb-ctl db-create``,
-``cubicweb-ctl db-init`` ) otherwise your installation will not be complete
-and you will not be able to launch your instance.
-
-
-Creation of an instance from a new cube
-```````````````````````````````````````
-
-Create first your new cube cube ::
-
- cubicweb-ctl newcube <mycube>
-
-This will create a new cube in ``/path/to/forest/cubicweb/cubes/<mycube>``
-and then create an instance as explained just above.
-
-
--- a/doc/book/en/03-10-stdlib-schemas.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Pre-defined schemas in the library
-----------------------------------
-
-The library defines a set of entities schemas that are required by the system
-or commonly used in `LAX` applications.
-Of course, you can extend those schemas if necessarry.
-
-System schemas
-``````````````
-Those are defined in::
-
- ./myapp/ginco/schemas/
- ./myapp/ginco/entities/
-
-``schemas/`` defines the data model you will use in your application.
-It allows you to describre the entities and the relations you will need.
-
-``entities/`` deifnes the methods you might need on the entities you
-defined in your schema.
-
-The system entities available are:
-
-* `EUser`, system users
-* `EGroup`, users groups
-* `EEType`, entity type
-* `ERType`, 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
-
-* `EProperty`, used to configure the application
-* `EPermission`, 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
-
-
-Components in the library
-`````````````````````````
-
-Those are defined in::
-
- ./myapp/ginco-apps/
-
-An application is based on several basic components. In the set of available
-basic components we can find by example:
-
-* `ecomment`, provides an entity type for `Comment` allowing us to comment others
- site's entities
-
-* `emailinglist`, provides an entity type for `Mailinglist` which groups informations
- in a discussion list
-
-* `efile`, provides entity types for `File` et `Image` used to represent
- files (text or binary) with additionnal informations such as MIME type or
- encoding.
-
-* `elink`, provides an entity type for hypertext link (`Link`)
-
-* `eblog`, provides an entity type weblog (`Blog`)
-
-* `eperson`, provides an entity type for a person (`Person`)
-
-* `eaddressbook`, provides an entity type used to represent phone
- numbers (`PhoneNumber`) and mailing address (`PostalAddress`)
-
-* `eclasstags`, categorization system based on tags (`Tag`)
-
-* `eclassfolders`, categorization system based on folders hierarchy in order
- to create navigation sections (`Folder`)
-
-* `eemail`, archiving management for emails (`Email`, `Emailpart`,
- `Emailthread`)
-
-* `ebasket`, basket management (`Basket`) allowing to group entities
-
-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.
-
--- a/doc/book/en/03-11-definition-schema.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,344 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Entity type definition
-----------------------
-
-An entity type is defined by a Python class which inherits `EntityType`. The
-class name correponds to the type name. Then the content of the class contains
-the description of attributes and relations for the defined entity type,
-by example ::
-
- class Personne(EntityType):
- """A person with the properties and the relations necessarry for my
- application"""
-
- last_name = String(required=True, fulltextindexed=True)
- first_name = String(required=True, fulltextindexed=True)
- title = String(vocabulary=('M', 'Mme', 'Mlle'))
- date_of_birth = Date()
- works_for = SubjectRelation('Company', cardinality='?*')
-
-* the name of the Python attribute corresponds to the name of the attribute
- or the relation in `LAX` application.
-
-* all built-in types are available: `String`, `Int`, `Float`,
- `Boolean`, `Date`, `Datetime`, `Time`, `Byte`.
-
-* each entity has at least the following meta-relations:
-
- - `eid` (`Int`)
-
- - `creation_date` (`Datetime`)
-
- - `modification_date` (`Datetime`)
-
- - `created_by` (`EUser`) (which user created the entity)
-
- - `owned_by` (`EUser`) (who does the entity belongs to, by default the
- creator but not necessarry and it could have multiple owners)
-
- - `is` (`EEType`)
-
-
-* it is also possible to define relations of type object by using `ObjectRelation`
- instead of `SubjectRelation`
-
-* the first argument of `SubjectRelation` and `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 correponding to multiple entities types
-
- * special string such as follows:
-
- - "**" : all types of entities
- - "*" : all types of entities non meta
- - "@" : all types of meta entities but not system entities (e.g. used for
- the basis 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)
-
-* optional properties for attributes and relations:
-
- - `description` : 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` : list of conditions/constraints that the relation needs to
- satisfy (c.f. `Contraints`_)
-
- - `cardinality` : two characters string which specify the cardinality of the
- relation. The first character defines the cardinality of the relation on
- the subject, the second on the object of the relation. When a relation
- has multiple possible subjects or objects, the cardinality applies to all
- and not on a one to one basis (so it must be consistent...). The possible
- values are inspired from regular expressions syntax:
-
- * `1`: 1..1
- * `?`: 0..1
- * `+`: 1..n
- * `*`: 0..n
-
- - `meta` : boolean indicating that the relation is a meta-relation (false by
- default)
-
-* optionnal 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 usefull 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 correpond to the RQL keywords `TODAY` and `NOW`.
-
- - `vocabulary` : specify static possible values of an attribute
-
-* optionnal 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)
-
-* optionnal 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 need
- to set 'object' as the value. The composition implies that when the relation
- is deleted (so when the composite is deleted), the composed are also deleted.
- [PAS CLAIR]
-
-Contraints
-``````````
-By default, the available constraints 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 needs 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
- [PAS CLAIR]
-
-
-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, as well as 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)[PAS CLAIR] by example ::
-
- class locked_by(RelationType):
- """relation on all entities indicating that they are locked"""
- inlined = True
- cardinality = '?*'
- subject = '*'
- object = 'EUser'
-
-In addition to the permissions, the own 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')
-
-* `symetric` : boolean indication that the relation is symetrical, 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 symetrical, and it does not require
-specific permissions, its definition (by using `SubjectRelation` and
-`ObjectRelation`) is all we need.
-
-Permissions definition
-----------------------
-
-Define permissions is set through to the attribute `permissions` of entities and
-relations types. It defines a dictionnary 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 define in the precreate
-of the application (``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_<ACTION>_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 <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
- [WHAT IS A NON FINALE 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 thatm the entity type `EPermission` from the standard library
-allow to build very complex and dynamic security architecture. The schema of
-this entity type is as follow: ::
-
- class EPermission(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('EGroup', 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 assumes/indicates [???] that an entity `EPermission` 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 `EPermission`, 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 [??] `RRQLExpression` on relation types for reading
-
-* special relations "has_<ACTION>_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 checks 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.
-[PAS CLAIR]
--- a/doc/book/en/04-00-define-schema.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Data model definition (*schema*)
-================================
-
-The schema is the core piece of a `CubicWeb` application as it defines
-the data model handled. It is based on entities types already defined
-in the `CubicWeb` standard library and others, more specific, we would
-expect to find in one or more Python files under the `schema` directory.
-
-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
-"<subject entity type> <relation type> <object entity type>".
-A relation type could have been implied if none is related to a
-relation definition of the schema.
-
-
-.. include:: 04-01-schema-stdlib.en.txt
-.. include:: 04-02-schema-definition.en.txt
-
--- a/doc/book/en/04-01-schema-stdlib.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Pre-defined schemas in the library
-----------------------------------
-
-The library defines a set of entities schemas that are required by the system
-or commonly used in `CubicWeb` applications.
-Of course, you can extend those schemas if necessarry.
-
-
-System schemas
-``````````````
-The system entities available are :
-
-* `EUser`, system users
-* `EGroup`, users groups
-* `EEType`, entity type
-* `ERType`, 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
-
-* `EProperty`, used to configure the application
-* `EPermission`, 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
-
-Cubes in the library
-````````````````````
-
-An application is based on several basic cubes. In the set of available
-basic cubes we can find by example :
-
-* `comment`, provides an entity type for `Comment` allowing us to comment others
- site's entities
-
-* `mailinglist`, provides an entity type for `Mailinglist` which groups informations
- in a discussion list
-
-* `file`, provides entity types for `File` et `Image` used to represent
- files (text or binary) with additionnal informations such as MIME type or
- encoding.
-
-* `link`, provides an entity type for hypertext link (`Link`)
-
-* `blog`, provides an entity type weblog (`Blog`)
-
-* `person`, provides an entity type for a person (`Person`)
-
-* `addressbook`, provides an entity type used to represent phone
- numbers (`PhoneNumber`) and mailing address (`PostalAddress`)
-
-* `classtags`, categorization system based on tags (`Tag`)
-
-* `classfolders`, categorization system based on folders hierarchy in order
- to create navigation sections (`Folder`)
-
-* `email`, archiving management for emails (`Email`, `Emailpart`,
- `Emailthread`)
-
-* `basket`, basket management (`Basket`) allowing to group entities
-
-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.
-
--- a/doc/book/en/04-02-schema-definition.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,379 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Entity type definition
-----------------------
-
-An entity type is defined by a Python class which inherits `EntityType`. The
-class name correponds to the type name. Then the content of the class contains
-the description of attributes and relations for the defined entity type,
-by example ::
-
- class Personne(EntityType):
- """A person with the properties and the relations necessarry for my
- application"""
-
- last_name = String(required=True, fulltextindexed=True)
- first_name = String(required=True, fulltextindexed=True)
- title = String(vocabulary=('M', 'Mme', 'Mlle'))
- date_of_birth = Date()
- works_for = SubjectRelation('Company', cardinality='?*')
-
-* the name of the Python attribute corresponds to the name of the attribute
- or the relation in `CubicWeb` application.
-
-* all built-in types are available : `String`, `Int`, `Float`,
- `Boolean`, `Date`, `Datetime`, `Time`, `Byte`.
-
-* each entity type has at least the following meta-relations :
-
- - `eid` (`Int`)
-
- - `creation_date` (`Datetime`)
-
- - `modification_date` (`Datetime`)
-
- - `created_by` (`EUser`) (which user created the entity)
-
- - `owned_by` (`EUser`) (who does the entity belongs to, by default the
- creator but not necessarry and it could have multiple owners)
-
- - `is` (`EEType`)
-
-
-* it is also possible to define relations of type object by using `ObjectRelation`
- instead of `SubjectRelation`
-
-* the first argument of `SubjectRelation` and `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 correponding to multiple entities 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)
-
-* optional properties for attributes and relations :
-
- - `description` : 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` : list of conditions/constraints that the relation needs to
- satisfy (c.f. `Contraints`_)
-
- - `cardinality` : two characters string which specify the cardinality of the
- relation. The first character defines the cardinality of the relation on
- the subject, the second on the object of the relation. When a relation
- has multiple possible subjects or objects, the cardinality applies to all
- and not on a one to one basis (so it must be consistent...). The possible
- values are inspired from regular expressions syntax :
-
- * `1`: 1..1
- * `?`: 0..1
- * `+`: 1..n
- * `*`: 0..n
-
- - `meta` : boolean indicating that the relation is a meta-relation (false by
- default)
-
-* optionnal 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 usefull 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 correpond to the RQL keywords `TODAY` and `NOW`.
-
- - `vocabulary` : specify static possible values of an attribute
-
-* optionnal 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)
-
-* optionnal 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 need
- to set 'object' as the 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 constraints 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 needs 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
-
-
-Relation definition
--------------------
-
-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
-contains 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) by example ::
-
- class locked_by(RelationType):
- """relation on all entities indicating that they are locked"""
- inlined = True
- cardinality = '?*'
- subject = '*'
- object = 'EUser'
-
-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`)
-
-* `symetric` : boolean indication that the relation is symetrical, 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 symetrical, and it does not require
-specific permissions, its definition (by using `SubjectRelation` and
-`ObjectRelation`) is all we need.
-
-
-The security model
-------------------
-
-Le modèle de sécurité de CubicWeb est un modèle fondé sur des `Access
-Control List`. Les notions sont les suivantes :
-
-* utilisateurs et groupes d'utilisateurs
-* un utilisateur appartient à au moins un groupe
-* droits (lire, modifier, créer, supprimer)
-* les droits sont attribués aux groupes (et non aux utilisateurs)
-
-Pour CubicWeb plus spécifiquement :
-
-* on associe les droits au niveau des schemas d'entites / relations
-
-* pour chaque type d'entité, on distingue les droits de lecture,
- ajout, modification et suppression
-
-* pour chaque type de relation, on distingue les droits de lecture,
- ajout et suppression (on ne peut pas modifer une relation)
-
-* les groupes de base sont : Administrateurs, Utilisateurs, Invités
-
-* les utilisateurs font par défaut parti du groupe Utilisateurs
-
-* on a un groupe virtuel "Utilisateurs Propriétaires", auquel on peut
- associer uniquement les droits de suppression et de modification
-
-* on ne peut pas mettre d'utilisateurs dans ce groupe, ils y sont
- ajoutés implicitement dans le contexte des objets dont ils sont
- propriétaires
-
-* les droits de ce groupe ne sont vérifiés que sur
- modification / suppression si tous les autres groupes auxquels
- l'utilisateur appartient se sont vu interdir l'accès
-
-
-Permissions definition
-``````````````````````
-
-Define permissions is set through to the attribute `permissions` of entities and
-relations types. It defines a dictionnary 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_<ACTION>_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 <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 `EPermission` from the standard library
-allow to build very complex and dynamic security architecture. The schema of
-this entity type is as follow : ::
-
- class EPermission(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('EGroup', 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 `EPermission` 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 `EPermission`, 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_<ACTION>_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.
--- a/doc/book/en/05-00-define-views.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,238 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _DefinitionVues:
-
-Views definition
-================
-
-Basic class for views
----------------------
-
-Class `View` (`cubicweb.common.view`)
-`````````````````````````````````````
-
-A view writes in its output exit thanks to its attribute `w` (`UStreamIO`).
-
-The basic interface for views is as follows:
-
-* `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
-* `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`
-
-* `creator(eid)`, returns the eid and the login of the entity creator of the entity
- having the eid given in the parameter
-
-Other basic classes:
-
-* `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
-
-
-The selection view principle
-----------------------------
-
-A view includes :
-
-- an identifier (all objects in `LAX` are entered in a registry
- and this identifier will be used as a key)
-
-- a filter to select the resulsets it can be applied to
-
-
-For a given identifier, multiple views can be defined. `CubicWeb` uses
-a selector which computes scores so that it can identify and select the
-best view to apply in context. The selector library is in
-``cubicweb.common.selector`` and a library of the methods used to
-compute scores is in ``cubicweb.vregistry.vreq``.
-
-
-`CubicWeb` provides a lot of standard views, for a complete list, you
-will have to read the code in directory ``cubicweb/web/views/`` (XXX
-improve doc).
-
-For example, the view named ``primary`` is the one used to display
-a single entity.
-
-If you want to change the way a ``BlogEntry`` is displayed, just
-override the view ``primary`` in ``BlogDemo/views.py`` ::
-
- 01. from ginco.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'<h1>%s</h1>' % entity.title)
- 10. self.w(u'<p>published on %s in category %s</p>' % \
- 11. (entity.publish_date.strftime('%Y-%m-%d'), entity.category))
- 12. self.w(u'<p>%s</p>' % entity.text)
-
-The above source code defines a new primary view (`line 03`) for
-``BlogEntry`` (`line 05`).
-
-Since views are applied to resultsets and resulsets can be tables of
-data, it is needed to recover the entity from its (row,col)
-coordinates (`line 08`). We will get to this in more detail later.
-
-The view has a ``self.w()`` method that is used to output data. Here `lines
-09-12` output HTML tags and values of the entity's attributes.
-
-When displaying same blog entry as before, you will notice that the
-page is now looking much nicer.
-
-.. 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'<h1>%s</h1>' % entity.title)
- 08. self.w(u'<p>%s</p>' % 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.
-
-At `line 09`, a simple request in made to build a resultset 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 resultset. At
-`line 10` the view 'primary' is applied to this resultset to output
-HTML.
-
-**This is to be compared to interfaces and protocols in object-oriented
-languages. Applying a given view to all the entities of a resultset only
-requires the availability, for each entity of this resultset, of a
-view with that name that can 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 resultset 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 cubicwweb.interfaces.ICalendarable interfaces on
-entities.BloEntry and apply the OneMonthCalendar and iCalendar views
-to resultsets 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 view that does 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 (it is not used in case an error is raised or for
-the login form by 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 necessarry
-2. identifying the view to use to render data if it is not specified
-3. composing the HTML page to return
-
-
-The default main template (`cubicweb.web.views.basetemplates.TheMainTemplate`)
-------------------------------------------------------------------------------
-
-The default main template build the page based on the following pattern:
-
-.. image:: images/main_template_layout.png
-
-The rectangle containing `view.dispathc()` 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 dictionnary of the forms parameters, before going the classic way (through
- step 1 and 2 described juste above)
-
-.. include:: 05-01-views-stdlib.en.txt
-
-
-XML views, binaries...
-----------------------
-For the views generating other formats that HTML (an image generated dynamically
-by example), and which can not usually be included in the HTML page generated
-by the main template (see above), you have to:
-
-* set the atribute `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 the views dedicated to binary content creation (an image dynamically generated
-by example), we have to set the attribute `binary` of the class to `True` (which
-implies that `templateable == 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 by example) are not happy with empty `<div>`
-(by empty we mean that there is no content in the tag, but there
-could be attributes), so we should always use `<div></div>` even if
-it is empty and not use `<div/>`.
-
--- a/doc/book/en/05-01-views-stdlib.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Predefined views in the library
--------------------------------
-
-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
- entity is in the result set and needs to be displayed. This view is supposed
- to render a maximum of informations about the entity.
-:secondary:
- secondary view of an entity. By default it renders the two first attributes
- of the entity as a clickable link redirecting to the primary view.
-:oneline:
- 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.
-:text:
- similar to the `oneline` view, but should not contain HTML.
-: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 is 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:
- creates a HTML list (`<ul>`) and call the view `listitem` for each entity
- of the result set
-:listitem:
- 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 dunblin core
- methods of the entity (`dc_*`)
-
-Start view:
-
-:index:
- home page
-:schema:
- display the schema of the application
-
-Special views:
-
-:noresult:
- called if the result set is empty
-:finall:
- 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 (`<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:
- view always applicable and which does not return anything
--- a/doc/book/en/06-00-define-workflows.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,155 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Workflow definition
-======================
-
-On peut mettre une condition rql ou/et un groupe auquel doit appartenir l'utilisateur.
-
-Si on met à la fois un(ou plusieurs) groupe et une condition RQL, il faut que les deux soient respectés.
-
-Si on met plusieurs groupes, il faut que l'utilisateur soit dans un des groupes.
-
-Pour la condition RQL sur une transition, on peut y mettre les substitutions suivantes :
-
-* `%(eid)s`, eid de l'objet
-* `%(ueid)s`, eid de l'utilisateur qui fait la requête
-* `%(seid)s`, eid de l'état courant de l'objet
-
-Dans le script de création d'un workflow, penser à mettre `_()` autour des noms d'états et de transitions
-pour que ceux si soient pris en compte par les scripts de gestion des catalogues i18n.
-
-General
--------
-
-A workflow can be defined in a `LAX` application thanks to the system
-entities ``State`` and ``Transition``. Those are defined within all
-LAX application and can be set-up through the main administrator interface.
-
-Once your schema is defined, you can start creating the set of states and
-the required transitions for your applications entities.
-
-You first need to define the states and then the transitions between those
-to complete your workflow.
-
-A ``State`` defines the status of an entity. While creating a new state,
-you will be first given the option to select the entity type the state
-can be applied to. By choosing ``Apply``, a new section will be displayed
-in the editing screen to enable you to add relation to the state you are
-creating.
-
-A ``Transition`` is also based on an entity type it can be applied to.
-By choosing ``Apply``, a new section will be displayed in the editing
-screen to enable you to add relation to the transition you are
-creating.
-
-At the transition level you will also define the group of user which can
-aplly this transition to an object.
-
-
-Example of a simple workflow
-----------------------------
-
-Please see the tutorial to view and example of a simple workflow.
-
-
-[Create a simple workflow for BlogDemo, to have a moderator approve new blog
-entry to be published. This implies, specify a dedicated group of blog
-moderator as well as hide the view of a blog entry to the user until
-it reaches the state published]
-
-Set-up a workflow
------------------
-
-Before starting, make sure you refresh your mind by reading [link to
-definition_workflow chapter].
-
-We want to create a workflow to control the quality of the BlogEntry
-submitted on your application. When a BlogEntry is created by a user
-its state should be `submitted`. To be visible to all, it needs to
-be in the state `published`. To move from `submitted` to `published`
-we need a transition that we can name `approve_blogentry`.
-
-We do not want every user to be allowed to change the state of a
-BlogEntry. We need to define a group of user, `moderators`, and
-this group will have appropriate permissions to approve BlogEntry
-to be published and visible to all.
-
-There are two ways to create a workflow, form the user interface,
-and also by defining it in ``migration/postcreate.py``. This script
-is executed each time a new ``./bin/laxctl db-init`` is done.
-If you create the states and transitions through the user interface
-this means that next time you will need to initialize the database
-you will have to re-create all the entities.
-We strongly recommand you create the workflow in ``migration\postcreate.py``
-and we will now show you how.
-The user interface would only be a reference for you to view the states
-and transitions but is not the appropriate interface to define your
-application workflow.
-
-Update the schema
-~~~~~~~~~~~~~~~~~
-To enable a BlogEntry to have a State, we have to define a relation
-``in_state`` in the schema of BlogEntry. Please do as follows, 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 will have re-execute ``./bin/laxctl db-init``
-to initialize the database and migrate your existing entities.
-[WRITE ABOUT MIGRATION]
-
-Create states, transitions and group permissions
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-At the time the ``postcreate.py`` script is executed, several methods
-can be used. They are all defined in the ``class ServerMigrationHelper``.
-We will only discuss the method we use to create a wrokflow here.
-
-To define our workflow for BlogDemo, please add the following lines
-to ``migration/postcreate.py``::
-
- _ = unicode
-
- moderators = add_entity('EGroup', name=u"moderators")
-
- submitted = add_state(_('submitted'), 'BlogEntry', initial=True)
- published = add_state(_('published'), 'BlogEntry')
-
- add_transition(_('approve_blogentry'), 'BlogEntry', (submitted,), published, ('moderators', 'managers'),)
-
- checkpoint()
-
-``add_entity`` is used here to define the new group of users that we
-need to define the transitions, `moderators`.
-If this group required by the transition is not defined before the
-transition is created, it will not create the relation `transition
-require the group moderator`.
-
-``add_state`` expects as the first argument the name of the state you are
-willing to create, then the entity type on which the state can be applied,
-and an optionnal argument to set if the state is the initial state
-of the entity type or not.
-
-``add_transition`` expects as the first argument the name of the
-transition, then the entity type on which we can apply the transition,
-then the list of possible initial states from which the transition
-can be applied, the target state of the transition, and the permissions
-(e.g. list of the groups of users who can apply the transition).
-
-.. image:: images/lax-book.03-transitions-view.en.png
-
-You can now notice that in the actions box of a BlogEntry, the state
-is now listed as well as the possible transitions from this state
-defined by the workflow. This transition, as defined in the workflow,
-will only being displayed for the users belonging to the group
-moderators of managers.
-
-
--- a/doc/book/en/07-00-data-as-objects.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,142 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-
-Manipulation des données stockées
-=================================
-
-Les classes `Entity` et `AnyEntity`
------------------------------------
-Pour fournir un comportement spécifique à un type d'entité, il suffit de définir
-une classe héritant de la class `ginco.entities.AnyEntity`. En général il faut
-définir ces classes dans un module du package `entities` d'une application pour
-qu'elle soit disponible à la fois coté serveur et coté client.
-
-La classe `AnyEntity` est une classe chargée dynamiquement héritant de la classe
-de base `Entity` (`ginco.common.entity`). On définit une sous-classe pour
-ajouter des méthodes ou spécialiser les comportements d'un type d'entité donné.
-
-Des descripteurs sont ajoutés à l'enregistrement pour initialiser la classe en
-fonction du schéma :
-
-* on peut accéder aux attributs définis dans le schéma via les attributs de même
- nom sur les instances (valeur typée)
-
-* on peut accéder aux relations définies dans le schéma via les attributs de même
- nom sur les instances (liste d'instances d'entité)
-
-Les méthodes définies sur la classe `AnyEntity` ou `Entity` sont les suivantes :
-
-* `has_eid()`, retourne vrai si l'entité à un eid affecté (i.e. pas en cours de
- création)
-
-* `check_perm(action)`, vérifie que l'utilisateur à le droit d'effectuer
- l'action demandée sur l'entité
-
-:Formattage et génération de la sortie:
-
- * `view(vid, **kwargs)`, applique la vue donnée à l'entité
-
- * `absolute_url(**kwargs)`, retourne une URL absolue permettant d'accéder à la
- vue primaire d'une entité
-
- * `rest_path()`, renvoie une l'URL REST relative permettant d'obtenir l'entité
-
- * `format(attr)`, retourne le format (type MIME) du champ passé en argument
-
- * `printable_value(attr, value=_marker, attrtype=None, format='text/html')`,
- retourne une chaine permettant l'affichage dans un format donné de la valeur
- d'un attribut (la valeur est automatiquement récupérée au besoin)
-
- * `display_name(form='')`, retourne une chaîne pour afficher le type de
- l'entité, en spécifiant éventuellement la forme désirée ('plural' pour la
- forme plurielle)
-
-:Gestion de données:
-
- * `as_rset()`, transforme l'entité en un resultset équivalent simulant
- le résultat de la requête `Any X WHERE X eid _eid_`
-
- * `complete(skip_bytes=True)`, effectue une requête permettant de récupérer d'un
- coup toutes les valeurs d'attributs manquant sur l'entité
-
- * `get_value(name)`, récupere la valeur associée à l'attribut passé en argument
-
- * `related(rtype, x='subject', limit=None, entities=False)`, retourne une liste
- des entités liées à l'entité courant par la relation donnée en argument
-
- * `unrelated(rtype, targettype, x='subject', limit=None)`, retourne un result set
- des entités not liées à l'entité courante par la relation donnée en argument
- et satisfaisants les contraintes de celle-ci
-
- * `set_attributes(**kwargs)`, met à jour la liste des attributs avec
- les valeurs correspondantes passées sous forme d'arguments nommés
-
- * `copy_relations(ceid)`, copie les relations de l'entité ayant l'eid passé en
- argument sur l'entité courante
-
- * `last_modified(view)`, retourne la date à laquelle on doit considérer
- l'objet comme modifié (utiliser par la gestion de cache HTTP)
-
- * `delete()` permet de supprimer l'entité représentée
-
-:Meta-données standard (Dublin Core):
-
- * `dc_title()`, retourne une chaine unicode correspondant à la méta-donnée
- 'Title' (utilise par défaut le premier attribut non 'meta' du schéma de
- l'entité)
-
- * `dc_long_title()`, comme dc_title mais peut retourner un titre plus détaillé
-
- * `dc_description(format='text/plain')`, retourne une chaine unicode
- correspondant à la méta-donnée 'Description' (cherche un attribut
- 'description' par défaut)
-
- * `dc_authors()`, retourne une chaine unicode correspondant à la méta-donnée
- 'Authors' (propriétaires par défaut)
-
- * `dc_date(date_format=None)`, retourne une chaine unicode
- correspondant à la méta-donnée 'Date' (date de modification par défaut)
-
-:Contrôle du vocabulaire pour les relations:
-
- * `vocabulary(rtype, x='subject', limit=None)`, appelée notamment
- par les vues d'édition d'erudi, elle renvoie une liste de couple
- (label, eid) des entités qui pourraient être liées à l'entité
- via la relation `rtype`
- * `subject_relation_vocabulary(rtype, limit=None)`, appelée
- en interne par `vocabulary` dans le cas d'une relation sujet
- * `object_relation_vocabulary(rtype, limit=None)`, appelée
- en interne par `vocabulary` dans le cas d'une relation objet
- * `relation_vocabulary(rtype, targettype, x, limit=None)`, appelé
- en interne par `subject_relation_vocabulary` et `object_relation_vocabulary`
-
-
-Les *rtags*
------------
-Les *rtags* permettent de spécifier certains comportements propres aux relations
-d'un type d'entité donné (voir plus loin). Ils sont définis sur la classe
-d'entité via l'attribut `rtags` qui est un dictionnaire dont les clés sont un
-triplet ::
-
- <type de relation>, <type d'entité cible>, <position du contexte ("subject" ou "object"
-
-et les valeurs un `set` ou un tuple de marqueurs définissant des propriétés
-s'appliquant à cette relation.
-
-Il est possible de simplifier ce dictionnaire :
-
-* si l'on veut spécifier un seul marqueur, il n'est pas nécessaire d'utiliser
- un tuple comme valeur, le marqueur seul (chaine de caractères) suffit
-* si l'on s'intéresse uniquement à un type de relation et non à la cible et à la
- position du contexte (ou que celui-ci n'est pas ambigüe), on peut simplement
- utiliser le nom du type de relation comme clé
-* si l'on veut qu'un marqueur s'applique quelque soit le type d'entité cible, il
- faut utiliser la chaine `*` comme type d'entité cible
-
-A noter également que ce dictionnaire est *traité à la création de la classe*.
-Il est automatiquement fusionné avec celui de la ou des classe(s) parentes (pas
-besoin de copier celui de la classe parent pour le modifier). De même modifier
-celui-ci après création de la classe n'aura aucun effet...
-
-
-.. include:: 07-01-define-entities.en.txt
--- a/doc/book/en/07-01-define-entities.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,168 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Paramétrages et extensions spécifiques
---------------------------------------
-
-Valeurs par défaut dynamiques
-`````````````````````````````
-Il est possible de définir dans le schéma des valeurs par défaut *statiques*.
-Il est également possible de définir des valeurs par défaut *dynamiques* en
-définissant sur la classe d'entité une méthode `default_<nom attribut>` pour
-un attribut donnée.
-
-
-Contrôle des attributs chargés et du tri par défaut
-```````````````````````````````````````````````````
-* l'attribut de classe `fetch_attrs` permet de définir sur une classe d'entité
- la liste des noms des attributs ou relations devant être chargés
- automatiquement lors de la récupération d'entité(s) de ce type. Dans le cas
- des relations, on est limité aux relations *sujets de cardinalité `?` ou `1`*.
-
-* la méthode de classe `fetch_order(attr, var)` prend en argument un nom
- d'attribut (ou de relation) et un nom de variable et doit retourner une chaine
- à utiliser dans la close "ORDERBY" d'une requête RQL pour trier
- automatiquement les listes d'entités de ce type selon cet attribut, ou `None`
- si l'on ne veut pas de tri sur l'attribut passé en argument. Par défaut les
- entités sont triées selon leur date de création
-
-* la méthode de classe `fetch_unrelated_order(attr, var)` est similaire à la
- méthode `fetch_order` mais est utilisée essentiellement pour contrôler le tri
- des listes déroulantes permettant de créer des relations dans la vue d'édition
- d'une entité
-
-La fonction `fetch_config(fetchattrs, mainattr=None)` permet de simplifier la
-définition des attributs à précharger et du tri en retournant une liste des
-attributs à précharger (en considérant ceux de la classe `AnyEntity`
-automatiquement) et une fonction de tri sur l'attribut "principal" (le 2eme
-argument si spécifié ou sinon le premier attribut de la liste `fetchattrs`).
-Cette fonction est définie dans le package `ginco.entities`.
-
-Par exemple : ::
-
- class Transition(AnyEntity):
- """..."""
- id = 'Transition'
- fetch_attrs, fetch_order = fetch_config(['name'])
-
-Indique que pour le type d'entité "Transition" il faut précharger l'attribut
-"name" et trier par défaut selon cet attribut.
-
-
-Contrôle des formulaires d'édition
-``````````````````````````````````
-Il est possible de contrôler les attributs/relations dans la vue d'édition
-simple ou multiple à l'aide des *rtags* suivants :
-
-* `primary`, indique qu'un attribut ou une relation doit être incorporé dans
- les formulaires d'édition simple et multiple. Dans le cas d'une relation,
- le formulaire d'édition de l'entité liée sera inclus dans le formulaire
-
-* `secondary`, indique qu'un attribut ou une relation doit être incorporé dans
- le formulaire d'édition simple uniquement. Dans le cas d'une relation,
- le formulaire d'édition de l'entité liée sera inclus dans le formulaire
-
-* `generic`, indique qu'une relation doit être incorporé dans le formulaire
- d'édition simple dans la boite générique d'ajout de relation
-
-* `generated`, indique qu'un attribut est caculé dynamiquement ou autre, et
- qu'il ne doit donc pas être présent dans les formulaires d'édition
-
-Au besoin il est possible de surcharger la méthode
-`relation_category(rtype, x='subject')` pour calculer dynamiquement la catégorie
-d'édition d'une relation.
-
-
-Contrôle de la boîte "add_related"
-``````````````````````````````````
-La boite `add related` est une boite automatique proposant de créer une entité
-qui sera automatiquement liée à l'entité de départ (le contexte dans lequel
-s'affiche la boite). Par défaut, les liens présents dans cette boite sont
-calculés en fonction des propriétés du schéma de l'entité visualisée, mais il
-est possible de les spécifier explicitement à l'aide des *rtags* suivants :
-
-* `link`, indique qu'une relation est généralement créée vers une entité
- existante et qu'il ne faut donc pas faire apparaitre de lien pour cette
- relation
-
-* `create`, indique qu'une relation est généralement créée vers de nouvelles
- entités et qu'il faut donc faire apparaitre un lien pour créer une nouvelle
- entité et la lier automatiquement
-
-Au besoin il est possible de surcharger la méthode
-`relation_mode(rtype, targettype, x='subject')` pour caculer dynamiquement la
-catégorie de création d'une relation.
-
-A noter également que si au moins une action dans la catégorie "addrelated" est
-trouvée pour le contexte courant, le fonctionnement automatique est désactivé
-en faveur du fonctionnement explicite (i.e. affichage des actions de la
-catégorie "addrelated" uniquement).
-
-Contrôle des formulaires de filtrage de table
-`````````````````````````````````````````````
-La vue "table" par défaut gère dynamiquement un formulaire de filtrage du
-contenu de celle-ci. L'algorithme est le suivant :
-
-1. on considère que la première colonne contient les entités à restreindre
-2. on recupère la première entité de la table (ligne 0) pour "représenter"
- toutes les autres
-3. pour toutes les autres variables définies dans la requête originale :
-
- 1. si la variable est liée à la variable principale par au moins une
- n'importe quelle relation
- 2. on appelle la méthode `filterform_vocabulary(rtype, x)` sur l'entité
- et si rien est retourné (ou plus exactement un tuple de valeur `None`,
- voir ci-dessous) on passe à la variable suivante, sinon un élément de
- formulaire de filtrage sera créé avec les valeurs de vocabulaire
- retournées
-
-4. il n'y a pas d'autres limitations sur le rql, il peut comporter des clauses
- de tris, de groupes... Des fonctions javascripts sont utilisées pour
- regénérer une requête à partir de la requête de départ et des valeurs
- séléctionnées dans les filtres de formulaire.
-
-
-La méthode `filterform_vocabulary(rtype, x, var, rqlst, args, cachekey)` prend
-en argument le nom d'une relation et la "cible", qui indique si l'entité sur
-laquelle la méthode est appellée est sujet ou objet de la relation. Elle doit
-retourner :
-
-* un 2-uple de None si elle ne sait pas gérer cette relation
-
-* un type et une liste contenant le vocabulaire
-
- * la liste doit contenir des couples (valeur, label)
- * le type indique si la valeur désigne un nombre entier (`type == 'int'`), une
- chaîne de caractères (`type == 'string'`) ou une entité non finale (`type
- == 'eid'`)
-
-Par exemple dans notre application de gestion de tickets, on veut pouvoir
-filtrés ceux-ci par :
-
-* type
-* priorité
-* état (in_state)
-* étiquette (tags)
-* version (done_in)
-
-On définit donc la méthode suivante : ::
-
-
- 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: Le support du filtrage sur les étiquettes et l'état est installé
-automatiquement, pas besoin de le gérer ici.
--- a/doc/book/en/08-00-site-config.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Interface de configuration du site
-==================================
-
-.. 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]
-
--- a/doc/book/en/09-00-instance-config.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,162 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Configuration d'une instance
-============================
-
-À la création d'une instance, un fichier de configuration est généré dans ::
-
- $(CW_REGISTRY)/<instance>/<nom configuration>.conf
-
-par exemple ::
-
- /etc/cubicweb.d/jpl/all-in-one.conf
-
-C'est un simple fichier texte au format INI. Dans la description suivante,
-chaque nom d'option est préfixé de sa section et suivi de sa valeur par défaut
-le cas échéant, e.g. "`<section>.<option>` [valeur]".
-
-
-Configuration du serveur web
-----------------------------
-:`web.auth-mode` [cookie]:
- mode d'authentification, cookie ou http
-:`web.realm`:
- realm de l'application en mode d'authentification http
-:`web.http-session-time` [0]:
- délai d'inactivité d'une session HTTP avant sa fermeture automatique. Durée
- en secondes, 0 signifiant pas d'expiration (ou plus exactement lors de la
- fermeture du navigateur du client)
-
-:`main.anonymous-user`, `main.anonymous-password`:
- login et mot de passe à utiliser pour se connecter au serveur RQL lors des
- connexions HTTP anonymes. Il faut que le compte EUser associé existe.
-
-:`main.base-url`:
- url de base du site, à utiliser pour générer les urls des pages web
-
-Configuration https
-```````````````````
-Il est possible de rendre un site accessible en http pour les connections
-anonymes et en https pour les utilisateurs authentifié. Il faut pour cela
-utiliser apache (par ex.) pour la redirection et la variable `main.https-url` du
-fichier de configuration.
-
-:Exemple:
-
- pour une redirection apache d'un site accessible via `http://localhost/demo`
- et `https://localhost/demo` et qui tourne en réalité sur le port 8080, il
- faut avoir pour la version http : ::
-
- RewriteCond %{REQUEST_URI} ^/demo
- RewriteRule ^/demo$ /demo/
- RewriteRule ^/demo/(.*) http://127.0.0.1:8080/$1 [L,P]
-
- et pour la version https : ::
-
- RewriteCond %{REQUEST_URI} ^/demo
- RewriteRule ^/demo$ /demo/
- RewriteRule ^/demo/(.*) http://127.0.0.1:8080/https/$1 [L,P]
-
-
- et on aura dans le fichier all-in-one.conf de l'instance : ::
-
- base-url = http://localhost/demo
- https-url = `https://localhost/demo`
-
-Configuration de l'interface web
---------------------------------
-:`web.embed-allowed`:
- expression régulière correspondant aux sites pouvant être "incorporé" dans
- le site (controleur 'embed')
-:`web.submit-url`:
- url à laquelle les bugs rencontrés dans l'application peuvent être posté
-
-
-Configuration du serveur RQL
-----------------------------
-:`main.host`:
- nom de l'hôte s'il ne peut être détecter correctement
-:`main.pid-file`:
- fichier où sera écrit le pid du serveur
-:`main.uid`:
- compte utilisateur à utiliser pour le lancement du serveur quand il est
- lancé en root par init
-:`main.session-time [30*60]`:
- temps d'expiration d'une session RQL
-:`main.query-log-file`:
- fichier dans lequel écrire toutes les requêtes RQL éxécutées par le serveur
-
-
-Configuration Pyro pour l'instance
------------------------------------
-Coté serveur web :
-
-:`pyro-client.pyro-application-id`:
- identifiant pyro du serveur RQL (e.g. le nom de l'instance)
-
-Coté serveur RQL :
-
-:`pyro-server.pyro-port`:
- numéro de port pyro. Si aucune valeur n'est spécifiée, un port est attribué
- automatiquement.
-
-Coté serveur RQL et serveur web :
-
-:`pyro-name-server.pyro-ns-host`:
- nom de l'hôte hébergeant le serveur de nom pyro. Si aucune valeur n'est
- spécifié, il est localisé par une requête de broadcast
-:`pyro-name-server.pyro-ns-group` [cubicweb]:
- groupe pyro sous lequel enregistrer l'application
-
-
-Configuration courriel
-----------------------
-Coté serveur RQL et serveur web :
-
-:`email.mangle-emails [no]`:
- indique si les adresses email doivent être affichées telle quelle ou
- transformée
-
-Coté serveur RQL :
-
-:`email.smtp-host [mail]`:
- nom de l'hôte hébergeant le serveur SMTP à utiliser pour le courriel sortant
-:`email.smtp-port [25]`:
- port du serveur SMTP à utiliser pour le courriel sortant
-:`email.sender-name`:
- nom à utiliser pour les courriels sortant de l'application
-:`email.sender-addr`:
- adresse à utiliser pour les courriels sortant de l'application
-:`email.default-dest-addrs`:
- adresses de destination par défaut, si utilisé par la configuration de la
- diffusion du modèle (séparées par des virgules)
-:`email.supervising-addrs`:
- addresses de destination des courriels de supervision (séparées par des
- virgules)
-
-
-Configuration journalisation
-----------------------------
-:`main.log-threshold`:
- niveau de filtrage des messages (DEBUG, INFO, WARNING, ERROR)
-:`main.log-file`:
- fichier dans lequel écrire les messages
-
-
-Configuration Eproperties
--------------------------
-D'autres paramètres de configuration sont sous la forme d'entités `EProperty`
-dans la base de données. Il faut donc les éditer via l'interface web ou par des
-requêtes rql.
-
-:`ui.encoding`:
- encodage de caractères à utiliser pour l'interface web
-:`navigation.short-line-size`: # XXX should be in ui
- nombre de caractères maximum pour les affichages "courts"
-:`navigation.page-size`:
- nombre d'entités maximum à afficher par page de résultat
-:`navigation.related-limit`:
- nombre d'entités liées maximum à afficher sur la vue primaire d'une entité
-:`navigation.combobox-limit`:
- nombre d'entités non liées maximum à afficher sur les listes déroulantes de
- la vue d'édition d'une entité
--- a/doc/book/en/10-00-form-management.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,133 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Gestion de formulaires
-======================
-
-Contrôle de la génération automatique de formulaire pour les entités manipulée
-------------------------------------------------------------------------------
-XXX FILLME
-
-* les formulaires 'edition' et 'creation'
-
-Le formulaire généré par défaut ne vous convient pas ? Vous êtes peut-être pas
-obligé de le refaire à la main ! :)
-
-* rtags primary, secondary, generated, generic,
- `Entity.relation_category(rtype, x='subject')`
-* inline_view (now a rtag?)
-* spécification widget
-
-
-Fonctionnement du contrôleur d'édition par défaut (id: 'edit')
---------------------------------------------------------------
-
-Contrôle de l'édition
-`````````````````````
-Prérequis: les paramètres liés aux entités à éditer sont spécifiés de la forme ::
-
- <nom de champ>:<eid de l'entité>
-
-où l'eid de l'entité pourra être une lettre dans le cas d'une entité à créer. On
-dénommera ces paramètres comme *qualifié*.
-
-1. récupération des entités à éditer en cherchant les paramètres de formulaire
- commençant par 'eid:' ayant également un paramètre '__type' associé
- (également *qualifié* par l'eid évidemment)
-
-2. pour tous les attributs et relations de chaque entité à éditer
-
- 1. recherche d'un paramètre 'edits-<nom relation>' ou 'edito-<nom relation>'
- qualifié dans le cas d'une relation dont l'entité est objet
- 2. si trouvé, la valeur récupérée est considérée comme la valeur originale
- pour cette relation, et on cherche la (ou les) nouvelle(s) valeur(s) dans
- le paramètre <nom relation> (qualifié)
- 3. si la valeur est différente de l'originale, une requête de modification en
- base est effectuée
-
-3. pour chaque entité à éditer
-
- 1. si un paramètre `__linkto` qualifié est spécifié, sa valeur doit être une
- chaine (ou une liste de chaine) de la forme : ::
-
- <relation type>:<eids>:<target>
-
- où <target> vaut 'subject' ou 'object' et chaque eid peut-être séparé d'un
- autre par un '_'. Target spécifie *l'entité éditée* est sujet ou objet de la
- relation et chaque relation ainsi spécifiée sera insérée.
-
- 2. si un paramètre `__cloned_eid` qualifié est spécifié pour une entité, les
- relations de l'entité spécifiée en valeur de cette argument sont copiées sur
- l'entité éditée
-
-
- 3. si un paramètre `__delete` qualifié est spécifié, sa valeur doit être une
- chaine (ou une liste de chaine) de la forme : ::
-
- <subject eids>:<relation type>:<object eids>
-
- où chaque eid sujet ou objet peut-être séparé d'un autre par un '_'. Chaque
- relation ainsi spécifiée sera supprimée.
-
- 4. si un paramètre `__insert` qualifié est spécifié, sa valeur doit être de
- même format que pour `__delete`, mais chaque relation ainsi spécifiée sera
- insérée.
-
-4. si les paramètres `__insert` et/ou `__delete` sont trouvés non qualifiés,
- ils sont interprétés comme décrit ci-dessus (quelque soit le nombre d'entité
- édité)
-
-5. si aucune entité n'est éditée mais que le formulaire contient les paramètres
- `__linkto` et `eid`, celui-ci est interprété en prenant la valeur spécifié
- par le paramètre `eid` pour désigner l'entité sur laquelle ajouter les
- relations
-
-
-A noter que :
-
-* si le paramètre `__action_delete` est trouvé, toutes les entités comme
- spécifiées à éditer seront supprimées
-
-* si le paramètre `__action_cancel` est trouvé, aucune action n'est effectuée
-
-* si le paramètre `__action_apply` est trouvé, l'édition est effectuée
- normalement mais la redirection sera effectuée sur le formulaire (cf `Contrôle
- de la redirection`_)
-
-* le paramètre `__method` est également supporté comme sur le template principal
- (XXX not very consistent, maybe __method should be dealed in the view controller)
-
-* si aucune entité à éditer n'est trouvée et qu'il n'y a pas de paramètre
- `__action_delete`, `__action_cancel`, `__linkto`, `__delete` ou `__insert`,
- une erreur est levée
-
-* placer dans le formulaire le paramètre `__message` permettra d'utiliser la
- valeur de ce paramètre comme message d'information à l'utilisateur une fois
- l'édition effectuée.
-
-
-Contrôle de la redirection
-``````````````````````````
-Une fois que l'édition s'est bien passé, reste un problème : c'est bien beau
-tout ça, mais où qu'on va maintenant ?? Si rien n'est spécifié, le controlleur
-se débrouille, mais comme il fait pas toujours ce qu'on voudrait, on peut
-controller ça en utilisant les paramètres suivant :
-
-* `__redirectpath`: chemin de l'url (relatif à la racine du site, sans paramètre
- de formulaire
-
-* `__redirectparams`: paramètres de formulaires à ajouter au chemin
-
-* `__redirectrql`: requête RQL de redirection
-
-* `__redirectvid`: identifiant de vue de redirection
-
-* `__errorurl`: url du formulaire original, utilisé pour la redirection en cas
- d'erreur de validation pendant l'édition. Si celui-ci n'est pas spécifié, une
- page d'erreur sera présentée plutot qu'un retour sur le formulaire (qui est le
- cas échéant responsable d'afficher les erreurs)
-
-* `__form_id`: identifiant de vue du formulaire original, utilisée si
- `__action_apply` est trouvé
-
-En général on utilise soit `__redirectpath et `__redirectparams` soit
-`__redirectrql` et `__redirectvid`.
--- a/doc/book/en/11-00-ajax-json.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /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
--- a/doc/book/en/12-00-internationalization.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _internationalization:
-
-
-Internationalization
-====================
-
-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 internalization
-----------------------
-
-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'<div class="searchMessage"><strong>%s</strong></div>\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 translation string
-it-self, but not it's translation.
-
-In the other hand the request's method `_` is ment to retrive 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 internalization 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 dont
- need to use this command.
-
-* `i18nupdate` updates the translation catalogs of *one particular
- component* (or of all components). FIXME 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 transaltion 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/<lang>/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 <component>`
-2. Edit the <component>/xxx.po files and add missing translations (empty `msgstr`)
-3. `hg ci -m "updated i18n catalogs"`
-4. `cubicweb-ctl i18n compile <myapplication>`
-
--- a/doc/book/en/12-00-reference.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-API Reference
-=============
-
-Schema API
-----------
-
-Base Types
-~~~~~~~~~~
-
-Base types are defined as a set in yams.BASE_TYPES that includes:
-`String`, `Int`, `Float`, `Boolean`, `Date`, `Time`, `Datetime`,
-`Interval`, `Password`, `Bytes`.
-
-See `yams' API <http://lax.logilab.org/apidoc>`_
-
-Constraints
-~~~~~~~~~~~
-
-Constraints are defined in yams.constraints and include:
-`UniqueConstraint`, `SizeConstraint`, `RegexpConstraint`,
-`BoundConstraint`, `IntervalBoundConstraint`,
-`StaticVocabularyConstraint`, `MultipleStaticVocabularyConstraint`.
-
-See `yams' API <http://lax.logilab.org/apidoc>`_
-
-Views API
----------
-
-See `yams' API <http://lax.logilab.org/apidoc>`_
-[WRITE ME]
-
--- a/doc/book/en/12-00-ui-components.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-Autres composants de l'interface web
-====================================
-
-Actions
--------
-XXXFILLME
-
-Component, VComponent
----------------------
-XXXFILLME
-
-EProperty
----------
-XXXFILLME
--- a/doc/book/en/14-00-hooks.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Les crochets (*hooks*)
-======================
-
-XXX FILLME
-
-Les crochets sont appelés avant ou après la mise à jour d'une entité ou d'une
-relations dans le dépot
-
-Leur prototypes sont les suivants
-
-
- * 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
-
--- a/doc/book/en/15-00-notifications.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Gestion de notifications
-========================
-
-XXX FILLME
--- a/doc/book/en/16-00-rql.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,216 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-RQL language (Relation Query Language)
-======================================
-
-XXX see also RQL documentation in source rql/doc.
-
-
-Introduction
-------------
-* RQL language focuses on browsing relations.
-* Attributes are considered as particular relations.
-* RQL is inspired from SQL but is a high level language.
-* A good knowledge of Erudi's schemas defining the application is required.
-
-
-Types of requests
------------------
-
-Search (`Any`)
- query the repository to extract entities and/or attributes.
-
-Insertion (`INSERT`)
- insert new entities in the database.
-
-Updates of entities, creation of relations (`SET`)
- update existing entities in the database, or create relations between existing
- entities
-
-Deletion of entities or relations (`DELETE`)
- delete existing entities and relations from the database.
-
-
-Variables and typing
---------------------
-
-Entities and values to browse and/or select are set in the query through *variables*
-which should be written in capital letters.
-
-The possible types for each variable can be deducted from the schema depending on
-the conditions expressed in the query.
-
-You can force the possible types for a variable thanks to the special relation `is`.
-
-
-
-Built-in types
---------------
-* `String` (literal: between double or single quotes).
-* `Int`, `Float` (separator is '.').
-* `Date`, `Datetime`, `Time` (literal: pattern YYYY/MM/DD[ hh:mm] or keywords
- `TODAY` and `NOW`).
-* `Boolean` (keywords `TRUE` et `FALSE`).
-* keyword `NULL`.
-
-Operators
-----------
-* Logical operators: `AND`, `OR`, `,`.
-* Mathematical operators: `+`, `-`, `*`, `/`.
-* Comparison operators: `=`, `<`, `<=`, `>=`, `>`, `~=`, `LIKE`, `IN`.
-
- * The operator `=` is the default operator.
-
- * The operator `LIKE` / `~=` allows the use of the character `%` in a string
- to indicate that the string should start/end with a prefix/suffix::
-
- Any X WHERE X nom ~= 'Th%'
- Any X WHERE X nom LIKE '%lt'
-
- * The operator `IN` allows to provide a list of possible values::
-
- Any X WHERE X nom IN ('chauvat', 'fayolle', 'di mascio', 'thenault')
-
-Search query
-------------
-
- [`DISTINCT`] <entity type> V1(, V2)\*
- [`GROUPBY` V1(, V2)\*] [`ORDERBY` <orderterms>]
- [`WHERE` <condition>]
- [`LIMIT` <value>] [`OFFSET` <value>]
-
-:entity type:
- Type of the selected variable
- Special type `Any` is equivalent to not specify a type
-:condition:
- list of relations to browse following the pattern
- `V1 relation V2|<static value>`
-:orderterms:
- Setting of the selection order : variable or column number followed by the
- sorting method (`ASC`, `DESC`), ASC being the default value.
-:note for grouped queries:
- For grouped queries (e.g. using function `GROUPBY`), all the selected
- variables must be grouped or aggregated.
-
-Examples - search
-~~~~~~~~~~~~~~~~~
-::
-
- Any X WHERE X eid 53
- Personne X
- Personne X WHERE X travaille_pour S, S nom "logilab"
- Any E,COUNT(X) GROUPBY E ORDERBY EN WHERE X is E, E name EN
- Any E,COUNT(X) GROUPBY E ORDERBY 2 WHERE X is E
-
-
-Advanced features
-~~~~~~~~~~~~~~~~~
-* Aggregate functions: `COUNT`, `MIN`, `MAX`, `SUM`.
-* String functions:`UPPER`, `LOWER`.
-* Optional relations:
-
- * They allow to select entities related to others or not.
-
- * You should use `?` behind the variable to specify the relation to itself is
- optional.
-
- - Project anomalies related to a version or not::
-
- Any X,V WHERE X concerns P, P eid 42, X corrected_in V?
-
- - All the cards and the project they document otherwise ::
-
- Any C,P WHERE C is Card, P? documented_by C
-
-Negation
-~~~~~~~~
-* A query such as `Document X WHERE NOT X owned_by U` is equivalent to
- "the documents which do not have relation `owned_by`".
-* Whereas the query `Document X WHERE NOT X owned_by U, U login "syt"`
- is equivalent to "the documents which do not have relation `owned_by`
- with the user syt". They could have a relation with other users.
-
-
-Identity
-~~~~~~~~
-
-We could use the special relation `identity` in a query in order to add a
-condition of identity between two variables. This is equivalent to ``is``
-in Python.
-
- Any A WHERE A comments B, A identity B
-
-returns the set of objects which comment themselves. The relation `identity`
-is very usefull while defining security rules with `RQLExpressions`.
-
-Insertion queries
------------------
- `INSERT` <entity type> V1(, <entity type> V2)\* `:` <assignments>
- [`WHERE` <condition>]
-
-:assignments:
- list of relations to assign such as `V1 relation V2|<static value>`
-
-The condition allow to define the variables we would use in assignments.
-
-Be careful, if a condition is specified, the insertion is done *for each result
-returned by the condition*.
-
-Examples - insertion
-~~~~~~~~~~~~~~~~~~~~~
-* Insertion of a new person named 'bidule'::
-
- INSERT Person X: X name 'bidule'
-
-* Insertion of a new person named 'bidule', another named
- 'chouette' and a relation 'friend' between them::
-
- INSERT Person X, Person Y: X name 'bidule', Y name 'chouette', X friend Y
-
-* Insertion of a new person named 'bidule' and a relation 'friend'with an
- existing person 'chouette'::
-
- INSERT Person X: X name 'bidule', X friend Y WHERE Y name 'chouette'
-
-
-Update queries
---------------
- `SET` <assignments>
- [`WHERE` <condition>]
-
-Be careful, if a condition is specified, the update is done *for each result
-returned by the condition*.
-
-Examples - update
-~~~~~~~~~~~~~~~~~
-* Renaming of the person named 'bidule' to 'toto', with change on the first name::
-
- SET X name 'toto', X firstname 'original' WHERE X is 'Person', X name 'bidule'
-
-* Insertion of a relation of type 'know' between two objects linked with the relation
- of type 'friend' ::
-
- SET X know Y WHERE X friend Y
-
-Deletion queries
-----------------
- `DELETE` (<entity type> V) | (V1 relation v2),...
- [`WHERE` <condition>]
-
-
-Be careful, if a condition is specified, the deletion is done *for each result
-returned by the condition*.
-
-
-Examples
-~~~~~~~~
-* Deletion of the person named 'toto'::
-
- DELETE Person X WHERE X name 'toto'
-
-* Deletion of all the relations of type 'friend' linked to the person named
- 'toto'::
-
- DELETE X friend Y WHERE X is 'Person', X name 'toto'
-
-
--- a/doc/book/en/17-00-migration.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,218 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-
-Migration
-=========
-
-Une des idées de base d'Erudi est la création incrémentale d'application, et
-pour cela de nombreuses actions sont fournies afin de facilement faire évoluer
-une application et tout particulièrement le modèle de données manipulé sans
-perdre les données des instances existantes.
-
-La version courante d'un modèle d'application est données dans le fichier
-`__pkginfo__.py` sous forme d'un tuple de 3 entiers.
-
-
-Gestion des scripts de migrations
----------------------------------
-Les scripts des migrations doivent être placés dans le répertoire `migration` de
-l'application, et nommé de la manière suivante :
-
-::
-
- <n° de version X.Y.Z>[_<description>]_<mode>.py
-
-dans lequel :
-
-* X.Y.Z correspond au n° de version du modèle vers lequel le script permet de
- migrer,
-
-* le *mode* (entre le dernier "_" et l'extension ".py") indique à quelle partie
- de l'application (serveur RQL, serveur web) le script s'applique en cas
- d'installation distribuée. Il peut valoir :
-
- * `common`, s'applique aussi bien sur le serveur RQL que sur le serveur web,
- et met à jour des fichiers sur le disque (migration de fichier de
- configuration par exemple).
-
- * `web`, s'applique uniquement sur le serveur web, et met à jour des fichiers
- sur le disque
-
- * `repository`, s'applique uniquement sur le serveur RQL, et met à jour des
- fichiers sur le disque
-
- * `Any`, s'applique uniquement sur le serveur RQL, et met à jour des
- données en base (migrations de schéma et de données par ex.)
-
-
-Toujours dans le répertoire `migration`, le fichier spécial `depends.map` permet
-d'indiquer que pour migrer vers une version spécifique du modèle, il faut tout
-d'abord avoir migrer vers une version données de erudi. Ce fichier peut contenir
-des commentaires (lignes commençant par un "#"), et une dépendance est notée sur
-une ligne de la manière suivante : ::
-
- <n° de version du modèle X.Y.Z> : <n° de version erudi X.Y.Z>
-
-Par exemple ::
-
- 0.12.0: 2.26.0
- 0.13.0: 2.27.0
- # 0.14 works with 2.27 <= erudi <= 2.28 at least
- 0.15.0: 2.28.0
-
-
-Contexte de base
-----------------
-Les identifiants suivants sont préféfinis dans les scripts de migration :
-
-* `config`, configuration de l'instance
-
-* `interactive_mode`, booléen indiquant si le script est éxécuté en mode
- interactif ou non
-
-* `appltemplversion`, version du modèle d'application de l'instance
-
-* `applerudiversion`, version erudi de l'instance
-
-* `templversion`, version du modéle d'application installée
-
-* `erudiversion`, version erudi installée
-
-* `confirm(question)`, fonction posant une question et retournant vrai si
- l'utilisateur a répondu oui, faux sinon (retourne toujours vrai en mode non
- interactif)
-
-* `_`, fonction équivalente à `unicode` permettant de marquer des chaines à
- internationaliser dans les scripts de migration
-
-Dans les scripts "repository", les identifiants suivant sont également définis :
-
-* `checkpoint`, demande confirmant et effectue un "commit" au point d'appel
-
-* `repo_schema`, schéma persistent de l'instance (i.e. schéma de l'instance en
- cours de migration)
-
-* `newschema`, schéma installé sur le système de fichier (i.e. schéma de la
- version à jour du modèle et de erudi)
-
-* `sqlcursor`, un curseur SQL pour les très rares cas où il est réellement
- nécessaire ou avantageux de passer par du sql
-
-* `repo`, l'objet repository
-
-
-Migration de schéma
--------------------
-Les fonctions de migration de schéma suivantes sont disponibles dans les scripts
-"repository" :
-
-* `add_attribute(etype, attrname, attrtype=None, commit=True)`, ajoute un
- nouvel attribut à un type d'entité existante. Si le type de celui-ci n'est pas
- spécifié il est extrait du schéma à jour.
-
-* `drop_attribute(etype, attrname, commit=True)`, supprime un
- attribut à un type d'entité existante.
-
-* `rename_attribute(etype, oldname, newname, commit=True)`, renomme un attribut
-
-* `add_entity_type(etype, auto=True, commit=True)`, ajoute un nouveau type
- d'entité. Si `auto` est vrai, toutes les relations utilisant ce type d'entité
- et ayant un type d'entité connu à l'autre extrémité vont également être
- ajoutées.
-
-* `drop_entity_type(etype, commit=True)`, supprime un type d'entité et toutes
- les relations l'utilisant.
-
-* `rename_entity_type(oldname, newname, commit=True)`, renomme un type d'entité
-
-* `add_relation_type(rtype, addrdef=True, commit=True)`, ajoute un nouveau type
- de relation. Si `addrdef` est vrai, toutes les définitions de relation de ce
- type seront également ajoutées.
-
-* `drop_relation_type(rtype, commit=True)`, supprime un type de relation et
- toutes les définitions de ce type.
-
-* `rename_relation(oldname, newname, commit=True)`, renomme une relation.
-
-* `add_relation_definition(subjtype, rtype, objtype, commit=True)`, ajoute une
- définition de relation.
-
-* `drop_relation_definition(subjtype, rtype, objtype, commit=True)`, supprime
- une définition de relation.
-
-* `synchronize_permissions(ertype, commit=True)`, synchronise les permissions
- d'un type d'entité ou de relation
-
-* `synchronize_rschema(rtype, commit=True)`, synchronise les propriétés et
- permissions d'un type de relation.
-
-* `synchronize_eschema(etype, commit=True)`, synchronise les propriétés et
- permissions d'un type d'entité.
-
-* `synchronize_schema(commit=True)`, synchronise le schéma persistent avec le
- schéma à jour (mais sans ajouter ni supprimer de nouveaux types d'entités ou
- de relations ni de définitions de relation).
-
-* `change_relation_props(subjtype, rtype, objtype, commit=True, **kwargs)`, change
- les propriétés d'une definition de relation en utilisant les arguments nommés
- pour les propriétés à changer.
-
-* `set_widget(etype, rtype, widget, commit=True)`, change le widget à utiliser
- pour la relation <rtype> du type d'entité <etype>
-
-* `set_size_constraint(etype, rtype, size, commit=True)`, change la contrainte
- de taille pour la relation <rtype> du type d'entité <etype>
-
-
-Migration de données
---------------------
-Les fonctions de migration de données suivantes sont disponibles dans les scripts
-"repository" :
-
-* `rql(rql, kwargs=None, cachekey=None, ask_confirm=True)`, éxécute une
- requête rql arbitraire, d'interrogation ou de modification. Un objet result
- set est retourné.
-
-* `add_entity(etype, *args, **kwargs)`, ajoute une nouvelle entité du type
- données. La valeur des attributs et relations est spécifiée en utilisant les
- arguments nommés et positionnels.
-
-
-Création de workflow
---------------------
-Les fonctions de création de workflow suivantes sont disponibles dans les scripts
-"repository" :
-
-* `add_state(name, stateof, initial=False, commit=False, **kwargs)`, ajoute un
- nouvel état de workflow
-
-* `add_transition(name, transitionof, fromstates, tostate, requiredgroups=(), commit=False, **kwargs)`,
- ajoute une nouvelle transtion de workflow
-
-Migration de configuration
---------------------------
-Les fonctions de migration de configuration suivantes sont disponibles dans tout
-les scripts :
-
-* `option_renamed(oldname, newname)`, indique qu'une option a été renommée
-
-* `option_group_change(option, oldgroup, newgroup)`, indique qu'une option a
- changé de groupe
-
-* `option_added(oldname, newname)`, indique qu'une option a été ajoutée
-
-* `option_removed(oldname, newname)`, indique qu'une option a été supprimée
-
-
-Autres fonctions de migration
------------------------------
-Ces fonctions ne sont utilisés que pour des opérations de bas niveau
-irréalisables autrement ou pour réparer des bases cassées lors de session
-interactive. Elles sont disponibles dans les scripts "repository".
-
-* `sqlexec(sql, args=None, ask_confirm=True)`, éxécute une requête sql
- arbitraire, à n'utiliser
-
-* `add_entity_type_table(etype, commit=True)`
-* `add_relation_type_table(rtype, commit=True)`
-* `uninline_relation(rtype, commit=True)`
--- a/doc/book/en/18-00-tests.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Tests
-=====
-
-Écriture de tests unitaires
----------------------------
-Le framework de test fournit principalement deux classes de tests dans le module
-`ginco.devtools.apptest`:
-
-* `EnvBasedTC`, pour simuler un environnement complet (web + repository)
-* `RepositoryBasedTC`, pour simuler un environnement de repository uniquement
-
-Ces deux classes ont quasiment la même interface et proposent un certain nombre de méthodes
-rendant l'écriture de test puissante et rapide.
-
-XXXFILLME describe API
-
-Dans la plupart des cas, vous allez vouloir hériter de `EnvBasedTC` pour écrire des tests
-unitaires ou fonctionnels pour vos entités, vues, crochets...
-
-
-Test des courriels de notifications
-```````````````````````````````````
-Lors de l'éxécution de tests les courriels potentiellement générés ne sont pas réellement
-envoyé mais se retrouve dans la liste `MAILBOX` du module `ginco.devtools.apptest`. Cette
-liste est remise à zéro au *setUp* de chaque test (par le setUp des classes `EnvBasedTC`
-et `RepositoryBasedTC`).
-
-Vous pouvez donc tester vos notifications en analysant le contenu de cette liste, qui
-contient des objets ayant deux attributs :
-* `recipients`, la liste des destinataires
-* `msg`, l'objet email.Message
-
-
-Tests automatiques
-------------------
-XXXFILLME
--- a/doc/book/en/19-00-i18n.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /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/<lang>/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 <composant>`
-2. éditer les fichiers <composant>/xxx.po dans pour y rajouter les traductions
- manquantes (`msgstr` vide)
-3. `hg ci -m "updated i18n catalogs"`
-4. `cubicweb-ctl i18n compile <monapplication>`
-
--- a/doc/book/en/20-00-google-appengine.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _contents:
-
-==========================
-Google AppEngine Datastore
-==========================
-
-
-.. include:: 20-01-intro.en.txt
-.. include:: 20-02-install.en.txt
--- a/doc/book/en/20-01-intro.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /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`.
-
--- a/doc/book/en/20-02-install.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,220 +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
-
-- `LAX` is available as an extension of `CubicWeb` under the GPLv2
- license which can be downloaded from : http://cubicweb.org/
-
-Please follow instructions on how to install `CubicWeb` framework.
-
-Once ``cubicweb-ctl`` is installed, then you can create a Google
-App Engine extension of our framework by running the command ::
-
- cubicweb-ctl newgapp <myapp>
-
-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
-`LAX` framework and its third-party libraries. You will notice that
-the directory ``cubes`` is a library of reusable components.
-
-The main directories that you should know about are:
-
- - ``cubes`` : this is a library of reusable yams components. To use
- those components you will list them in the variable
- `included-yams-cubes` of ``app.conf``. See also :ref:`components`.
- - [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 <myapp>``, 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
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-`LAX` 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
-'erudi'". 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 components from ginco-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 <http://localhost:8080/_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 <http://localhost:8080/?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 <http://localhost:8080/?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 <http://localhost:8080/?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/ <http://localhost:8080>`_
-as a normal user.
-
-Unless you did something to change it, http://MYAPP_URL should be
-http://localhost:8080/
-
-
--- a/doc/book/en/21-00-appendix.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _contents:
-
-Appendix
-========
-
-.. toctree::
- :maxdepth: 1
-
- 21-01-architecture.en.txt
- 21-02-querier.en.txt
- 21-03-modules-stdlib.en.txt
- 21-04-modules-cbw-api.en.txt
- 21-05-mercurial.en.txt
- 21-06-mercurial-forest.en.txt
-
--- a/doc/book/en/21-01-architecture.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-
-Architecture du serveur
------------------------
-
-.. image:: images/server-class-diagram.png
-
-`Diagramme ArgoUML`_
-
-[FIXME]
-Make a downloadable source of zargo file.
-
-.. _`Diagramme ArgoUML`: cubicweb.zargo
--- a/doc/book/en/21-03-modules-stdlib.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,158 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-================
-Standard library
-================
-
-:mod:`cubes.addressbook`
-========================
-
-.. automodule:: cubes.addressbook
- :members:
-
-:mod:`cubes.basket`
-========================
-
-.. automodule:: cubes.basket
- :members:
-
-:mod:`cubes.blog`
-========================
-
-.. automodule:: cubes.blog
- :members:
-
-:mod:`cubes.book`
-========================
-
-.. automodule:: cubes.book
- :members:
-
-:mod:`cubes.comment`
-========================
-
-.. automodule:: cubes.comment
- :members:
-
-:mod:`cubes.company`
-========================
-
-.. automodule:: cubes.company
- :members:
-
-
-:mod:`cubes.conference`
-========================
-
-.. automodule:: cubes.conference
- :members:
-
-:mod:`cubes.email`
-========================
-
-.. automodule:: cubes.email
- :members:
-
-:mod:`cubes.event`
-========================
-
-.. automodule:: cubes.event
- :members:
-
-:mod:`cubes.expense`
-========================
-
-.. automodule:: cubes.expense
- :members:
-
-
-:mod:`cubes.file`
-========================
-
-.. automodule:: cubes.file
- :members:
-
-:mod:`cubes.folder`
-========================
-
-.. automodule:: cubes.folder
- :members:
-
-:mod:`cubes.i18ncontent`
-========================
-
-.. automodule:: cubes.i18ncontent
- :members:
-
-:mod:`cubes.invoice`
-========================
-
-.. automodule:: cubes.invoice
- :members:
-
-:mod:`cubes.keyword`
-========================
-
-.. automodule:: cubes.keyword
- :members:
-
-:mod:`cubes.link`
-========================
-
-.. automodule:: cubes.link
- :members:
-
-:mod:`cubes.mailinglist`
-========================
-
-.. automodule:: cubes.mailinglist
- :members:
-
-:mod:`cubes.person`
-========================
-
-.. automodule:: cubes.person
- :members:
-
-:mod:`cubes.shopcart`
-========================
-
-.. automodule:: cubes.shopcart
- :members:
-
-:mod:`cubes.skillmat`
-========================
-
-.. automodule:: cubes.skillmat
- :members:
-
-:mod:`cubes.tag`
-========================
-
-.. automodule:: cubes.tag
- :members:
-
-:mod:`cubes.task`
-========================
-
-.. automodule:: cubes.task
- :members:
-
-:mod:`cubes.workcase`
-========================
-
-.. automodule:: cubes.workcase
- :members:
-
-:mod:`cubes.workorder`
-========================
-
-.. automodule:: cubes.workorder
- :members:
-
-:mod:`cubes.zone`
-========================
-
-.. automodule:: cubes.zone
- :members:
-
--- a/doc/book/en/21-04-modules-cbw-api.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,104 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-============
-CubicWeb API
-============
-
-:mod:`cubicweb`
-===============
-
-.. automodule:: cubicweb
- :members:
-
-:mod:`cubicweb.common`
-======================
-
-.. automodule:: cubicweb.common
- :members:
-
-:mod:`cubicweb.devtools`
-========================
-
-.. automodule:: cubicweb.devtools
- :members:
-
-:mod:`cubicweb.entities`
-========================
-
-.. automodule:: cubicweb.entities
- :members:
-
-:mod:`cubicweb.etwist`
-======================
-
-.. automodule:: cubicweb.etwist
- :members:
-
-:mod:`cubicweb.goa`
-===================
-
-.. automodule:: cubicweb.goa
- :members:
-
-:mod:`cubicweb.schemas`
-=======================
-
-.. automodule:: cubicweb.schemas
- :members:
-
-:mod:`cubicweb.server`
-======================
-
-.. automodule:: cubicweb.server
- :members:
-
-:mod:`cubicweb.sobjects`
-========================
-
-.. automodule:: cubicweb.sobjects
- :members:
-
-:mod:`cubicweb.web`
-===================
-
-.. automodule:: cubicweb.web
- :members:
-
-:mod:`cubicweb.web.views`
-=========================
-
-.. automodule:: cubicweb.web.views
- :members:
-
-
-:mod:`cubicweb.wsgi`
-====================
-
-.. automodule:: cubicweb.wsgi
- :members:
-
-:mod:`indexer`
-==============
-
-.. automodule:: indexer
- :members:
-
-:mod:`logilab`
-==============
-
-.. automodule:: logilab
- :members:
-
-
-
-:mod:`rql`
-==========
-
-.. automodule:: rql
- :members:
-
-:mod:`yams`
-===========
-
-.. automodule:: yams
- :members:
--- a/doc/book/en/21-05-mercurial.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,114 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _MercurialPresentation:
-
-Présentation de Mercurial
-=========================
-
-Introduction
-````````````
-Mercurial_ gère un ensemble distribué d'entrepôts contenant des arbres de
-révisions (chaque révision indique les changements à effectuer pour obtenir la
-version suivante, et ainsi de suite). Localement, on dispose d'un entrepôt
-contenant un arbre de révisions, et d'un répertoire de travail. Il est possible
-de mettre dans son répertoire de travail, une des versions issue de son entrepôt
-local, de la modifier puis de la verser dans son entrepôt. Il est également
-possible de récuprer dans son entrepôt local des révisions venant d'un autre
-entrepôt, ou d'exporter ses propres révisions depuis son entrepôt local vers un
-autre entrepôt.
-
-A noter que contrairement à CVS/Subversion, on crée généralement un entrepôt par
-projet à gérer.
-
-Lors d'un développement collaboratif, on crée généralement un entrepôt central
-accessible à tout les développeurs du projet. Ces entrepôts centraux servent de
-référence. Selon ses besoins, chacun peut ensuite disposer d'un entrepôt local,
-qu'il faudra penser à synchroniser avec l'entrepôt central de temps à autre.
-
-
-Principales commandes
-`````````````````````
-* Créer un entrepôt local ::
-
- hg clone ssh://orion//home/src/prive/rep
-
-* Voir le contenu de l'entrepôt local (outil graphique en Tk) ::
-
- hg view
-
-* Ajouter un sous-répertoire ou un fichier dans le répertoire courant ::
-
- hg add rep
-
-* Placer dans son répertoire de travail une révision spécifique (ou la dernière
- revision) issue de l'entrepôt local ::
-
- hg update [identifiant-revision]
- hg up [identifiant-revision]
-
-* Récupérer dans son entrepôt local, l'arbre de révisions contenu dans un
- entrepôt distant (cette opération ne modifie pas le répertoire local) ::
-
- hg pull ssh://orion//home/src/prive/rep
- hg pull -u ssh://orion//home/src/prive/rep # équivalent à pull + update
-
-* Voir quelles sont les têtes de branches de l'entrepôt local si un `pull` a
- tiré une nouvelle branche ::
-
- hg heads
-
-* Verser le répertoire de travail dans l'entrepôt local (et créer une nouvelle
- révision) ::
-
- hg commit
- hg ci
-
-* Fusionner, avec la révision mère du répertoire local, une autre révision issue
- de l'entrepôt local (la nouvelle révision qui en résultera aura alors deux
- révisions mères) ::
-
- hg merge identifiant-revision
-
-* Exporter dans un entrepôt distant, l'arbre de révisions contenu dans son
- entrepôt local (cette opération ne modifie pas le répertoire local) ::
-
- hg push ssh://orion//home/src/prive/rep
-
-* Voir quelle sont les révisions locales non présentes dans un autre entrepôt ::
-
- hg outgoing ssh://orion//home/src/prive/rep
-
-* Voir quelle sont les révisions d'un autre entrepôt non présentes localement ::
-
- hg incoming ssh://orion//home/src/prive/rep
-
-* Voir quelle est la révision issue de l'entrepôt local qui a été sortie dans le
- répertoire de travail et modifiée ::
-
- hg parent
-
-* Voir les différences entre le répertoire de travail et la révision mère de
- l'entrepôt local, éventuellement permettant de les verser dans l'entrepôt
- local ::
-
- hg diff
- hg commit-tool
- hg ct
-
-
-Bonnes pratiques
-````````````````
-* penser à faire un `hg pull -u` régulièrement et particulièrement avant de
- faire un `hg commit`
-
-* penser à faire un `hg push` lorsque votre entrepôt contient une version
- relativement stable de vos modifications
-
-* si un `hg pull -u` a créé une nouvelle tête de branche :
-
- 1. identifier l'identifiant de celle-ci avec `hg head`
- 2. fusionner avec `hg merge`
- 3. `hg ci`
- 4. `hg push`
-
-.. _Mercurial: http://www.selenic.com/mercurial/
--- a/doc/book/en/21-06-mercurial-forest.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _MercurialForestInstall:
-
-Installation of `CubicWeb` with Mercurial
-=========================================
-
-`CubicWeb` is available as a Mercurial repository using the forest extension.
-First make sure Mercurial is installed and that the forest extension is
-available.
-
-Mercurial installation
-``````````````````````
-
-Please refer to the project online documentation Mercurial_.
-
-.. _Mercurial: http://www.selenic.com/mercurial/wiki/
-
-We also provide in this book a quick guide on how to use
-Mercurial (:ref:`MercurialPresentation`).
-
-
-Installation of the forest extension
-````````````````````````````````````
-
-Set up the forest extension by getting a copy of the sources
-from http://hg.akoha.org/hgforest/ and adding the following
-lines to your ``~/.hgrc``: ::
-
- [extensions]
- hgext.forest=
- # or, if forest.py is not in the hgext dir:
- # forest=/path/to/forest.py
-
-Get `CubicWeb` source code
-``````````````````````````
-
-Clone the forest in you working directory.
-
-::
-
- hg fclone http://www.logilab.org/hg/forests/cubicweb
-
-.. note::
- We recommand you to create a symbolic link to the command ``cubicweb-ctl``
- as you will use it pretty often.
-
- ::
-
- $ ln -s /path/to/forest/cubicweb/bin/cubicweb-ctl ~/bin
-
-
--- a/doc/book/en/22-00-faq.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,104 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Frequently Asked Questions
-==========================
-
-* Why does not LAX have a template language ?
-
- It does. Actually, you can use your preferred template language if you
- want. [explain how to use a template language]
-
- The reason template languages are not used in this book is that
- experience has proved us that using pure python was more efficient.
-
-* Why do you think using pure python is better than using a template language ?
-
- [copy answer from forum]
-
- code is easier to maintain, does not have to learn a new dialect
- each time, real function/classes etc -> real development
-
-* Why do you use the GPL license to prevent me from doing X ?
-
- [copy answer from forum]
-
-* LAX looks pretty recent. Is it stable ?
-
- [answer that framework has evolved over the past seven years and that
- data migrated from one schema to the other ever since]
-
-* Why is the RQL query language looking similar to X ?
-
- [copy answer from forum, explain why similar to sparql and why better
- than django and SQL]
-
-* which ajax library
-
- [we use mochikit and things on top of that]
-
-* `Error while publishing rest text ...`
-
- While modifying the description of an entity, you get an error message in
- the application `Error while publishing ...` for Rest text and plain text.
- The server returns a traceback like as follows ::
-
- 2008-10-06 15:05:08 - (erudi.rest) ERROR: error while publishing ReST text
- Traceback (most recent call last):
- File "/home/sandrine/src/blogdemo/ginco/common/rest.py", line 217, in rest_publish
- File "/usr/lib/python2.5/codecs.py", line 817, in open
- file = __builtin__.open(filename, mode, buffering)
- TypeError: __init__() takes at most 3 arguments (4 given)
-
-
- This can be fixed by applying the patch described in :
- http://code.google.com/p/googleappengine/issues/detail?id=48
-
-* What are hooks used for?
-
- Les crochets sont appeles lorsqu'une requete RQL est executee. Cela
- permet d'executer des actions specifiques lors d'un acces a la base
- de donnees, ce qui donne un controle de la base de donnees afin de
- prevenir l'insertion de `mauvaises` entites dans la base.
-
-* When should you define an HTML template rather than define a graphical component?
-
- Un template HTML ne peut contenir de logique, il ne permettra donc
- que de definir une vue statique. Un composant permet lui de gerer
- plus de logique et d'operations sur le contexte dans lequel il
- s'applique. Il faut donc bien reflechir avant de decider de l'un ou
- de l'autre, mais vous avez la possibilite de choisir.
-
-* How to update a database after a schema modification?
-
- Cela dépend de ce qui a été modifié dans le schéma.
-
- * Modification d'une relation non finale
-
- * Modification d'une relation finale
-
-[TO COMPLETE]
-
-* How to create an anonymous user?
-
- Cela vous permet d'acceder a votre site sans avoir besoin de vous authentifier.
- Dans le fichier ``all-in-one.conf`` de votre instance, définir l'utilisateur
- anonyme en initilisant les valeurs des variables suivantes ::
-
- # login of the Erudi user account to use for anonymous user (if you want to
- # allow anonymous)
- anonymous-user=anon
-
- # password of the Erudi user account matching login
- anonymous-password=anon
-
- Vous devez aussi vous assurer que cet utilisateur `anon` existe dans la base
- de données, le plus simple étant de s'identifier sur votre application en
- administrateur et de rajouter l'utilisateur `anon` via l'interface d'administration.
-
-* What is the difference between `AppRsetObject` and `AppObject` ?
-
- La différence entre la classe `AppRsetObject` et la classe `AppObject` est que
- les instances de la premières sont séléctionnées pour une requête et un "result
- set" et alors que les secondes ne sont séléctionnées qu'en fonction de leur
- identifiant.
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/A000-introduction.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,18 @@
+.. -*- coding: utf-8 -*-
+
+
+===================================
+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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/A010-book-map.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,10 @@
+.. -*- 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
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/A020-tutorial.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,24 @@
+.. -*- coding: utf-8 -*-
+
+.. _Overview:
+
+Quick overview of `CubicWeb`
+============================
+
+`CubicWeb` allows us to develop web applications instances based on
+one or more `cubes`.
+
+What we call a `cube` is a model defining the data types and views.
+A `cube` is a reusable component grouped with others cubes in the file
+system.
+
+An `instance` refers to a specific installation of one or more `cubes`
+ where are grouped configuration files of the final web application.
+
+In this document, we will show you how to create a `cube` and how to use it
+in an `instance` for your web application.
+
+.. include:: A02a-create-cube.en.txt
+.. include:: A02b-components.en.txt
+.. include:: A02c-maintemplate.en.txt
+.. include:: A02d-rss-xml.en.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/A02a-create-cube.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,314 @@
+.. -*- coding: utf-8 -*-
+
+Create your cube
+----------------
+
+After you installed your `CubicWeb` development environment, you can start
+to build your first cube: ::
+
+ cubicweb-ctl newcube blog
+
+This will create in ``/path/to/forest/cubes`` a directory containing: ::
+
+ blog/
+ |
+ |-- data/
+ | |-- cubes.blog.css
+ | |-- cubes.blog.js
+ | |-- external_resources
+ |
+ |-- debian/
+ | |-- changelog
+ | |-- compat
+ | |-- control
+ | |-- copyright
+ | |-- cubicweb-blog.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
+ |
+ |-- sobjects.py
+ |
+ |-- test/
+ | |-- data/
+ | |-- bootstrap_cubes
+ | |-- pytestconf.py
+ | |-- realdb_test_blog.py
+ | |-- test_blog.py
+ |
+ |-- views.py
+
+Any changes applied to your data model should be done in this
+directory.
+
+
+Define your data schema
+-----------------------
+
+The data model or schema is hte core of your `CubicWeb` application.
+This is where is defined the type of content you application will handle.
+
+The data model is defined in the file ``schema.py`` of your cube
+``blog`` such as follows.
+
+::
+
+ from cubicweb.schema import format_constraint
+ 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
+--------------------
+
+::
+
+ cubicweb-ctl create blog blogdemo
+
+
+This command will create a directory ``~/etc/cubicweb.d/blogdemo``
+which will contain all the configuration files required to start
+you web application.
+
+The instance ``blogdemo`` is based on the cube ``blog``.
+
+
+Welcome in your web application
+-------------------------------
+
+Run your application with the following command: ::
+
+ cubicweb-ctl start -D blogdemo
+
+
+You can now access to your web application to create blogs and post messages
+by visitin the URL http://localhost:8080/.
+A login form will first be prompted. By default, the application will not allow
+anonymous user to get in the application. You should 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. Bravo!
+
+.. image:: images/blog-demo-first-page.png
+
+Please notice that so far, `CubicWeb` franework managed all aspects of
+the web application based in the schema provided at first.
+
+
+Create entities
+---------------
+
+We will now create a couple of entities in our web application.
+
+Create a Blog
+~~~~~~~~~~~~~
+
+Let us create a few of these entities. Click on the `[+]` at the right
+of the link Blog. 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
+
+Create a BlogEntry
+~~~~~~~~~~~~~~~~~~
+
+Get back to the home page and click on [+] at the right 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)
+
+
+Define your entities views
+--------------------------
+
+The views 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 resulsets it can be applied to
+
+
+`CubicWeb` provides a lot of standard views for the type
+`EntityView`, for a complete list, you
+will have to 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
+mecanism which computes a score used to identify which view
+is the best to apply for the `result set` we are trying to
+display. 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. We will see more details
+on this in :ref:`DefinitionVues`.
+
+For example, the view named ``primary`` is the one used to display
+a single entity. We will now show you hos 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 by example add in front of the pulication date a prefix specifying
+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'<h1>%s</h1>' % 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'<h1>%s</h1>' % entity.title)
+ self.w(u'<p>published on %s</p>' % entity.publish_date.strftime('%Y-%m-%d'))
+ self.w(u'<p>%s</p>' % 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 resultsets and resulsets can be tables of
+data, it is needed to recover the entity from its (row,col)
+coordinates. We will get to this in more detail later.
+
+The view has a ``self.w()`` method that is used to output data. In our
+example we use it to output HTML tags and values of the entity's attributes.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/A02b-components.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,150 @@
+.. -*- coding: utf-8 -*-
+
+.. _components:
+
+Components
+----------
+
+What is a component
+~~~~~~~~~~~~~~~~~~~
+
+A component 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
+others components.
+You can decide to write your own set of components if you wish to re-use the
+entity types you develop. By default, LAX comes with its owns set of components
+that you can start using right away.
+
+
+Standard library
+~~~~~~~~~~~~~~~~
+
+A library of standard components is part of the `LAX` release (look at
+``lax/skel/ginco-apps``). Components provide entities and views. With
+``lax-0.4``, you should get a set of application entities and system
+entities you can re-use.
+
+The available application entities are:
+
+* addressbook: PhoneNumber and PostalAddress
+
+* ebasket: Basket (like a shopping cart)
+
+* eblog: Blog (a *very* basic blog)
+
+* eclassfolder: Folder (to organize things but grouping them in folders)
+
+* eclasstags: Tag (to tag anything)
+
+
+* efile: File (to allow users to upload and store binary or text files)
+
+* elink: Link (to collect links to web resources)
+
+* emailinglist: MailingList (to reference a mailing-list and the URLs
+ for its archives and its admin interface)
+
+* eperson: Person (easily mixed with addressbook)
+
+* etask: Task (something to be done between start and stop date)
+
+* ezone: Zone (to define places within larger places, for example a
+ city in a state in a country)
+
+The available system entities are:
+
+* ecomment: Comment (to attach comment threads to entities)
+
+
+
+Adding comments to BlogDemo
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To import a component in your application just change the line in the
+``app.conf`` file. For example::
+
+ included-yams-components=ecomment
+
+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 ecomment component defines the
+``comments`` relationship, adding the line::
+
+ comments = ObjectRelation('Comment', cardinality='1*', composite='object')
+
+to the definition of a ``BlogEntry`` will be enough.
+
+Clear the datastore and restart.
+
+Component structure
+~~~~~~~~~~~~~~~~~~~
+
+A complex component is structured as follows:
+::
+
+ mycomponent/
+ |
+ |-- schema.py
+ |
+ |-- entities/
+ |
+ |-- sobjects/
+ |
+ |-- views/
+ |
+ |-- test/
+ |
+ |-- i18n/
+ |
+ |-- data/
+ |
+ |-- migration/
+ | |- postcreate.py
+ | \- depends.map
+ |
+ |-- debian/
+ |
+ \-- __pkginfo__.py
+
+We can also define simple Python module instead of directories (packages), for example:
+::
+
+ mycomponent/
+ |
+ |-- entities.py
+ |-- hooks.py
+ \-- views.py
+
+
+where:
+
+* ``schema`` contains the definition of the schema (server side only)
+* ``entities`` contains entities definition (server side and web interface)
+* ``sobjects`` contains hooks and/or notification views (server side only)
+* ``views`` contains the web interface components (web interface only)
+* ``test`` contains tests related to the application (not installed)
+* ``i18n`` contains messages 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-components used by
+ the component.
+
+At least you should have:
+
+* the file ``__pkginfo__.py``
+* schema definition
+
+[WRITE ME]
+
+* explain the component architecture
+
+* add comments to the blog by importing the comments component
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/A02c-maintemplate.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,209 @@
+.. -*- coding: utf-8 -*-
+
+Views & Templates
+-----------------
+
+Look at ``lax/skel/ginco/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
+~~~~~~~~~~~~~~~
+
+Let's use a different logo than the default one provided with LAX
+and customize our header.
+
+Change logo
+```````````
+
+The easiest way to use a different logo is to replace the existing
+``logo.png`` in ``myapp/data`` by your prefered icon and refresh.
+By default all application will look for a ``logo.png`` to be
+rendered in the logo section.
+
+.. image:: images/lax-book.06-main-template-logo.en.png
+
+[ADD]
+customized external_resources in myapp/data cd crih for reference
+
+[WRITE ME]
+ADD how to use external_resources variables used in ginco/web/webconfig.py
+
+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 sat 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'<table id="header"><tr>\n')
+ self.w(u'<td id="firstcolumn">')
+ self.vreg.select_component('logo', self.req, self.rset).dispatch(w=self.w)
+ self.w(u'</td>\n')
+ # appliname and breadcrumbs
+ self.w(u'<td id="headtext">')
+ comp = self.vreg.select_component('appliname', self.req, self.rset)
+ if comp and comp.propval('visible'):
+ comp.dispatch(w=self.w)
+ comp = self.vreg.select_component('breadcrumbs', self.req, self.rset, view=view)
+ if comp and comp.propval('visible'):
+ comp.dispatch(w=self.w, view=view)
+ self.w(u'</td>')
+ # logged user and help
+ #self.w(u'<td>\n')
+ #comp = self.vreg.select_component('loggeduserlink', self.req, self.rset)
+ #comp.dispatch(w=self.w)
+ #self.w(u'</td><td>')
+
+ self.w(u'<td>')
+ helpcomp = self.vreg.select_component('help', self.req, self.rset)
+ if helpcomp: # may not be available if Card is not defined in the schema
+ helpcomp.dispatch(w=self.w)
+ self.w(u'</td>')
+ # lastcolumn
+ self.w(u'<td id="lastcolumn">')
+ self.w(u'</td>\n')
+ self.w(u'</tr></table>\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 ginco.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'<table id="header"><tr>\n')
+ self.w(u'<td id="firstcolumn">')
+ self.vreg.select_component('logo', self.req, self.rset).dispatch(w=self.w)
+ self.w(u'</td>\n')
+ # appliname and breadcrumbs
+ self.w(u'<td id="headtext">')
+ comp = self.vreg.select_component('appliname', self.req, self.rset)
+ if comp and comp.propval('visible'):
+ comp.dispatch(w=self.w)
+ comp = self.vreg.select_component('breadcrumbs', self.req, self.rset, view=view)
+ if comp and comp.propval('visible'):
+ comp.dispatch(w=self.w, view=view)
+ self.w(u'</td>')
+
+ # logged user and help
+ #self.w(u'<td>\n')
+ #comp = self.vreg.select_component('loggeduserlink', self.req, self.rset)
+ #comp.dispatch(w=self.w)
+ #self.w(u'</td><td>')
+
+ # search box
+ self.w(u'<td>')
+ self.get_searchbox(view, 'left')
+ self.w(u'</td>')
+
+ self.w(u'<td>')
+ helpcomp = self.vreg.select_component('help', self.req, self.rset)
+ if helpcomp: # may not be available if Card is not defined in the schema
+ helpcomp.dispatch(w=self.w)
+ self.w(u'</td>')
+ # lastcolumn
+ self.w(u'<td id="lastcolumn">')
+ self.w(u'</td>\n')
+ self.w(u'</tr></table>\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 ginco.web.views.basetemplates import HTMLPageFooter
+ class MyHTMLPageFooter(HTMLPageFooter):
+ def call(self, **kwargs):
+ self.w(u'<div class="footer">')
+ self.w(u'This website has been created with <a href="http://lax.logilab.org">LAX</a>.')
+ self.w(u'</div>')
+
+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 ``ginco/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
+
+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/``.
+
+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.
+
+[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 ginco-doc rajouter une section pour erudi-ctl shell ou
+on liste les commandes dispos.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/A02d-rss-xml.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -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
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/A030-foundation.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,32 @@
+.. -*- 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), etc.
+
+In 2008, `CubicWeb` was ported for a new type of source : the datastore
+from GoogleAppEngine_.
+
+.. include:: A03a-concepts.en.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/A03a-concepts.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,411 @@
+.. -*- coding: utf-8 -*-
+
+Concepts
+--------
+
+Global architecture
+~~~~~~~~~~~~~~~~~~~
+.. image:: images/archi_globale.png
+
+.. note::
+ For real, the client and server sides are integrated in the same
+ process and interact directly, without the needs for distants
+ calls using Pyro. It is important to note down that those two
+ sides, client/server, are disjointed and it is possible to execute
+ a couple of calls in distincts processes to balance the load of
+ your web site on one or more machines.
+
+.. _TermsVocabulary:
+
+Terms and vocabulary
+~~~~~~~~~~~~~~~~~~~~~
+
+*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 as
+ it is necessarry for the core of `CubicWeb` and a library of
+ cubes that can be explicitely included if necessary.
+
+
+*entity type*
+ An entity 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 corresponds 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 others
+ vital informations for the system.
+
+*configuration*
+ It is possible to create differents 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 functionnality or a complete `CubicWeb` application
+ potentially using other cubes. The available subes are located in the file
+ system at `/path/to/forest/cubicweb/cubes`.
+ Larger applications can be built faster by importing cubes,
+ adding entities and relationships and overriding the
+ views that need to display or edit informations not provided by
+ cubes.
+
+*instance*
+ An instance is a specific installation of a cube. All the required
+ configuration files necessarry 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.
+ By 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 sometime 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 information 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*
+ XXX
+
+.. _`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 dynamics objects, based on the schema
+or the library, are building the final application. The differents dymanic components are
+by 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
+~~~~~~~~~~~~~~
+
+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 dictionnary containing the values to use
+:eid_key:
+ an implementation detail of the RQL queries 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 correponding key in the dictionnary
+ 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 updates 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 HTPP request is sent to the web server.
+It contains informations such as forms 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 by example)**
+
+An instance of `Request` has the following attributes:
+
+* `user`, instance of `cubicweb.common.utils.User` corresponding to the authenticated
+ user
+* `form`, dictionnary containing the values of a web form
+* `encoding`, characters encoding to use in the response
+
+But also:
+
+:Session data handling:
+ * `session_data()`, returns a dictinnary 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 dictionnary 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 (`EProperty`)
+ * dictionnary `data` to store data to share informations between components
+ *while a request is executed*
+
+Please note down 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 so 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 necessarry
+* `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)`
+ * `format_time(time)`
+
+:And more...:
+
+ * `external_resource(rid, default=_MARKER)`, access to a value defined in the
+ configuration file `external_resource`
+
+ * `tal_render(template, variables)`,
+
+
+.. 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.
+ By 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)
+
+
+Standard structure for a cube
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A complex cube is structured as follows:
+
+::
+
+ mycube/
+ |
+ |-- schema.py
+ |
+ |-- entities/
+ |
+ |-- sobjects/
+ |
+ |-- views/
+ |
+ |-- test/
+ |
+ |-- i18n/
+ |
+ |-- data/
+ |
+ |-- migration/
+ | |- postcreate.py
+ | \- depends.map
+ |
+ |-- debian/
+ |
+ \-- __pkginfo__.py
+
+We can use simple Python module instead of packages, by example:
+
+::
+
+ mycube/
+ |
+ |-- entities.py
+ |-- hooks.py
+ \-- views.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 different components of the web interface (web interface only)
+* ``test`` contains tests specifics to the application (not installed)
+* ``i18n`` contains the messages catalog for supported languages (server side and
+ web interface)
+* ``data`` contains arbitrary data files served statically
+ (images, css, javascripts files)... (web interface only)
+* ``migration`` contains the initialization file for new instances
+ (``postcreate.py``) and in general a file containing the `CubicWeb` dependancies
+ of the cube depending on its version (``depends.map``)
+* ``debian`` contains all the files that manages the debian packaging
+ (you would find there the classical structure with ``control``, ``rules``,
+ ``changelog``... (not installed)
+* the file ``__pkginfo__.py`` provides meta-data on the cube, especially the
+ distribution name and the current version (server side and web interface) or
+ also the sub-cubes used by this cube
+
+The only required files are:
+
+* 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 embeding for instance)
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/B000-development.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,39 @@
+.. -*- coding: utf-8 -*-
+
+
+=====================
+Part II - Development
+=====================
+
+This part is about developing web applications with the `CubicWeb` framework.
+
+.. toctree::
+ :maxdepth: 1
+
+ B020-define-schema.en.txt
+ B030-define-views.en.txt
+ B040-define-workflows.en.txt
+ B050-data-as-objects.en.txt
+ B060-form-management.en.txt
+ B070-ajax-json.en.txt
+ B080-internationalization.en.txt
+ B090-ui-components.en.txt
+ B100-hooks.en.txt
+ B110-notifications.en.txt
+ B120-migration.en.txt
+ B130-tests.en.txt
+ B140-google-appengine.en.txt
+ BXXX-actions.en.txt
+ BXXX-boxes.en.txt
+ BXXX-configuration.en.txt
+ BXXX-dbapi.en.txt
+ BXXX-embedding-external-page.en.txt
+ BXXX-online-doc.en.txt
+ BXXX-registry.en.txt
+ BXXX-repository-operations.en.txt
+ BXXX-repository-session.en.txt
+ BXXX-repository-tasks.en.txt
+ BXXX-request.en.txt
+ BXXX-sessions.en.txt
+ BXXX-templates.en.txt
+ BXXX-urlrewrite.en.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/B020-define-schema.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,22 @@
+.. -*- coding: utf-8 -*-
+
+Data model definition (*schema*)
+================================
+
+The schema is the core piece of a `CubicWeb` application as it defines
+the data model handled. It is based on entities types already defined
+in the `CubicWeb` standard library and others, more specific, we would
+expect to find in one or more Python files under the `schema` directory.
+
+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
+"<subject entity type> <relation type> <object entity type>".
+A relation type could have been implied if none is related to a
+relation definition of the schema.
+
+
+.. include:: B021-schema-stdlib.en.txt
+.. include:: B022-schema-definition.en.txt
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/B021-schema-stdlib.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,71 @@
+.. -*- coding: utf-8 -*-
+
+Pre-defined schemas in the library
+----------------------------------
+
+The library defines a set of entities schemas that are required by the system
+or commonly used in `CubicWeb` applications.
+Of course, you can extend those schemas if necessarry.
+
+
+System schemas
+``````````````
+The system entities available are :
+
+* `EUser`, system users
+* `EGroup`, users groups
+* `EEType`, entity type
+* `ERType`, 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
+
+* `EProperty`, used to configure the application
+* `EPermission`, 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
+
+Cubes in the library
+````````````````````
+
+An application is based on several basic cubes. In the set of available
+basic cubes we can find by example :
+
+* `comment`, provides an entity type for `Comment` allowing us to comment others
+ site's entities
+
+* `mailinglist`, provides an entity type for `Mailinglist` which groups informations
+ in a discussion list
+
+* `file`, provides entity types for `File` et `Image` used to represent
+ files (text or binary) with additionnal informations such as MIME type or
+ encoding.
+
+* `link`, provides an entity type for hypertext link (`Link`)
+
+* `blog`, provides an entity type weblog (`Blog`)
+
+* `person`, provides an entity type for a person (`Person`)
+
+* `addressbook`, provides an entity type used to represent phone
+ numbers (`PhoneNumber`) and mailing address (`PostalAddress`)
+
+* `classtags`, categorization system based on tags (`Tag`)
+
+* `classfolders`, categorization system based on folders hierarchy in order
+ to create navigation sections (`Folder`)
+
+* `email`, archiving management for emails (`Email`, `Emailpart`,
+ `Emailthread`)
+
+* `basket`, basket management (`Basket`) allowing to group entities
+
+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.
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/B022-schema-definition.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,372 @@
+.. -*- coding: utf-8 -*-
+
+Entity type definition
+----------------------
+
+An entity type is defined by a Python class which inherits `EntityType`. The
+class name correponds to the type name. Then the content of the class contains
+the description of attributes and relations for the defined entity type,
+by example ::
+
+ class Personne(EntityType):
+ """A person with the properties and the relations necessarry for my
+ application"""
+
+ last_name = String(required=True, fulltextindexed=True)
+ first_name = String(required=True, fulltextindexed=True)
+ title = String(vocabulary=('M', 'Mme', 'Mlle'))
+ date_of_birth = Date()
+ works_for = SubjectRelation('Company', cardinality='?*')
+
+* the name of the Python attribute corresponds to the name of the attribute
+ or the relation in `CubicWeb` application.
+
+* all built-in types are available : `String`, `Int`, `Float`,
+ `Boolean`, `Date`, `Datetime`, `Time`, `Byte`.
+
+* each entity type has at least the following meta-relations :
+
+ - `eid` (`Int`)
+
+ - `creation_date` (`Datetime`)
+
+ - `modification_date` (`Datetime`)
+
+ - `created_by` (`EUser`) (which user created the entity)
+
+ - `owned_by` (`EUser`) (who does the entity belongs to, by default the
+ creator but not necessarry and it could have multiple owners)
+
+ - `is` (`EEType`)
+
+
+* it is also possible to define relations of type object by using `ObjectRelation`
+ instead of `SubjectRelation`
+
+* the first argument of `SubjectRelation` and `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 correponding to multiple entities 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)
+
+* optional properties for attributes and relations :
+
+ - `description` : 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` : list of conditions/constraints that the relation needs to
+ satisfy (c.f. `Contraints`_)
+
+ - `cardinality` : two characters string which specify the cardinality of the
+ relation. The first character defines the cardinality of the relation on
+ the subject, the second on the object of the relation. When a relation
+ has multiple possible subjects or objects, the cardinality applies to all
+ and not on a one to one basis (so it must be consistent...). The possible
+ values are inspired from regular expressions syntax :
+
+ * `1`: 1..1
+ * `?`: 0..1
+ * `+`: 1..n
+ * `*`: 0..n
+
+ - `meta` : boolean indicating that the relation is a meta-relation (false by
+ default)
+
+* optionnal 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 usefull 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 correpond to the RQL keywords `TODAY` and `NOW`.
+
+ - `vocabulary` : specify static possible values of an attribute
+
+* optionnal 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)
+
+* optionnal 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 need
+ to set 'object' as the 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 constraints 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 needs 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
+
+
+Relation definition
+-------------------
+
+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
+contains 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) by example ::
+
+ class locked_by(RelationType):
+ """relation on all entities indicating that they are locked"""
+ inlined = True
+ cardinality = '?*'
+ subject = '*'
+ object = 'EUser'
+
+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`)
+
+* `symetric` : boolean indication that the relation is symetrical, 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 symetrical, 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
+``````````````````````
+
+Define permissions is set through to the attribute `permissions` of entities and
+relations types. It defines a dictionnary 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_<ACTION>_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 <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 `EPermission` from the standard library
+allow to build very complex and dynamic security architecture. The schema of
+this entity type is as follow : ::
+
+ class EPermission(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('EGroup', 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 `EPermission` 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 `EPermission`, 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_<ACTION>_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.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/B030-define-views.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,238 @@
+.. -*- coding: utf-8 -*-
+
+.. _DefinitionVues:
+
+Views definition
+================
+
+Basic class for views
+---------------------
+
+Class `View` (`cubicweb.common.view`)
+`````````````````````````````````````
+
+A view writes in its output exit thanks to its attribute `w` (`UStreamIO`).
+
+The basic interface for views is as follows:
+
+* `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
+* `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`
+
+* `creator(eid)`, returns the eid and the login of the entity creator of the entity
+ having the eid given in the parameter
+
+Other basic classes:
+
+* `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
+
+
+The selection view principle
+----------------------------
+
+A view includes :
+
+- an identifier (all objects in `LAX` are entered in a registry
+ and this identifier will be used as a key)
+
+- a filter to select the resulsets it can be applied to
+
+
+For a given identifier, multiple views can be defined. `CubicWeb` uses
+a selector which computes scores so that it can identify and select the
+best view to apply in context. The selector library is in
+``cubicweb.common.selector`` and a library of the methods used to
+compute scores is in ``cubicweb.vregistry.vreq``.
+
+
+`CubicWeb` provides a lot of standard views, for a complete list, you
+will have to read the code in directory ``cubicweb/web/views/`` (XXX
+improve doc).
+
+For example, the view named ``primary`` is the one used to display
+a single entity.
+
+If you want to change the way a ``BlogEntry`` is displayed, just
+override the view ``primary`` in ``BlogDemo/views.py`` ::
+
+ 01. from ginco.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'<h1>%s</h1>' % entity.title)
+ 10. self.w(u'<p>published on %s in category %s</p>' % \
+ 11. (entity.publish_date.strftime('%Y-%m-%d'), entity.category))
+ 12. self.w(u'<p>%s</p>' % entity.text)
+
+The above source code defines a new primary view (`line 03`) for
+``BlogEntry`` (`line 05`).
+
+Since views are applied to resultsets and resulsets can be tables of
+data, it is needed to recover the entity from its (row,col)
+coordinates (`line 08`). We will get to this in more detail later.
+
+The view has a ``self.w()`` method that is used to output data. Here `lines
+09-12` output HTML tags and values of the entity's attributes.
+
+When displaying same blog entry as before, you will notice that the
+page is now looking much nicer.
+
+.. 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'<h1>%s</h1>' % entity.title)
+ 08. self.w(u'<p>%s</p>' % 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.
+
+At `line 09`, a simple request in made to build a resultset 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 resultset. At
+`line 10` the view 'primary' is applied to this resultset to output
+HTML.
+
+**This is to be compared to interfaces and protocols in object-oriented
+languages. Applying a given view to all the entities of a resultset only
+requires the availability, for each entity of this resultset, of a
+view with that name that can 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 resultset 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 cubicwweb.interfaces.ICalendarable interfaces on
+entities.BloEntry and apply the OneMonthCalendar and iCalendar views
+to resultsets 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 view that does 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 (it is not used in case an error is raised or for
+the login form by 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 necessarry
+2. identifying the view to use to render data if it is not specified
+3. composing the HTML page to return
+
+
+The default main template (`cubicweb.web.views.basetemplates.TheMainTemplate`)
+------------------------------------------------------------------------------
+
+The default main template build the page based on the following pattern:
+
+.. image:: images/main_template_layout.png
+
+The rectangle containing `view.dispathc()` 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 dictionnary of the forms parameters, before going the classic way (through
+ step 1 and 2 described juste above)
+
+.. include:: B031-views-stdlib.en.txt
+
+
+XML views, binaries...
+----------------------
+For the views generating other formats that HTML (an image generated dynamically
+by example), and which can not usually be included in the HTML page generated
+by the main template (see above), you have to:
+
+* set the atribute `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 the views dedicated to binary content creation (an image dynamically generated
+by example), we have to set the attribute `binary` of the class to `True` (which
+implies that `templateable == 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 by example) are not happy with empty `<div>`
+(by empty we mean that there is no content in the tag, but there
+could be attributes), so we should always use `<div></div>` even if
+it is empty and not use `<div/>`.
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/B031-views-stdlib.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,65 @@
+.. -*- coding: utf-8 -*-
+
+Predefined views in the library
+-------------------------------
+
+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
+ entity is in the result set and needs to be displayed. This view is supposed
+ to render a maximum of informations about the entity.
+:secondary:
+ secondary view of an entity. By default it renders the two first attributes
+ of the entity as a clickable link redirecting to the primary view.
+:oneline:
+ 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.
+:text:
+ similar to the `oneline` view, but should not contain HTML.
+: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 is 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:
+ creates a HTML list (`<ul>`) and call the view `listitem` for each entity
+ of the result set
+:listitem:
+ 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 dunblin core
+ methods of the entity (`dc_*`)
+
+Start view:
+
+:index:
+ home page
+:schema:
+ display the schema of the application
+
+Special views:
+
+:noresult:
+ called if the result set is empty
+:finall:
+ 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 (`<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:
+ view always applicable and which does not return anything
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/B040-define-workflows.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,159 @@
+.. -*- coding: utf-8 -*-
+
+Workflow definition
+======================
+
+General
+-------
+
+A workflow can be defined in a `CubicWeb` application thanks to the system
+entities ``State`` and ``Transition``. Those are defined within all
+`CubicWeb` application and can be set-up through the main administrator interface.
+
+Once your schema is defined, you can start creating the set of states and
+the required transitions for your applications entities.
+
+You first need to define the states and then the transitions between those
+to complete your workflow.
+
+A ``State`` defines the status of an entity. While creating a new state,
+you will be first given the option to select the entity type the state
+can be applied to. By choosing ``Apply``, a new section will be displayed
+in the editing screen to enable you to add relation to the state you are
+creating.
+
+A ``Transition`` is also based on an entity type it can be applied to.
+By choosing ``Apply``, a new section will be displayed in the editing
+screen to enable you to add relation to the transition you are
+creating.
+
+At the transition level you will also define the group of user which can
+aplly this transition to an object.
+
+
+Example of a simple workflow
+----------------------------
+
+Please see the tutorial to view and example of a simple workflow.
+
+
+[Create a simple workflow for BlogDemo, to have a moderator approve new blog
+entry to be published. This implies, specify a dedicated group of blog
+moderator as well as hide the view of a blog entry to the user until
+it reaches the state published]
+
+Set-up a workflow
+-----------------
+
+Before starting, make sure you refresh your mind by reading [link to
+definition_workflow chapter].
+
+We want to create a workflow to control the quality of the BlogEntry
+submitted on your application. When a BlogEntry is created by a user
+its state should be `submitted`. To be visible to all, it needs to
+be in the state `published`. To move from `submitted` to `published`
+we need a transition that we can name `approve_blogentry`.
+
+We do not want every user to be allowed to change the state of a
+BlogEntry. We need to define a group of user, `moderators`, and
+this group will have appropriate permissions to approve BlogEntry
+to be published and visible to all.
+
+There are two ways to create a workflow, form the user interface,
+and also by defining it in ``migration/postcreate.py``. This script
+is executed each time a new ``./bin/laxctl db-init`` is done.
+If you create the states and transitions through the user interface
+this means that next time you will need to initialize the database
+you will have to re-create all the entities.
+We strongly recommand you create the workflow in ``migration\postcreate.py``
+and we will now show you how.
+The user interface would only be a reference for you to view the states
+and transitions but is not the appropriate interface to define your
+application workflow.
+
+Update the schema
+~~~~~~~~~~~~~~~~~
+To enable a BlogEntry to have a State, we have to define a relation
+``in_state`` in the schema of BlogEntry. Please do as follows, 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 will have re-execute ``./bin/laxctl db-init``
+to initialize the database and migrate your existing entities.
+[WRITE ABOUT MIGRATION]
+
+Create states, transitions and group permissions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+At the time the ``postcreate.py`` script is executed, several methods
+can be used. They are all defined in the ``class ServerMigrationHelper``.
+We will only discuss the method we use to create a wrokflow here.
+
+To define our workflow for BlogDemo, please add the following lines
+to ``migration/postcreate.py``::
+
+ _ = unicode
+
+ moderators = add_entity('EGroup', name=u"moderators")
+
+ submitted = add_state(_('submitted'), 'BlogEntry', initial=True)
+ published = add_state(_('published'), 'BlogEntry')
+
+ add_transition(_('approve_blogentry'), 'BlogEntry', (submitted,), published, ('moderators', 'managers'),)
+
+ 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.
+
+``add_entity`` is used here to define the new group of users that we
+need to define the transitions, `moderators`.
+If this group required by the transition is not defined before the
+transition is created, it will not create the relation `transition
+require the group moderator`.
+
+``add_state`` expects as the first argument the name of the state you are
+willing to create, then the entity type on which the state can be applied,
+and an optionnal argument to set if the state is the initial state
+of the entity type or not.
+
+``add_transition`` expects as the first argument the name of the
+transition, then the entity type on which we can apply the transition,
+then the list of possible initial states from which the transition
+can be applied, the target state of the transition, and the permissions
+(e.g. list of the groups of users who can apply the transition, the user
+needs to belong to at least one of the listed group).
+
+
+We could have also added a RQL condition in addition to a group to
+which the user should belong to.
+
+If we use both RQL condition and group, the two must be satisfied
+for the user to be allowed to apply the transition.
+
+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 now notice that in the actions box of a BlogEntry, the state
+is now listed as well as the possible transitions from this state
+defined by the workflow. This transition, as defined in the workflow,
+will only being displayed for the users belonging to the group
+moderators of managers.
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/B050-data-as-objects.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,144 @@
+.. -*- coding: utf-8 -*-
+
+
+Stored data handling
+====================
+
+Classes `Entity` and `AnyEntity`
+--------------------------------
+
+To provide a specific behavior for each entity, we just need to define
+a class inheriting from `cubicweb.entities.EnyEntity`. In genera, we have
+to defined those classes in a module of `entites` 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 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 execcute the
+ requested action on the entity
+
+:Formatting and output generation:
+
+ * `view(vid, **kwargs)`, apply 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 necessarry)
+
+ * `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`
+
+
+*rtags*
+-------
+
+*rtags* allows 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 dictionnary with as its keys the triplet ::
+
+ <relation type>, <target entity type>, <context position ("subject" ou "object")>
+
+and as the values a `set` or a tuple of markers defining the properties that
+apply to this relation.
+
+It is possible to simplify this dictionnary:
+
+* if we want to specifiy a single marker, it is not necessarry to
+ use a tuple as the value, the marker by itself (characters 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 the key
+* if we want a marker to apply independently from the target entity type,
+ we have to use the string `*` as the target entity type
+
+
+Please note that this dictionnary is *treated at the time the class is created*.
+It is automatically merged with the parent class(es) (no need to copy the
+dictionnary from the parent class to modify it). Also, modify it after the
+class is created will not have any effect...
+
+.. include:: B051-define-entities.en.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/B051-define-entities.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,170 @@
+.. -*- coding: utf-8 -*-
+
+Parametrization and specific extensions
+---------------------------------------
+
+Dynamic default values
+``````````````````````
+It is possible to define in the schema *static* default values.
+It is also possible to define in the schema *dynamic* default values
+by defining in the entity class a method `default_<attribut name>` for
+a given attribute.
+
+
+Control of loaded attributes and default sorting
+````````````````````````````````````````````````
+
+* 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`.
+
+By example: ::
+
+ class Transition(AnyEntity):
+ """..."""
+ id = 'Transition'
+ fetch_attrs, fetch_order = fetch_config(['name'])
+
+Indique que pour le type d'entité "Transition" il faut précharger l'attribut
+"name" et trier par défaut selon cet attribut.
+
+
+Contrôle des formulaires d'édition
+``````````````````````````````````
+Il est possible de contrôler les attributs/relations dans la vue d'édition
+simple ou multiple à l'aide des *rtags* suivants :
+
+* `primary`, indique qu'un attribut ou une relation doit être incorporé dans
+ les formulaires d'édition simple et multiple. Dans le cas d'une relation,
+ le formulaire d'édition de l'entité liée sera inclus dans le formulaire
+
+* `secondary`, indique qu'un attribut ou une relation doit être incorporé dans
+ le formulaire d'édition simple uniquement. Dans le cas d'une relation,
+ le formulaire d'édition de l'entité liée sera inclus dans le formulaire
+
+* `generic`, indique qu'une relation doit être incorporé dans le formulaire
+ d'édition simple dans la boite générique d'ajout de relation
+
+* `generated`, indique qu'un attribut est caculé dynamiquement ou autre, et
+ qu'il ne doit donc pas être présent dans les formulaires d'édition
+
+Au besoin il est possible de surcharger la méthode
+`relation_category(rtype, x='subject')` pour calculer dynamiquement la catégorie
+d'édition d'une relation.
+
+
+Contrôle de la boîte "add_related"
+``````````````````````````````````
+La boite `add related` est une boite automatique proposant de créer une entité
+qui sera automatiquement liée à l'entité de départ (le contexte dans lequel
+s'affiche la boite). Par défaut, les liens présents dans cette boite sont
+calculés en fonction des propriétés du schéma de l'entité visualisée, mais il
+est possible de les spécifier explicitement à l'aide des *rtags* suivants :
+
+* `link`, indique qu'une relation est généralement créée vers une entité
+ existante et qu'il ne faut donc pas faire apparaitre de lien pour cette
+ relation
+
+* `create`, indique qu'une relation est généralement créée vers de nouvelles
+ entités et qu'il faut donc faire apparaitre un lien pour créer une nouvelle
+ entité et la lier automatiquement
+
+Au besoin il est possible de surcharger la méthode
+`relation_mode(rtype, targettype, x='subject')` pour caculer dynamiquement la
+catégorie de création d'une relation.
+
+A noter également que si au moins une action dans la catégorie "addrelated" est
+trouvée pour le contexte courant, le fonctionnement automatique est désactivé
+en faveur du fonctionnement explicite (i.e. affichage des actions de la
+catégorie "addrelated" uniquement).
+
+Contrôle des formulaires de filtrage de table
+`````````````````````````````````````````````
+La vue "table" par défaut gère dynamiquement un formulaire de filtrage du
+contenu de celle-ci. L'algorithme est le suivant :
+
+1. on considère que la première colonne contient les entités à restreindre
+2. on recupère la première entité de la table (ligne 0) pour "représenter"
+ toutes les autres
+3. pour toutes les autres variables définies dans la requête originale :
+
+ 1. si la variable est liée à la variable principale par au moins une
+ n'importe quelle relation
+ 2. on appelle la méthode `filterform_vocabulary(rtype, x)` sur l'entité
+ et si rien est retourné (ou plus exactement un tuple de valeur `None`,
+ voir ci-dessous) on passe à la variable suivante, sinon un élément de
+ formulaire de filtrage sera créé avec les valeurs de vocabulaire
+ retournées
+
+4. il n'y a pas d'autres limitations sur le rql, il peut comporter des clauses
+ de tris, de groupes... Des fonctions javascripts sont utilisées pour
+ regénérer une requête à partir de la requête de départ et des valeurs
+ séléctionnées dans les filtres de formulaire.
+
+
+La méthode `filterform_vocabulary(rtype, x, var, rqlst, args, cachekey)` prend
+en argument le nom d'une relation et la "cible", qui indique si l'entité sur
+laquelle la méthode est appellée est sujet ou objet de la relation. Elle doit
+retourner :
+
+* un 2-uple de None si elle ne sait pas gérer cette relation
+
+* un type et une liste contenant le vocabulaire
+
+ * la liste doit contenir des couples (valeur, label)
+ * le type indique si la valeur désigne un nombre entier (`type == 'int'`), une
+ chaîne de caractères (`type == 'string'`) ou une entité non finale (`type
+ == 'eid'`)
+
+Par exemple dans notre application de gestion de tickets, on veut pouvoir
+filtrés ceux-ci par :
+
+* type
+* priorité
+* état (in_state)
+* étiquette (tags)
+* version (done_in)
+
+On définit donc la méthode suivante : ::
+
+
+ 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: Le support du filtrage sur les étiquettes et l'état est installé
+automatiquement, pas besoin de le gérer ici.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/B060-form-management.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,133 @@
+.. -*- coding: utf-8 -*-
+
+Gestion de formulaires
+======================
+
+Contrôle de la génération automatique de formulaire pour les entités manipulée
+------------------------------------------------------------------------------
+XXX FILLME
+
+* les formulaires 'edition' et 'creation'
+
+Le formulaire généré par défaut ne vous convient pas ? Vous êtes peut-être pas
+obligé de le refaire à la main ! :)
+
+* rtags primary, secondary, generated, generic,
+ `Entity.relation_category(rtype, x='subject')`
+* inline_view (now a rtag?)
+* spécification widget
+
+
+Fonctionnement du contrôleur d'édition par défaut (id: 'edit')
+--------------------------------------------------------------
+
+Contrôle de l'édition
+`````````````````````
+Prérequis: les paramètres liés aux entités à éditer sont spécifiés de la forme ::
+
+ <nom de champ>:<eid de l'entité>
+
+où l'eid de l'entité pourra être une lettre dans le cas d'une entité à créer. On
+dénommera ces paramètres comme *qualifié*.
+
+1. récupération des entités à éditer en cherchant les paramètres de formulaire
+ commençant par 'eid:' ayant également un paramètre '__type' associé
+ (également *qualifié* par l'eid évidemment)
+
+2. pour tous les attributs et relations de chaque entité à éditer
+
+ 1. recherche d'un paramètre 'edits-<nom relation>' ou 'edito-<nom relation>'
+ qualifié dans le cas d'une relation dont l'entité est objet
+ 2. si trouvé, la valeur récupérée est considérée comme la valeur originale
+ pour cette relation, et on cherche la (ou les) nouvelle(s) valeur(s) dans
+ le paramètre <nom relation> (qualifié)
+ 3. si la valeur est différente de l'originale, une requête de modification en
+ base est effectuée
+
+3. pour chaque entité à éditer
+
+ 1. si un paramètre `__linkto` qualifié est spécifié, sa valeur doit être une
+ chaine (ou une liste de chaine) de la forme : ::
+
+ <relation type>:<eids>:<target>
+
+ où <target> vaut 'subject' ou 'object' et chaque eid peut-être séparé d'un
+ autre par un '_'. Target spécifie *l'entité éditée* est sujet ou objet de la
+ relation et chaque relation ainsi spécifiée sera insérée.
+
+ 2. si un paramètre `__cloned_eid` qualifié est spécifié pour une entité, les
+ relations de l'entité spécifiée en valeur de cette argument sont copiées sur
+ l'entité éditée
+
+
+ 3. si un paramètre `__delete` qualifié est spécifié, sa valeur doit être une
+ chaine (ou une liste de chaine) de la forme : ::
+
+ <subject eids>:<relation type>:<object eids>
+
+ où chaque eid sujet ou objet peut-être séparé d'un autre par un '_'. Chaque
+ relation ainsi spécifiée sera supprimée.
+
+ 4. si un paramètre `__insert` qualifié est spécifié, sa valeur doit être de
+ même format que pour `__delete`, mais chaque relation ainsi spécifiée sera
+ insérée.
+
+4. si les paramètres `__insert` et/ou `__delete` sont trouvés non qualifiés,
+ ils sont interprétés comme décrit ci-dessus (quelque soit le nombre d'entité
+ édité)
+
+5. si aucune entité n'est éditée mais que le formulaire contient les paramètres
+ `__linkto` et `eid`, celui-ci est interprété en prenant la valeur spécifié
+ par le paramètre `eid` pour désigner l'entité sur laquelle ajouter les
+ relations
+
+
+A noter que :
+
+* si le paramètre `__action_delete` est trouvé, toutes les entités comme
+ spécifiées à éditer seront supprimées
+
+* si le paramètre `__action_cancel` est trouvé, aucune action n'est effectuée
+
+* si le paramètre `__action_apply` est trouvé, l'édition est effectuée
+ normalement mais la redirection sera effectuée sur le formulaire (cf `Contrôle
+ de la redirection`_)
+
+* le paramètre `__method` est également supporté comme sur le template principal
+ (XXX not very consistent, maybe __method should be dealed in the view controller)
+
+* si aucune entité à éditer n'est trouvée et qu'il n'y a pas de paramètre
+ `__action_delete`, `__action_cancel`, `__linkto`, `__delete` ou `__insert`,
+ une erreur est levée
+
+* placer dans le formulaire le paramètre `__message` permettra d'utiliser la
+ valeur de ce paramètre comme message d'information à l'utilisateur une fois
+ l'édition effectuée.
+
+
+Contrôle de la redirection
+``````````````````````````
+Une fois que l'édition s'est bien passé, reste un problème : c'est bien beau
+tout ça, mais où qu'on va maintenant ?? Si rien n'est spécifié, le controlleur
+se débrouille, mais comme il fait pas toujours ce qu'on voudrait, on peut
+controller ça en utilisant les paramètres suivant :
+
+* `__redirectpath`: chemin de l'url (relatif à la racine du site, sans paramètre
+ de formulaire
+
+* `__redirectparams`: paramètres de formulaires à ajouter au chemin
+
+* `__redirectrql`: requête RQL de redirection
+
+* `__redirectvid`: identifiant de vue de redirection
+
+* `__errorurl`: url du formulaire original, utilisé pour la redirection en cas
+ d'erreur de validation pendant l'édition. Si celui-ci n'est pas spécifié, une
+ page d'erreur sera présentée plutot qu'un retour sur le formulaire (qui est le
+ cas échéant responsable d'afficher les erreurs)
+
+* `__form_id`: identifiant de vue du formulaire original, utilisée si
+ `__action_apply` est trouvé
+
+En général on utilise soit `__redirectpath et `__redirectparams` soit
+`__redirectrql` et `__redirectvid`.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/B070-ajax-json.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,16 @@
+.. -*- coding: utf-8 -*-
+
+AJAX
+====
+JSON bla bla
+XXX FILLME
+
+
+Le contrôleur 'json'
+--------------------
+XXX FILLME
+
+
+API Javascript
+--------------
+XXX FILLME
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/B080-internationalization.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,100 @@
+.. -*- coding: utf-8 -*-
+
+.. _internationalization:
+
+
+Internationalization
+====================
+
+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 internalization
+----------------------
+
+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'<div class="searchMessage"><strong>%s</strong></div>\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 translation string
+it-self, but not it's translation.
+
+In the other hand the request's method `_` is ment to retrive 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 internalization 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 dont
+ need to use this command.
+
+* `i18nupdate` updates the translation catalogs of *one particular
+ component* (or of all components). FIXME 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 transaltion 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/<lang>/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 <component>`
+2. Edit the <component>/xxx.po files and add missing translations (empty `msgstr`)
+3. `hg ci -m "updated i18n catalogs"`
+4. `cubicweb-ctl i18n compile <myapplication>`
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/B081-i18n.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,71 @@
+.. -*- 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/<lang>/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 <composant>`
+2. éditer les fichiers <composant>/xxx.po dans pour y rajouter les traductions
+ manquantes (`msgstr` vide)
+3. `hg ci -m "updated i18n catalogs"`
+4. `cubicweb-ctl i18n compile <monapplication>`
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/B090-ui-components.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,14 @@
+Autres composants de l'interface web
+====================================
+
+Actions
+-------
+XXXFILLME
+
+Component, VComponent
+---------------------
+XXXFILLME
+
+EProperty
+---------
+XXXFILLME
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/B100-hooks.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,31 @@
+.. -*- coding: utf-8 -*-
+
+Les crochets (*hooks*)
+======================
+
+XXX FILLME
+
+Les crochets sont appelés avant ou après la mise à jour d'une entité ou d'une
+relations dans le dépot
+
+Leur prototypes sont les suivants
+
+
+ * 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
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/B110-notifications.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,6 @@
+.. -*- coding: utf-8 -*-
+
+Gestion de notifications
+========================
+
+XXX FILLME
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/B120-migration.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,218 @@
+.. -*- coding: utf-8 -*-
+
+
+Migration
+=========
+
+Une des idées de base d'Erudi est la création incrémentale d'application, et
+pour cela de nombreuses actions sont fournies afin de facilement faire évoluer
+une application et tout particulièrement le modèle de données manipulé sans
+perdre les données des instances existantes.
+
+La version courante d'un modèle d'application est données dans le fichier
+`__pkginfo__.py` sous forme d'un tuple de 3 entiers.
+
+
+Gestion des scripts de migrations
+---------------------------------
+Les scripts des migrations doivent être placés dans le répertoire `migration` de
+l'application, et nommé de la manière suivante :
+
+::
+
+ <n° de version X.Y.Z>[_<description>]_<mode>.py
+
+dans lequel :
+
+* X.Y.Z correspond au n° de version du modèle vers lequel le script permet de
+ migrer,
+
+* le *mode* (entre le dernier "_" et l'extension ".py") indique à quelle partie
+ de l'application (serveur RQL, serveur web) le script s'applique en cas
+ d'installation distribuée. Il peut valoir :
+
+ * `common`, s'applique aussi bien sur le serveur RQL que sur le serveur web,
+ et met à jour des fichiers sur le disque (migration de fichier de
+ configuration par exemple).
+
+ * `web`, s'applique uniquement sur le serveur web, et met à jour des fichiers
+ sur le disque
+
+ * `repository`, s'applique uniquement sur le serveur RQL, et met à jour des
+ fichiers sur le disque
+
+ * `Any`, s'applique uniquement sur le serveur RQL, et met à jour des
+ données en base (migrations de schéma et de données par ex.)
+
+
+Toujours dans le répertoire `migration`, le fichier spécial `depends.map` permet
+d'indiquer que pour migrer vers une version spécifique du modèle, il faut tout
+d'abord avoir migrer vers une version données de erudi. Ce fichier peut contenir
+des commentaires (lignes commençant par un "#"), et une dépendance est notée sur
+une ligne de la manière suivante : ::
+
+ <n° de version du modèle X.Y.Z> : <n° de version erudi X.Y.Z>
+
+Par exemple ::
+
+ 0.12.0: 2.26.0
+ 0.13.0: 2.27.0
+ # 0.14 works with 2.27 <= erudi <= 2.28 at least
+ 0.15.0: 2.28.0
+
+
+Contexte de base
+----------------
+Les identifiants suivants sont préféfinis dans les scripts de migration :
+
+* `config`, configuration de l'instance
+
+* `interactive_mode`, booléen indiquant si le script est éxécuté en mode
+ interactif ou non
+
+* `appltemplversion`, version du modèle d'application de l'instance
+
+* `applerudiversion`, version erudi de l'instance
+
+* `templversion`, version du modéle d'application installée
+
+* `erudiversion`, version erudi installée
+
+* `confirm(question)`, fonction posant une question et retournant vrai si
+ l'utilisateur a répondu oui, faux sinon (retourne toujours vrai en mode non
+ interactif)
+
+* `_`, fonction équivalente à `unicode` permettant de marquer des chaines à
+ internationaliser dans les scripts de migration
+
+Dans les scripts "repository", les identifiants suivant sont également définis :
+
+* `checkpoint`, demande confirmant et effectue un "commit" au point d'appel
+
+* `repo_schema`, schéma persistent de l'instance (i.e. schéma de l'instance en
+ cours de migration)
+
+* `newschema`, schéma installé sur le système de fichier (i.e. schéma de la
+ version à jour du modèle et de erudi)
+
+* `sqlcursor`, un curseur SQL pour les très rares cas où il est réellement
+ nécessaire ou avantageux de passer par du sql
+
+* `repo`, l'objet repository
+
+
+Migration de schéma
+-------------------
+Les fonctions de migration de schéma suivantes sont disponibles dans les scripts
+"repository" :
+
+* `add_attribute(etype, attrname, attrtype=None, commit=True)`, ajoute un
+ nouvel attribut à un type d'entité existante. Si le type de celui-ci n'est pas
+ spécifié il est extrait du schéma à jour.
+
+* `drop_attribute(etype, attrname, commit=True)`, supprime un
+ attribut à un type d'entité existante.
+
+* `rename_attribute(etype, oldname, newname, commit=True)`, renomme un attribut
+
+* `add_entity_type(etype, auto=True, commit=True)`, ajoute un nouveau type
+ d'entité. Si `auto` est vrai, toutes les relations utilisant ce type d'entité
+ et ayant un type d'entité connu à l'autre extrémité vont également être
+ ajoutées.
+
+* `drop_entity_type(etype, commit=True)`, supprime un type d'entité et toutes
+ les relations l'utilisant.
+
+* `rename_entity_type(oldname, newname, commit=True)`, renomme un type d'entité
+
+* `add_relation_type(rtype, addrdef=True, commit=True)`, ajoute un nouveau type
+ de relation. Si `addrdef` est vrai, toutes les définitions de relation de ce
+ type seront également ajoutées.
+
+* `drop_relation_type(rtype, commit=True)`, supprime un type de relation et
+ toutes les définitions de ce type.
+
+* `rename_relation(oldname, newname, commit=True)`, renomme une relation.
+
+* `add_relation_definition(subjtype, rtype, objtype, commit=True)`, ajoute une
+ définition de relation.
+
+* `drop_relation_definition(subjtype, rtype, objtype, commit=True)`, supprime
+ une définition de relation.
+
+* `synchronize_permissions(ertype, commit=True)`, synchronise les permissions
+ d'un type d'entité ou de relation
+
+* `synchronize_rschema(rtype, commit=True)`, synchronise les propriétés et
+ permissions d'un type de relation.
+
+* `synchronize_eschema(etype, commit=True)`, synchronise les propriétés et
+ permissions d'un type d'entité.
+
+* `synchronize_schema(commit=True)`, synchronise le schéma persistent avec le
+ schéma à jour (mais sans ajouter ni supprimer de nouveaux types d'entités ou
+ de relations ni de définitions de relation).
+
+* `change_relation_props(subjtype, rtype, objtype, commit=True, **kwargs)`, change
+ les propriétés d'une definition de relation en utilisant les arguments nommés
+ pour les propriétés à changer.
+
+* `set_widget(etype, rtype, widget, commit=True)`, change le widget à utiliser
+ pour la relation <rtype> du type d'entité <etype>
+
+* `set_size_constraint(etype, rtype, size, commit=True)`, change la contrainte
+ de taille pour la relation <rtype> du type d'entité <etype>
+
+
+Migration de données
+--------------------
+Les fonctions de migration de données suivantes sont disponibles dans les scripts
+"repository" :
+
+* `rql(rql, kwargs=None, cachekey=None, ask_confirm=True)`, éxécute une
+ requête rql arbitraire, d'interrogation ou de modification. Un objet result
+ set est retourné.
+
+* `add_entity(etype, *args, **kwargs)`, ajoute une nouvelle entité du type
+ données. La valeur des attributs et relations est spécifiée en utilisant les
+ arguments nommés et positionnels.
+
+
+Création de workflow
+--------------------
+Les fonctions de création de workflow suivantes sont disponibles dans les scripts
+"repository" :
+
+* `add_state(name, stateof, initial=False, commit=False, **kwargs)`, ajoute un
+ nouvel état de workflow
+
+* `add_transition(name, transitionof, fromstates, tostate, requiredgroups=(), commit=False, **kwargs)`,
+ ajoute une nouvelle transtion de workflow
+
+Migration de configuration
+--------------------------
+Les fonctions de migration de configuration suivantes sont disponibles dans tout
+les scripts :
+
+* `option_renamed(oldname, newname)`, indique qu'une option a été renommée
+
+* `option_group_change(option, oldgroup, newgroup)`, indique qu'une option a
+ changé de groupe
+
+* `option_added(oldname, newname)`, indique qu'une option a été ajoutée
+
+* `option_removed(oldname, newname)`, indique qu'une option a été supprimée
+
+
+Autres fonctions de migration
+-----------------------------
+Ces fonctions ne sont utilisés que pour des opérations de bas niveau
+irréalisables autrement ou pour réparer des bases cassées lors de session
+interactive. Elles sont disponibles dans les scripts "repository".
+
+* `sqlexec(sql, args=None, ask_confirm=True)`, éxécute une requête sql
+ arbitraire, à n'utiliser
+
+* `add_entity_type_table(etype, commit=True)`
+* `add_relation_type_table(rtype, commit=True)`
+* `uninline_relation(rtype, commit=True)`
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/B130-tests.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,38 @@
+.. -*- coding: utf-8 -*-
+
+Tests
+=====
+
+Écriture de tests unitaires
+---------------------------
+Le framework de test fournit principalement deux classes de tests dans le module
+`ginco.devtools.apptest`:
+
+* `EnvBasedTC`, pour simuler un environnement complet (web + repository)
+* `RepositoryBasedTC`, pour simuler un environnement de repository uniquement
+
+Ces deux classes ont quasiment la même interface et proposent un certain nombre de méthodes
+rendant l'écriture de test puissante et rapide.
+
+XXXFILLME describe API
+
+Dans la plupart des cas, vous allez vouloir hériter de `EnvBasedTC` pour écrire des tests
+unitaires ou fonctionnels pour vos entités, vues, crochets...
+
+
+Test des courriels de notifications
+```````````````````````````````````
+Lors de l'éxécution de tests les courriels potentiellement générés ne sont pas réellement
+envoyé mais se retrouve dans la liste `MAILBOX` du module `ginco.devtools.apptest`. Cette
+liste est remise à zéro au *setUp* de chaque test (par le setUp des classes `EnvBasedTC`
+et `RepositoryBasedTC`).
+
+Vous pouvez donc tester vos notifications en analysant le contenu de cette liste, qui
+contient des objets ayant deux attributs :
+* `recipients`, la liste des destinataires
+* `msg`, l'objet email.Message
+
+
+Tests automatiques
+------------------
+XXXFILLME
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/B140-google-appengine.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,11 @@
+.. -*- coding: utf-8 -*-
+
+.. _contents:
+
+==========================
+Google AppEngine Datastore
+==========================
+
+
+.. include:: B141-intro.en.txt
+.. include:: B142-install.en.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/B141-intro.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,44 @@
+.. -*- 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`.
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/B142-install.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,220 @@
+.. -*- coding: utf-8 -*-
+
+.. _installation:
+
+Installation
+============
+
+Download the source
+-------------------
+
+- The `Google AppEngine SDK` can be downloaded from:
+ http://code.google.com/appengine/downloads.html
+
+- `LAX` is available as an extension of `CubicWeb` under the GPLv2
+ license which can be downloaded from : http://cubicweb.org/
+
+Please follow instructions on how to install `CubicWeb` framework.
+
+Once ``cubicweb-ctl`` is installed, then you can create a Google
+App Engine extension of our framework by running the command ::
+
+ cubicweb-ctl newgapp <myapp>
+
+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
+`LAX` framework and its third-party libraries. You will notice that
+the directory ``cubes`` is a library of reusable components.
+
+The main directories that you should know about are:
+
+ - ``cubes`` : this is a library of reusable yams components. To use
+ those components you will list them in the variable
+ `included-yams-cubes` of ``app.conf``. See also :ref:`components`.
+ - [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 <myapp>``, 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
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+`LAX` 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
+'erudi'". 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 components from ginco-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 <http://localhost:8080/_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 <http://localhost:8080/?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 <http://localhost:8080/?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 <http://localhost:8080/?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/ <http://localhost:8080>`_
+as a normal user.
+
+Unless you did something to change it, http://MYAPP_URL should be
+http://localhost:8080/
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/BXXX-actions.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,9 @@
+.. -*- coding: utf-8 -*-
+
+Actions
+=========
+
+[WRITE ME]
+
+* talk about actions that appear in the action box
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/BXXX-boxes.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,9 @@
+.. -*- coding: utf-8 -*-
+
+Boxes
+=========
+
+[WRITE ME]
+
+* boxes in the web interface
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/BXXX-configuration.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,9 @@
+.. -*- coding: utf-8 -*-
+
+Configuration
+-------------
+
+[WRITE ME]
+
+* the config object. adding configuration option
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/BXXX-dbapi.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,9 @@
+.. -*- coding: utf-8 -*-
+
+DB-API
+=========
+
+[WRITE ME]
+
+* direct connection to the repository
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/BXXX-embedding-external-page.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,9 @@
+.. -*- coding: utf-8 -*-
+
+Embedding external pages
+========================
+
+[WRITE ME]
+
+* including external content
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/BXXX-online-doc.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,9 @@
+.. -*- coding: utf-8 -*-
+
+Online documentation system
+===========================
+
+[WRITE ME]
+
+* describe the on-line documentation system
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/BXXX-registry.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,147 @@
+.. -*- 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
+ - its selector may be derivated 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.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/BXXX-repository-operations.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,9 @@
+.. -*- coding: utf-8 -*-
+
+Repository operations
+======================
+
+[WRITE ME]
+
+* repository operations
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/BXXX-repository-session.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,9 @@
+.. -*- coding: utf-8 -*-
+
+Repository sessions
+===================
+
+[WRITE ME]
+
+* repository sessions
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/BXXX-repository-tasks.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,9 @@
+.. -*- coding: utf-8 -*-
+
+Tasks
+=========
+
+[WRITE ME]
+
+* repository tasks
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/BXXX-request.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,9 @@
+.. -*- coding: utf-8 -*-
+
+request
+=======
+
+[WRITE ME]
+
+* the request object
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/BXXX-sessions.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,9 @@
+.. -*- coding: utf-8 -*-
+
+sessions
+========
+
+[WRITE ME]
+
+* authentication and management of sessions
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/BXXX-templates.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,9 @@
+.. -*- coding: utf-8 -*-
+
+Templates
+=========
+
+[WRITE ME]
+
+* talk about main templates, etc.
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/BXXX-urlrewrite.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,11 @@
+.. -*- coding: utf-8 -*-
+
+URL Rewriting
+=============
+
+XXX FIXME this should be a chapter
+
+[WRITE ME]
+
+* show how urls are mapped to selections and views and explain URLRewriting
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/C000-administration.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,17 @@
+.. -*- coding: utf-8 -*-
+
+
+==========================
+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-site-config.en.txt
+ C030-instance-config.en.txt
+ C040-rql.en.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/C010-setup.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,13 @@
+.. -*- coding: utf-8 -*-
+
+.. _MiseEnPlaceEnv:
+
+===================================================
+Installation and set-up of a `CubicWeb` environment
+===================================================
+.. contents::
+
+.. include:: C011-installation.en.txt
+.. include:: C012-create-instance.en.txt
+.. include:: C013-cubicweb-ctl.en.txt
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/C011-bis-installation.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,79 @@
+.. -*- coding: utf-8 -*-
+
+.. _installationGAE:
+
+Installation de `CubicWeb` pour GoogleAppEngine
+===============================================
+
+Qu'est-ce que `LAX` ?
+=======================
+
+`LAX` (Logilab Appengine eXtension) est un framework d'application
+web basé sur `Google AppEngine`.
+
+`LAX` est un portage de la partie web de la plate-forme applicative
+développée par Logilab depuis 2001. Cette plate-forme publie des
+données tirées de bases SQL, d'annuaires LDAP et de systèmes de
+gestion de version. En avril 2008, elle a été portée pour fonctionner
+sur le "datastore" de `Google AppEngine`.
+
+XXX: faire un parallèle entre Django/GAE et LAX/GAE
+
+
+Téléchargement des sources
+==========================
+
+- Les sources de `Google AppEngine` peuvent être récupérées à l'adresse
+ suivante : http://code.google.com/appengine/downloads.html
+
+- Les sources de `LAX` se trouvent à l'adresse suivante :
+ http://lax.logilab.org/
+
+
+Installation
+============
+
+Une fois décompactée, l'archive `lax-0.1.0-alpha.tar.gz`, on obtient
+l'arborescence suivante::
+
+ .
+ |-- app.yaml
+ |-- custom.py
+ |-- data
+ |-- ginco/
+ |-- i18n/
+ |-- logilab/
+ |-- main.py
+ |-- mx/
+ |-- rql/
+ |-- schema.py
+ |-- simplejson/
+ |-- tools/
+ | |-- generate_schema_img.py
+ | `-- i18ncompile.py
+ |-- views.py
+ |-- yams/
+ `-- yapps/
+
+
+On retrouve le squelette d'une application web de `Google AppEngine`
+(fichiers ``app.yaml``, ``main.py`` en particulier) avec les dépendances
+supplémentaires nécessaires à l'utilisation du framework `LAX`
+
+
+Lancement de l'application de base
+==================================
+
+Plusieurs répertoires doivent être accessibles via la variable
+d'environnement ``PYTHONPATH`` ::
+
+ $ export PYTHONPATH=/path/to/google_appengine:/path/to/google_appengine/lib/yaml/lib:/path/to/myapp/
+
+Le répertoire yaml n'est nécessaire que pour le lancement des scripts
+qui se trouvent dans lax/tools et pour l'exécution des tests unitaires.
+
+Pour démarrer::
+
+ $ python /path/to/google_appengine/dev_appserver.py /path/to/lax
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/C011-installation.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,158 @@
+.. -*- coding: utf-8 -*-
+
+Installation
+============
+
+Installation of `Cubicweb` and its dependancies
+-----------------------------------------------
+
+`CubicWeb` is available as a debian package as well as an archive.
+We will detail here the two easiest way to set-up `CubciWeb`
+environment.
+
+Debian packages
+```````````````
+You need first to make sure that you added our public repository
+in the list of sources you packages manager will search in.
+
+Depending on the debian distribution you are using here are all the
+available options: ::
+
+ deb http://ftp.logilab.org/dists/ lenny/
+ deb http://ftp.logilab.org/dists/ hardy/
+ deb http://ftp.logilab.org/dists/ sid/
+
+As we assume you are installing `CubciWeb` on a debian machine, please
+add the appropriate line from above in ``/etc/apt/sources.list``.
+
+You can now install the required packages with the follwoing command: ::
+
+ apt-get install cubicweb
+
+This is it!
+
+``tar.gz`` archive
+``````````````````
+
+You can download our sources at: ::
+
+ http://ftp.logilab.org/pub/cubicweb/
+
+Unpack the sources
+
+
+
+
+.. note::
+ `CubicWeb` is also available as a Mercurial repository using the forest
+ extension (see :ref:`MercurialForestInstall` for more details).
+
+
+Postgres installation
+`````````````````````
+
+Please refer to the project online documentation Postgres_.
+
+.. _Postgres: 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 is accessible through Pyro
+ or if the client and the server are not running on the same machine
+ (in suche case the packages will have to be isntalled on both
+ machines)
+
+* `python-ldap` if you plan to use a LDAP source on the server
+
+.. _ConfigurationEnv:
+
+Environment configuration
+-------------------------
+
+[FIXME]
+Ces variables ne sont plus requises pour le bon fonctionnement de `CubicWeb`, non?
+A part rajouter la foret dans le PYTHONPATH, rien de plus ne doit etre fait?
+
+Update the environment variable PYTHONPATH to add to it 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
+
+ //deprecated??
+ export ERUDI_REGISTRY=~/etc/erudi.d/
+ export ERUDI_TEMPLATES=~/hg/
+ export ERUDI_RUNTIME=/tmp/
+
+Cela suppose que le composant erudi que vous développez est dans un
+sous-répertoire de *~/hg/* et que vous avez créé le répertoire *~/etc/erudi.d/*
+pour que `cubicweb-ctl` y place vos instances de test.
+
+.. _ConfigurationPostgres:
+
+Postgres configuration
+----------------------
+
+* First you have to initialize the database Postgres with the command ``initdb``.
+ ::
+
+ $ initdb -D /path/to/pgsql
+
+ Once initialized, you can launch 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
+
+* Create a superuser for `CubicWeb` instance (**root**) ::
+
+ createuser -s username
+
+ Initialize the password of the superuser you juste created with
+ ``su - postgres`` and ``psql``.
+
+ This password will be asked to you later on where you will create an
+ instance with `cubicweb-ctl create`
+
+[XXX]
+Est-ce que ces etapes sont vraiment necessaires?
+sand : lors de l'installation de ma bdd cela n'a pas ete fait
+et il semble que tout aille bien. Doit etre verifie avec les experts.
+
+* 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
+
+
+Pyro configuration
+------------------
+
+If you use Pyro, it is required to have a name server Pyro runing on your
+network (by default it is identified by a broadcast request).
+
+To do so, you need to :
+
+* launch the server manually before starting cubicweb with `pyro-ns`
+
+* 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 macine fire up
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/C012-create-instance.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,123 @@
+.. -*- 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
+one or more cubes.
+
+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 schems and workflows
+in an independant directory located in ``/path/to/forest/cubicweb/cubes/``.
+
+When an instance is created, you list one or more cubes that your instance
+will use. Use 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).
+
+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 by 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 transaction [FIXME - bas niveau]. 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/moninstance/*. 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
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/C013-cubicweb-ctl.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,123 @@
+.. -*- coding: utf-8 -*-
+
+.. _cubicweb-ctl:
+
+``cubicweb-ctl`` tool
+=====================
+
+`cubicweb-ctl` is the swiss knife to manage `CubicWeb` instances.
+The general syntax is ::
+
+ cubicweb-ctl <command> [options command] <arguments commands>
+
+To view available commands ::
+
+ cubicweb-ctl
+ cubicweb-ctl --help
+
+Please note that the commands available depends on the `CubicWeb` packages
+and cubes that have been installed.
+
+To view the help menu on specific command ::
+
+ cubicweb-ctl <command> --help
+
+Command to create a cube
+------------------------
+
+* ``newcube``, create a new cube on the file system based on the name
+ given in the parameters. This command create a cube from an application
+ skeleton that includes default files required for debian packaging.
+
+
+Command to create an instance
+-----------------------------
+* ``create``, creates the files for the instance configuration
+* ``db-create``, creates the system database of an instance (tables and
+ extensions only)
+* ``db-init``, initializes the system database of an instance
+ (schema, groups, users, workflows...)
+
+By default, those three commandes are encapsulated in ``create`` so
+that they can be executed consecutively.
+
+Command to create an instance for Google AppEngine datastore source
+-------------------------------------------------------------------
+* ``newgapp``, creates the configuration files for an instance
+
+This command needs to be followed by the commands responsible for
+the database initialization. As those are specific to the `datastore`,
+specific Google AppEgine database, they are not available for now
+in cubicweb-ctl, but they are available in the instance created.
+
+[FIXME] - add link to gae install
+For more details, please see :ref:`` .
+
+Commands to launch instance
+---------------------------
+* ``start``, starts one or more or all instances
+* ``stop``, stops one or more or all instances
+* ``restart``, restarts one or more or all instances
+* ``status``, returns the status of the instance
+
+Commands to maintain instances
+------------------------------
+* ``upgrade``, launches the existing instances migration when a new version
+ of `CubicWeb` or the cubes installed is available
+* ``shell``, opens a migration shell for manual maintenance of the instance
+* ``db-dump``, creates a dump of the system database
+* ``db-restore``, restores a dump of the system database
+* ``db-check``, checks data integrity of an instance. If the automatic correction
+ is activated, it is recommanded to create a dump before this operation.
+* ``schema-sync``, synchronizes the persistent schema of an instance with
+ the application schema. It is recommanded to create a dump before this operation.
+
+Commands to maintain i18n catalogs
+----------------------------------
+* ``i18nlibupdate``, regenerates messages catalogs of the `CubicWeb` library
+* ``i18nupdate``, regenerates the messages catalogs of a cube
+* ``i18ncompile``, recompiles the messages catalogs of an instance.
+ This is automatically done while upgrading.
+
+Cf :ref:`Internationalisation`.
+
+Other commands
+--------------
+* ``list``, provides a list of the available configuration, cubes
+ and instances.
+* ``delete``, deletes an instance (configuration files and database)
+
+Examples
+--------
+
+Create an instance from an existing cube
+````````````````````````````````````````
+
+To create an instance from an existing cube, execute the following
+command ::
+
+ cubicweb-ctl create <cube_name> <instance_name>
+
+This command will create the configuration files of an instance in
+``~/etc/cubicweb.d/<instance_name>``.
+The tool ``cubicweb-ctl`` allows you to execute the command ``db-create``
+and ``db-init`` when you run ``create`` so that you can complete an
+instance creation in a single command.
+
+If you decide not to execut those commands while ``cubicweb-ctl create``,
+then you will have to execute them seperately(``cubicweb-ctl db-create``,
+``cubicweb-ctl db-init`` ) otherwise your installation will not be complete
+and you will not be able to launch your instance.
+
+
+Creation of an instance from a new cube
+```````````````````````````````````````
+
+Create first your new cube cube ::
+
+ cubicweb-ctl newcube <mycube>
+
+This will create a new cube in ``/path/to/forest/cubicweb/cubes/<mycube>``
+and then create an instance as explained just above.
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/C020-site-config.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,94 @@
+.. -*- coding: utf-8 -*-
+
+Interface de configuration du site
+==================================
+
+.. 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]
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/C030-instance-config.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,162 @@
+.. -*- coding: utf-8 -*-
+
+Configuration d'une instance
+============================
+
+À la création d'une instance, un fichier de configuration est généré dans ::
+
+ $(CW_REGISTRY)/<instance>/<nom configuration>.conf
+
+par exemple ::
+
+ /etc/cubicweb.d/jpl/all-in-one.conf
+
+C'est un simple fichier texte au format INI. Dans la description suivante,
+chaque nom d'option est préfixé de sa section et suivi de sa valeur par défaut
+le cas échéant, e.g. "`<section>.<option>` [valeur]".
+
+
+Configuration du serveur web
+----------------------------
+:`web.auth-mode` [cookie]:
+ mode d'authentification, cookie ou http
+:`web.realm`:
+ realm de l'application en mode d'authentification http
+:`web.http-session-time` [0]:
+ délai d'inactivité d'une session HTTP avant sa fermeture automatique. Durée
+ en secondes, 0 signifiant pas d'expiration (ou plus exactement lors de la
+ fermeture du navigateur du client)
+
+:`main.anonymous-user`, `main.anonymous-password`:
+ login et mot de passe à utiliser pour se connecter au serveur RQL lors des
+ connexions HTTP anonymes. Il faut que le compte EUser associé existe.
+
+:`main.base-url`:
+ url de base du site, à utiliser pour générer les urls des pages web
+
+Configuration https
+```````````````````
+Il est possible de rendre un site accessible en http pour les connections
+anonymes et en https pour les utilisateurs authentifié. Il faut pour cela
+utiliser apache (par ex.) pour la redirection et la variable `main.https-url` du
+fichier de configuration.
+
+:Exemple:
+
+ pour une redirection apache d'un site accessible via `http://localhost/demo`
+ et `https://localhost/demo` et qui tourne en réalité sur le port 8080, il
+ faut avoir pour la version http : ::
+
+ RewriteCond %{REQUEST_URI} ^/demo
+ RewriteRule ^/demo$ /demo/
+ RewriteRule ^/demo/(.*) http://127.0.0.1:8080/$1 [L,P]
+
+ et pour la version https : ::
+
+ RewriteCond %{REQUEST_URI} ^/demo
+ RewriteRule ^/demo$ /demo/
+ RewriteRule ^/demo/(.*) http://127.0.0.1:8080/https/$1 [L,P]
+
+
+ et on aura dans le fichier all-in-one.conf de l'instance : ::
+
+ base-url = http://localhost/demo
+ https-url = `https://localhost/demo`
+
+Configuration de l'interface web
+--------------------------------
+:`web.embed-allowed`:
+ expression régulière correspondant aux sites pouvant être "incorporé" dans
+ le site (controleur 'embed')
+:`web.submit-url`:
+ url à laquelle les bugs rencontrés dans l'application peuvent être posté
+
+
+Configuration du serveur RQL
+----------------------------
+:`main.host`:
+ nom de l'hôte s'il ne peut être détecter correctement
+:`main.pid-file`:
+ fichier où sera écrit le pid du serveur
+:`main.uid`:
+ compte utilisateur à utiliser pour le lancement du serveur quand il est
+ lancé en root par init
+:`main.session-time [30*60]`:
+ temps d'expiration d'une session RQL
+:`main.query-log-file`:
+ fichier dans lequel écrire toutes les requêtes RQL éxécutées par le serveur
+
+
+Configuration Pyro pour l'instance
+-----------------------------------
+Coté serveur web :
+
+:`pyro-client.pyro-application-id`:
+ identifiant pyro du serveur RQL (e.g. le nom de l'instance)
+
+Coté serveur RQL :
+
+:`pyro-server.pyro-port`:
+ numéro de port pyro. Si aucune valeur n'est spécifiée, un port est attribué
+ automatiquement.
+
+Coté serveur RQL et serveur web :
+
+:`pyro-name-server.pyro-ns-host`:
+ nom de l'hôte hébergeant le serveur de nom pyro. Si aucune valeur n'est
+ spécifié, il est localisé par une requête de broadcast
+:`pyro-name-server.pyro-ns-group` [cubicweb]:
+ groupe pyro sous lequel enregistrer l'application
+
+
+Configuration courriel
+----------------------
+Coté serveur RQL et serveur web :
+
+:`email.mangle-emails [no]`:
+ indique si les adresses email doivent être affichées telle quelle ou
+ transformée
+
+Coté serveur RQL :
+
+:`email.smtp-host [mail]`:
+ nom de l'hôte hébergeant le serveur SMTP à utiliser pour le courriel sortant
+:`email.smtp-port [25]`:
+ port du serveur SMTP à utiliser pour le courriel sortant
+:`email.sender-name`:
+ nom à utiliser pour les courriels sortant de l'application
+:`email.sender-addr`:
+ adresse à utiliser pour les courriels sortant de l'application
+:`email.default-dest-addrs`:
+ adresses de destination par défaut, si utilisé par la configuration de la
+ diffusion du modèle (séparées par des virgules)
+:`email.supervising-addrs`:
+ addresses de destination des courriels de supervision (séparées par des
+ virgules)
+
+
+Configuration journalisation
+----------------------------
+:`main.log-threshold`:
+ niveau de filtrage des messages (DEBUG, INFO, WARNING, ERROR)
+:`main.log-file`:
+ fichier dans lequel écrire les messages
+
+
+Configuration Eproperties
+-------------------------
+D'autres paramètres de configuration sont sous la forme d'entités `EProperty`
+dans la base de données. Il faut donc les éditer via l'interface web ou par des
+requêtes rql.
+
+:`ui.encoding`:
+ encodage de caractères à utiliser pour l'interface web
+:`navigation.short-line-size`: # XXX should be in ui
+ nombre de caractères maximum pour les affichages "courts"
+:`navigation.page-size`:
+ nombre d'entités maximum à afficher par page de résultat
+:`navigation.related-limit`:
+ nombre d'entités liées maximum à afficher sur la vue primaire d'une entité
+:`navigation.combobox-limit`:
+ nombre d'entités non liées maximum à afficher sur les listes déroulantes de
+ la vue d'édition d'une entité
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/C040-rql.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,216 @@
+.. -*- coding: utf-8 -*-
+
+RQL language (Relation Query Language)
+======================================
+
+XXX see also RQL documentation in source rql/doc.
+
+
+Introduction
+------------
+* RQL language focuses on browsing relations.
+* Attributes are considered as particular relations.
+* RQL is inspired from SQL but is a high level language.
+* A good knowledge of Erudi's schemas defining the application is required.
+
+
+Types of requests
+-----------------
+
+Search (`Any`)
+ query the repository to extract entities and/or attributes.
+
+Insertion (`INSERT`)
+ insert new entities in the database.
+
+Updates of entities, creation of relations (`SET`)
+ update existing entities in the database, or create relations between existing
+ entities
+
+Deletion of entities or relations (`DELETE`)
+ delete existing entities and relations from the database.
+
+
+Variables and typing
+--------------------
+
+Entities and values to browse and/or select are set in the query through *variables*
+which should be written in capital letters.
+
+The possible types for each variable can be deducted from the schema depending on
+the conditions expressed in the query.
+
+You can force the possible types for a variable thanks to the special relation `is`.
+
+
+
+Built-in types
+--------------
+* `String` (literal: between double or single quotes).
+* `Int`, `Float` (separator is '.').
+* `Date`, `Datetime`, `Time` (literal: pattern YYYY/MM/DD[ hh:mm] or keywords
+ `TODAY` and `NOW`).
+* `Boolean` (keywords `TRUE` et `FALSE`).
+* keyword `NULL`.
+
+Operators
+----------
+* Logical operators: `AND`, `OR`, `,`.
+* Mathematical operators: `+`, `-`, `*`, `/`.
+* Comparison operators: `=`, `<`, `<=`, `>=`, `>`, `~=`, `LIKE`, `IN`.
+
+ * The operator `=` is the default operator.
+
+ * The operator `LIKE` / `~=` allows the use of the character `%` in a string
+ to indicate that the string should start/end with a prefix/suffix::
+
+ Any X WHERE X nom ~= 'Th%'
+ Any X WHERE X nom LIKE '%lt'
+
+ * The operator `IN` allows to provide a list of possible values::
+
+ Any X WHERE X nom IN ('chauvat', 'fayolle', 'di mascio', 'thenault')
+
+Search query
+------------
+
+ [`DISTINCT`] <entity type> V1(, V2)\*
+ [`GROUPBY` V1(, V2)\*] [`ORDERBY` <orderterms>]
+ [`WHERE` <condition>]
+ [`LIMIT` <value>] [`OFFSET` <value>]
+
+:entity type:
+ Type of the selected variable
+ Special type `Any` is equivalent to not specify a type
+:condition:
+ list of relations to browse following the pattern
+ `V1 relation V2|<static value>`
+:orderterms:
+ Setting of the selection order : variable or column number followed by the
+ sorting method (`ASC`, `DESC`), ASC being the default value.
+:note for grouped queries:
+ For grouped queries (e.g. using function `GROUPBY`), all the selected
+ variables must be grouped or aggregated.
+
+Examples - search
+~~~~~~~~~~~~~~~~~
+::
+
+ Any X WHERE X eid 53
+ Personne X
+ Personne X WHERE X travaille_pour S, S nom "logilab"
+ Any E,COUNT(X) GROUPBY E ORDERBY EN WHERE X is E, E name EN
+ Any E,COUNT(X) GROUPBY E ORDERBY 2 WHERE X is E
+
+
+Advanced features
+~~~~~~~~~~~~~~~~~
+* Aggregate functions: `COUNT`, `MIN`, `MAX`, `SUM`.
+* String functions:`UPPER`, `LOWER`.
+* Optional relations:
+
+ * They allow to select entities related to others or not.
+
+ * You should use `?` behind the variable to specify the relation to itself is
+ optional.
+
+ - Project anomalies related to a version or not::
+
+ Any X,V WHERE X concerns P, P eid 42, X corrected_in V?
+
+ - All the cards and the project they document otherwise ::
+
+ Any C,P WHERE C is Card, P? documented_by C
+
+Negation
+~~~~~~~~
+* A query such as `Document X WHERE NOT X owned_by U` is equivalent to
+ "the documents which do not have relation `owned_by`".
+* Whereas the query `Document X WHERE NOT X owned_by U, U login "syt"`
+ is equivalent to "the documents which do not have relation `owned_by`
+ with the user syt". They could have a relation with other users.
+
+
+Identity
+~~~~~~~~
+
+We could use the special relation `identity` in a query in order to add a
+condition of identity between two variables. This is equivalent to ``is``
+in Python.
+
+ Any A WHERE A comments B, A identity B
+
+returns the set of objects which comment themselves. The relation `identity`
+is very usefull while defining security rules with `RQLExpressions`.
+
+Insertion queries
+-----------------
+ `INSERT` <entity type> V1(, <entity type> V2)\* `:` <assignments>
+ [`WHERE` <condition>]
+
+:assignments:
+ list of relations to assign such as `V1 relation V2|<static value>`
+
+The condition allow to define the variables we would use in assignments.
+
+Be careful, if a condition is specified, the insertion is done *for each result
+returned by the condition*.
+
+Examples - insertion
+~~~~~~~~~~~~~~~~~~~~~
+* Insertion of a new person named 'bidule'::
+
+ INSERT Person X: X name 'bidule'
+
+* Insertion of a new person named 'bidule', another named
+ 'chouette' and a relation 'friend' between them::
+
+ INSERT Person X, Person Y: X name 'bidule', Y name 'chouette', X friend Y
+
+* Insertion of a new person named 'bidule' and a relation 'friend'with an
+ existing person 'chouette'::
+
+ INSERT Person X: X name 'bidule', X friend Y WHERE Y name 'chouette'
+
+
+Update queries
+--------------
+ `SET` <assignments>
+ [`WHERE` <condition>]
+
+Be careful, if a condition is specified, the update is done *for each result
+returned by the condition*.
+
+Examples - update
+~~~~~~~~~~~~~~~~~
+* Renaming of the person named 'bidule' to 'toto', with change on the first name::
+
+ SET X name 'toto', X firstname 'original' WHERE X is 'Person', X name 'bidule'
+
+* Insertion of a relation of type 'know' between two objects linked with the relation
+ of type 'friend' ::
+
+ SET X know Y WHERE X friend Y
+
+Deletion queries
+----------------
+ `DELETE` (<entity type> V) | (V1 relation v2),...
+ [`WHERE` <condition>]
+
+
+Be careful, if a condition is specified, the deletion is done *for each result
+returned by the condition*.
+
+
+Examples
+~~~~~~~~
+* Deletion of the person named 'toto'::
+
+ DELETE Person X WHERE X name 'toto'
+
+* Deletion of all the relations of type 'friend' linked to the person named
+ 'toto'::
+
+ DELETE X friend Y WHERE X is 'Person', X name 'toto'
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/D000-annex.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,18 @@
+.. -*- coding: utf-8 -*-
+
+
+=================
+Part IV - Annexes
+=================
+
+The following chapters are reference material.
+
+.. toctree::
+ :maxdepth: 1
+
+ D010-faq.en.txt
+ D020-api-reference.en.txt
+ D030-architecture.en.txt
+ D040-modules-stdlib.en.txt
+ D050-modules-cbw-api.en.txt
+ D060-mercurial.en.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/D010-faq.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,104 @@
+.. -*- coding: utf-8 -*-
+
+Frequently Asked Questions
+==========================
+
+* Why does not LAX have a template language ?
+
+ It does. Actually, you can use your preferred template language if you
+ want. [explain how to use a template language]
+
+ The reason template languages are not used in this book is that
+ experience has proved us that using pure python was more efficient.
+
+* Why do you think using pure python is better than using a template language ?
+
+ [copy answer from forum]
+
+ code is easier to maintain, does not have to learn a new dialect
+ each time, real function/classes etc -> real development
+
+* Why do you use the GPL license to prevent me from doing X ?
+
+ [copy answer from forum]
+
+* LAX looks pretty recent. Is it stable ?
+
+ [answer that framework has evolved over the past seven years and that
+ data migrated from one schema to the other ever since]
+
+* Why is the RQL query language looking similar to X ?
+
+ [copy answer from forum, explain why similar to sparql and why better
+ than django and SQL]
+
+* which ajax library
+
+ [we use mochikit and things on top of that]
+
+* `Error while publishing rest text ...`
+
+ While modifying the description of an entity, you get an error message in
+ the application `Error while publishing ...` for Rest text and plain text.
+ The server returns a traceback like as follows ::
+
+ 2008-10-06 15:05:08 - (erudi.rest) ERROR: error while publishing ReST text
+ Traceback (most recent call last):
+ File "/home/sandrine/src/blogdemo/ginco/common/rest.py", line 217, in rest_publish
+ File "/usr/lib/python2.5/codecs.py", line 817, in open
+ file = __builtin__.open(filename, mode, buffering)
+ TypeError: __init__() takes at most 3 arguments (4 given)
+
+
+ This can be fixed by applying the patch described in :
+ http://code.google.com/p/googleappengine/issues/detail?id=48
+
+* What are hooks used for?
+
+ Les crochets sont appeles lorsqu'une requete RQL est executee. Cela
+ permet d'executer des actions specifiques lors d'un acces a la base
+ de donnees, ce qui donne un controle de la base de donnees afin de
+ prevenir l'insertion de `mauvaises` entites dans la base.
+
+* When should you define an HTML template rather than define a graphical component?
+
+ Un template HTML ne peut contenir de logique, il ne permettra donc
+ que de definir une vue statique. Un composant permet lui de gerer
+ plus de logique et d'operations sur le contexte dans lequel il
+ s'applique. Il faut donc bien reflechir avant de decider de l'un ou
+ de l'autre, mais vous avez la possibilite de choisir.
+
+* How to update a database after a schema modification?
+
+ Cela dépend de ce qui a été modifié dans le schéma.
+
+ * Modification d'une relation non finale
+
+ * Modification d'une relation finale
+
+[TO COMPLETE]
+
+* How to create an anonymous user?
+
+ Cela vous permet d'acceder a votre site sans avoir besoin de vous authentifier.
+ Dans le fichier ``all-in-one.conf`` de votre instance, définir l'utilisateur
+ anonyme en initilisant les valeurs des variables suivantes ::
+
+ # login of the Erudi user account to use for anonymous user (if you want to
+ # allow anonymous)
+ anonymous-user=anon
+
+ # password of the Erudi user account matching login
+ anonymous-password=anon
+
+ Vous devez aussi vous assurer que cet utilisateur `anon` existe dans la base
+ de données, le plus simple étant de s'identifier sur votre application en
+ administrateur et de rajouter l'utilisateur `anon` via l'interface d'administration.
+
+* What is the difference between `AppRsetObject` and `AppObject` ?
+
+ La différence entre la classe `AppRsetObject` et la classe `AppObject` est que
+ les instances de la premières sont séléctionnées pour une requête et un "result
+ set" et alors que les secondes ne sont séléctionnées qu'en fonction de leur
+ identifiant.
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/D020-api-reference.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,33 @@
+.. -*- coding: utf-8 -*-
+
+API Reference
+=============
+
+Schema API
+----------
+
+Base Types
+~~~~~~~~~~
+
+Base types are defined as a set in yams.BASE_TYPES that includes:
+`String`, `Int`, `Float`, `Boolean`, `Date`, `Time`, `Datetime`,
+`Interval`, `Password`, `Bytes`.
+
+See `yams' API <http://lax.logilab.org/apidoc>`_
+
+Constraints
+~~~~~~~~~~~
+
+Constraints are defined in yams.constraints and include:
+`UniqueConstraint`, `SizeConstraint`, `RegexpConstraint`,
+`BoundConstraint`, `IntervalBoundConstraint`,
+`StaticVocabularyConstraint`, `MultipleStaticVocabularyConstraint`.
+
+See `yams' API <http://lax.logilab.org/apidoc>`_
+
+Views API
+---------
+
+See `yams' API <http://lax.logilab.org/apidoc>`_
+[WRITE ME]
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/D030-architecture.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,14 @@
+.. -*- coding: utf-8 -*-
+
+
+Architecture du serveur
+-----------------------
+
+.. image:: images/server-class-diagram.png
+
+`Diagramme ArgoUML`_
+
+[FIXME]
+Make a downloadable source of zargo file.
+
+.. _`Diagramme ArgoUML`: cubicweb.zargo
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/D040-modules-stdlib.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,158 @@
+.. -*- coding: utf-8 -*-
+
+================
+Standard library
+================
+
+:mod:`cubes.addressbook`
+========================
+
+.. automodule:: cubes.addressbook
+ :members:
+
+:mod:`cubes.basket`
+========================
+
+.. automodule:: cubes.basket
+ :members:
+
+:mod:`cubes.blog`
+========================
+
+.. automodule:: cubes.blog
+ :members:
+
+:mod:`cubes.book`
+========================
+
+.. automodule:: cubes.book
+ :members:
+
+:mod:`cubes.comment`
+========================
+
+.. automodule:: cubes.comment
+ :members:
+
+:mod:`cubes.company`
+========================
+
+.. automodule:: cubes.company
+ :members:
+
+
+:mod:`cubes.conference`
+========================
+
+.. automodule:: cubes.conference
+ :members:
+
+:mod:`cubes.email`
+========================
+
+.. automodule:: cubes.email
+ :members:
+
+:mod:`cubes.event`
+========================
+
+.. automodule:: cubes.event
+ :members:
+
+:mod:`cubes.expense`
+========================
+
+.. automodule:: cubes.expense
+ :members:
+
+
+:mod:`cubes.file`
+========================
+
+.. automodule:: cubes.file
+ :members:
+
+:mod:`cubes.folder`
+========================
+
+.. automodule:: cubes.folder
+ :members:
+
+:mod:`cubes.i18ncontent`
+========================
+
+.. automodule:: cubes.i18ncontent
+ :members:
+
+:mod:`cubes.invoice`
+========================
+
+.. automodule:: cubes.invoice
+ :members:
+
+:mod:`cubes.keyword`
+========================
+
+.. automodule:: cubes.keyword
+ :members:
+
+:mod:`cubes.link`
+========================
+
+.. automodule:: cubes.link
+ :members:
+
+:mod:`cubes.mailinglist`
+========================
+
+.. automodule:: cubes.mailinglist
+ :members:
+
+:mod:`cubes.person`
+========================
+
+.. automodule:: cubes.person
+ :members:
+
+:mod:`cubes.shopcart`
+========================
+
+.. automodule:: cubes.shopcart
+ :members:
+
+:mod:`cubes.skillmat`
+========================
+
+.. automodule:: cubes.skillmat
+ :members:
+
+:mod:`cubes.tag`
+========================
+
+.. automodule:: cubes.tag
+ :members:
+
+:mod:`cubes.task`
+========================
+
+.. automodule:: cubes.task
+ :members:
+
+:mod:`cubes.workcase`
+========================
+
+.. automodule:: cubes.workcase
+ :members:
+
+:mod:`cubes.workorder`
+========================
+
+.. automodule:: cubes.workorder
+ :members:
+
+:mod:`cubes.zone`
+========================
+
+.. automodule:: cubes.zone
+ :members:
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/D050-modules-cbw-api.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,104 @@
+.. -*- coding: utf-8 -*-
+
+============
+CubicWeb API
+============
+
+:mod:`cubicweb`
+===============
+
+.. automodule:: cubicweb
+ :members:
+
+:mod:`cubicweb.common`
+======================
+
+.. automodule:: cubicweb.common
+ :members:
+
+:mod:`cubicweb.devtools`
+========================
+
+.. automodule:: cubicweb.devtools
+ :members:
+
+:mod:`cubicweb.entities`
+========================
+
+.. automodule:: cubicweb.entities
+ :members:
+
+:mod:`cubicweb.etwist`
+======================
+
+.. automodule:: cubicweb.etwist
+ :members:
+
+:mod:`cubicweb.goa`
+===================
+
+.. automodule:: cubicweb.goa
+ :members:
+
+:mod:`cubicweb.schemas`
+=======================
+
+.. automodule:: cubicweb.schemas
+ :members:
+
+:mod:`cubicweb.server`
+======================
+
+.. automodule:: cubicweb.server
+ :members:
+
+:mod:`cubicweb.sobjects`
+========================
+
+.. automodule:: cubicweb.sobjects
+ :members:
+
+:mod:`cubicweb.web`
+===================
+
+.. automodule:: cubicweb.web
+ :members:
+
+:mod:`cubicweb.web.views`
+=========================
+
+.. automodule:: cubicweb.web.views
+ :members:
+
+
+:mod:`cubicweb.wsgi`
+====================
+
+.. automodule:: cubicweb.wsgi
+ :members:
+
+:mod:`indexer`
+==============
+
+.. automodule:: indexer
+ :members:
+
+:mod:`logilab`
+==============
+
+.. automodule:: logilab
+ :members:
+
+
+
+:mod:`rql`
+==========
+
+.. automodule:: rql
+ :members:
+
+:mod:`yams`
+===========
+
+.. automodule:: yams
+ :members:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/D060-mercurial.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,116 @@
+.. -*- coding: utf-8 -*-
+
+.. _MercurialPresentation:
+
+Présentation de Mercurial
+=========================
+
+Introduction
+````````````
+Mercurial_ gère un ensemble distribué d'entrepôts contenant des arbres de
+révisions (chaque révision indique les changements à effectuer pour obtenir la
+version suivante, et ainsi de suite). Localement, on dispose d'un entrepôt
+contenant un arbre de révisions, et d'un répertoire de travail. Il est possible
+de mettre dans son répertoire de travail, une des versions issue de son entrepôt
+local, de la modifier puis de la verser dans son entrepôt. Il est également
+possible de récuprer dans son entrepôt local des révisions venant d'un autre
+entrepôt, ou d'exporter ses propres révisions depuis son entrepôt local vers un
+autre entrepôt.
+
+A noter que contrairement à CVS/Subversion, on crée généralement un entrepôt par
+projet à gérer.
+
+Lors d'un développement collaboratif, on crée généralement un entrepôt central
+accessible à tout les développeurs du projet. Ces entrepôts centraux servent de
+référence. Selon ses besoins, chacun peut ensuite disposer d'un entrepôt local,
+qu'il faudra penser à synchroniser avec l'entrepôt central de temps à autre.
+
+
+Principales commandes
+`````````````````````
+* Créer un entrepôt local ::
+
+ hg clone ssh://orion//home/src/prive/rep
+
+* Voir le contenu de l'entrepôt local (outil graphique en Tk) ::
+
+ hg view
+
+* Ajouter un sous-répertoire ou un fichier dans le répertoire courant ::
+
+ hg add rep
+
+* Placer dans son répertoire de travail une révision spécifique (ou la dernière
+ revision) issue de l'entrepôt local ::
+
+ hg update [identifiant-revision]
+ hg up [identifiant-revision]
+
+* Récupérer dans son entrepôt local, l'arbre de révisions contenu dans un
+ entrepôt distant (cette opération ne modifie pas le répertoire local) ::
+
+ hg pull ssh://orion//home/src/prive/rep
+ hg pull -u ssh://orion//home/src/prive/rep # équivalent à pull + update
+
+* Voir quelles sont les têtes de branches de l'entrepôt local si un `pull` a
+ tiré une nouvelle branche ::
+
+ hg heads
+
+* Verser le répertoire de travail dans l'entrepôt local (et créer une nouvelle
+ révision) ::
+
+ hg commit
+ hg ci
+
+* Fusionner, avec la révision mère du répertoire local, une autre révision issue
+ de l'entrepôt local (la nouvelle révision qui en résultera aura alors deux
+ révisions mères) ::
+
+ hg merge identifiant-revision
+
+* Exporter dans un entrepôt distant, l'arbre de révisions contenu dans son
+ entrepôt local (cette opération ne modifie pas le répertoire local) ::
+
+ hg push ssh://orion//home/src/prive/rep
+
+* Voir quelle sont les révisions locales non présentes dans un autre entrepôt ::
+
+ hg outgoing ssh://orion//home/src/prive/rep
+
+* Voir quelle sont les révisions d'un autre entrepôt non présentes localement ::
+
+ hg incoming ssh://orion//home/src/prive/rep
+
+* Voir quelle est la révision issue de l'entrepôt local qui a été sortie dans le
+ répertoire de travail et modifiée ::
+
+ hg parent
+
+* Voir les différences entre le répertoire de travail et la révision mère de
+ l'entrepôt local, éventuellement permettant de les verser dans l'entrepôt
+ local ::
+
+ hg diff
+ hg commit-tool
+ hg ct
+
+
+Bonnes pratiques
+````````````````
+* penser à faire un `hg pull -u` régulièrement et particulièrement avant de
+ faire un `hg commit`
+
+* penser à faire un `hg push` lorsque votre entrepôt contient une version
+ relativement stable de vos modifications
+
+* si un `hg pull -u` a créé une nouvelle tête de branche :
+
+ 1. identifier l'identifiant de celle-ci avec `hg head`
+ 2. fusionner avec `hg merge`
+ 3. `hg ci`
+ 4. `hg push`
+
+.. _Mercurial: http://www.selenic.com/mercurial/
+
+.. include:: D061-mercurial-forest.en.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/D061-mercurial-forest.en.txt Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,52 @@
+.. -*- coding: utf-8 -*-
+
+.. _MercurialForestInstall:
+
+Installation of `CubicWeb` with Mercurial
+=========================================
+
+`CubicWeb` is available as a Mercurial repository using the forest extension.
+First make sure Mercurial is installed and that the forest extension is
+available.
+
+Mercurial installation
+``````````````````````
+
+Please refer to the project online documentation Mercurial_.
+
+.. _Mercurial: http://www.selenic.com/mercurial/wiki/
+
+We also provide in this book a quick guide on how to use
+Mercurial (:ref:`MercurialPresentation`).
+
+
+Installation of the forest extension
+````````````````````````````````````
+
+Set up the forest extension by getting a copy of the sources
+from http://hg.akoha.org/hgforest/ and adding the following
+lines to your ``~/.hgrc``: ::
+
+ [extensions]
+ hgext.forest=
+ # or, if forest.py is not in the hgext dir:
+ # forest=/path/to/forest.py
+
+Get `CubicWeb` source code
+``````````````````````````
+
+Clone the forest in you working directory.
+
+::
+
+ hg fclone http://www.logilab.org/hg/forests/cubicweb
+
+.. note::
+ We recommand you to create a symbolic link to the command ``cubicweb-ctl``
+ as you will use it pretty often.
+
+ ::
+
+ $ ln -s /path/to/forest/cubicweb/bin/cubicweb-ctl ~/bin
+
+
--- a/doc/book/en/XX-XX-actions.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /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
-
--- a/doc/book/en/XX-XX-boxes.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /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
-
--- a/doc/book/en/XX-XX-dbapi.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /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
-
--- a/doc/book/en/XX-XX-embedding-external-page.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /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
-
--- a/doc/book/en/XX-XX-repository-operations.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Repository operations
-======================
-
-[WRITE ME]
-
-* repository operations
-
--- a/doc/book/en/XX-XX-repository-session.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Repository sessions
-===================
-
-[WRITE ME]
-
-* repository sessions
-
--- a/doc/book/en/XX-XX-repository-tasks.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Tasks
-=========
-
-[WRITE ME]
-
-* repository tasks
-
--- a/doc/book/en/XX-XX-request.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-request
-=======
-
-[WRITE ME]
-
-* the request object
-
--- a/doc/book/en/XX-XX-sessions.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /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
-
--- a/doc/book/en/XX-XX-templates.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Templates
-=========
-
-[WRITE ME]
-
-* talk about main templates, etc.
-
--- a/doc/book/en/XX-XX-urlrewrite.en.txt Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-URL Rewriting
-=============
-
-XXX FIXME this should be a chapter
-
-[WRITE ME]
-
-* show how urls are mapped to selections and views and explain URLRewriting
-
--- a/doc/book/en/index.txt Tue Nov 25 17:44:54 2008 +0100
+++ b/doc/book/en/index.txt Tue Nov 25 17:45:11 2008 +0100
@@ -38,40 +38,10 @@
.. toctree::
:maxdepth: 2
- 01-08-book-map.en.txt
- 01-00-introduction.en.txt
- 02-00-foundation.en.txt
- 03-00-setup.en.txt
- 04-00-define-schema.en.txt
- 05-00-define-views.en.txt
- 06-00-define-workflows.en.txt
- 07-00-data-as-objects.en.txt
- 08-00-site-config.en.txt
- 09-00-instance-config.en.txt
- 10-00-form-management.en.txt
- 11-00-ajax-json.en.txt
- 12-00-ui-components.en.txt
- 14-00-hooks.en.txt
- 15-00-notifications.en.txt
- 16-00-rql.en.txt
- 17-00-migration.en.txt
- 18-00-tests.en.txt
- 19-00-i18n.en.txt
- 20-00-google-appengine.en.txt
- 21-00-appendix.en.txt
- 22-00-faq.en.txt
- XX-XX-actions.en.txt
- XX-XX-repository-operations.en.txt
- XX-XX-sessions.en.txt
- XX-XX-boxes.en.txt
- XX-XX-repository-session.en.txt
- XX-XX-templates.en.txt
- XX-XX-dbapi.en.txt
- XX-XX-repository-tasks.en.txt
- XX-XX-urlrewrite.en.txt
- XX-XX-embedding-external-page.en.txt
- XX-XX-request.en.txt
-
+ A000-introduction.en.txt
+ B000-development.en.txt
+ C000-administration.en.txt
+ D000-annex.en.txt
Indices and tables
==================
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/mode_plan.py Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,33 @@
+"""
+>>> from mode_plan import *
+>>> ls()
+<list of directory content>
+>>> ren('A01','A03')
+rename A010-joe.en.txt to A030-joe.en.txt
+accept [y/N]?
+"""
+
+def ren(a,b):
+ names = glob.glob('%s*'%a)
+ for name in names :
+ print 'rename %s to %s' % (name, name.replace(a,b))
+ if raw_input('accept [y/N]?').lower() =='y':
+ for name in names:
+ os.system('hg mv %s %s' % (name, name.replace(a,b)))
+
+
+def ls(): print '\n'.join(sorted(os.listdir('.')))
+
+def move():
+ filenames = []
+ for name in sorted(os.listdir('.')):
+ num = name[:2]
+ if num.isdigit():
+ filenames.append( (int(num), name) )
+
+
+ #print filenames
+
+ for num, name in filenames:
+ if num >= start:
+ print 'hg mv %s %2i%s' %(name,num+1,name[2:])
--- a/etwist/twconfig.py Tue Nov 25 17:44:54 2008 +0100
+++ b/etwist/twconfig.py Tue Nov 25 17:45:11 2008 +0100
@@ -46,7 +46,7 @@
'default': None,
'help': 'if this option is set, use the specified user to start \
the repository rather than the user running the command',
- 'group': 'main', 'inputlevel': 0,
+ 'group': 'main', 'inputlevel': (WebConfiguration.mode == 'installed') and 0 or 1,
}),
('session-time',
{'type' : 'int',
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/migration/2.99.0_Any.py Tue Nov 25 17:45:11 2008 +0100
@@ -0,0 +1,11 @@
+from cubicweb import CW_MIGRATION_MAP
+
+for pk, in rql('Any K WHERE X is EProperty, X pkey IN (%s), X pkey K'
+ % ','.join("'system.version.%s'" % cube for cube in CW_MIGRATION_MAP)):
+ cube = pk.split('.')[-1]
+ newk = pk.replace(cube, CW_MIGRATION_MAP[cube])
+ rql('SET X pkey %(newk)s WHERE X pkey %(oldk)s',
+ {'oldk': pk, 'newk': newk})
+ print 'renamed', pk, 'to', newk
+
+add_entity_type('ECache')
--- a/misc/migration/3.0.0_Any.py Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-from cubicweb import CW_MIGRATION_MAP
-
-for pk, in rql('Any K WHERE X is EProperty, X pkey IN (%s), X pkey K'
- % ','.join("'system.version.%s'" % cube for cube in CW_MIGRATION_MAP)):
- cube = pk.split('.')[-1]
- newk = pk.replace(cube, CW_MIGRATION_MAP[cube])
- rql('SET X pkey %(newk)s WHERE X pkey %(oldk)s',
- {'oldk': pk, 'newk': newk})
- print 'renamed', pk, 'to', newk
-
-add_entity_type('ECache')
--- a/server/serverconfig.py Tue Nov 25 17:44:54 2008 +0100
+++ b/server/serverconfig.py Tue Nov 25 17:45:11 2008 +0100
@@ -52,7 +52,7 @@
'default': None,
'help': 'if this option is set, use the specified user to start \
the repository rather than the user running the command',
- 'group': 'main', 'inputlevel': 0,
+ 'group': 'main', 'inputlevel': (CubicWebConfiguration.mode == 'installed') and 0 or 1,
}),
('session-time',
{'type' : 'int',
--- a/server/serverctl.py Tue Nov 25 17:44:54 2008 +0100
+++ b/server/serverctl.py Tue Nov 25 17:45:11 2008 +0100
@@ -18,7 +18,7 @@
# utility functions ###########################################################
-def source_cnx(source, dbname=None, special_privs=False):
+def source_cnx(source, dbname=None, special_privs=False, verbose=True):
"""open and return a connection to the system database defined in the
given server.serverconfig
"""
@@ -29,7 +29,7 @@
dbname = source['db-name']
driver = source['db-driver']
print '**** connecting to %s database %s@%s' % (driver, dbname, dbhost),
- if not special_privs and source.get('db-user'):
+ if not verbose or (not special_privs and source.get('db-user')):
user = source['db-user']
print 'as', user
if source.get('db-password'):
@@ -53,7 +53,8 @@
return get_connection(driver, dbhost, dbname, user, password=password,
port=source.get('db-port'))
-def system_source_cnx(source, dbms_system_base=False, special_privs=None):
+def system_source_cnx(source, dbms_system_base=False,
+ special_privs='CREATE/DROP DATABASE', verbose=True):
"""shortcut to get a connextion to the application system database
defined in the given config. If <dbms_system_base> is True,
connect to the dbms system database instead (for task such as
@@ -62,11 +63,10 @@
if dbms_system_base:
from logilab.common.adbh import get_adv_func_helper
system_db = get_adv_func_helper(source['db-driver']).system_database()
- special_privs = special_privs or 'CREATE/DROP DATABASE'
- return source_cnx(source, system_db, special_privs=special_privs)
- return source_cnx(source, special_privs=special_privs)
+ return source_cnx(source, system_db, special_privs=special_privs, verbose=verbose)
+ return source_cnx(source, special_privs=special_privs, verbose=verbose)
-def _db_sys_cnx(source, what, db=None, user=None):
+def _db_sys_cnx(source, what, db=None, user=None, verbose=True):
"""return a connection on the RDMS system table (to create/drop a user
or a database
"""
@@ -79,7 +79,7 @@
if db is not None:
special_privs += ' %s DATABASE' % what
# connect on the dbms system base to create our base
- cnx = system_source_cnx(source, True, special_privs=special_privs)
+ cnx = system_source_cnx(source, True, special_privs=special_privs, verbose=verbose)
# disable autocommit (isolation_level(1)) because DROP and
# CREATE DATABASE can't be executed in a transaction
try:
@@ -189,7 +189,8 @@
def postcreate(self):
if confirm('do you want to create repository\'s system database?'):
- cmd_run('db-create', self.config.appid)
+ verbosity = (self.config.mode == 'installed') and 'y' or 'n'
+ cmd_run('db-create', self.config.appid, '--verbose=%s' % verbosity)
else:
print 'nevermind, you can do it later using the db-create command'
@@ -280,11 +281,18 @@
{'short': 'c', 'type': "yn", 'metavar': '<y or n>',
'default': True,
'help': 'create the database (yes by default)'}),
+ ("verbose",
+ {'short': 'v', 'type' : 'yn', 'metavar': '<verbose>',
+ 'default': 'n',
+ 'help': 'verbose mode: will ask all possible configuration questions',
+ }
+ ),
)
def run(self, args):
"""run the command with its specific arguments"""
from logilab.common.adbh import get_adv_func_helper
from indexer import get_indexer
+ verbose = self.get('verbose')
appid = pop_arg(args, msg="No application specified !")
config = ServerConfiguration.config_for(appid)
create_db = self.config.create_db
@@ -293,7 +301,7 @@
helper = get_adv_func_helper(driver)
if create_db:
# connect on the dbms system base to create our base
- dbcnx = _db_sys_cnx(source, 'CREATE DATABASE and / or USER')
+ dbcnx = _db_sys_cnx(source, 'CREATE DATABASE and / or USER', verbose=verbose)
cursor = dbcnx.cursor()
try:
if helper.users_support:
@@ -319,7 +327,7 @@
except:
dbcnx.rollback()
raise
- cnx = system_source_cnx(source, special_privs='LANGUAGE C')
+ cnx = system_source_cnx(source, special_privs='LANGUAGE C', verbose=verbose)
cursor = cnx.cursor()
indexer = get_indexer(driver)
indexer.init_extensions(cursor)
--- a/skeleton/__pkginfo__.py.tmpl Tue Nov 25 17:44:54 2008 +0100
+++ b/skeleton/__pkginfo__.py.tmpl Tue Nov 25 17:45:11 2008 +0100
@@ -19,10 +19,7 @@
from os import listdir as _listdir
from os.path import join, isdir
-from glob import glob
-scripts = glob(join('bin', '%(cubename)s-*'))
-
-web, ftp = '', ''
+web = ''
pyversions = ['2.4']
@@ -40,17 +37,9 @@
data_files = [
# common files
[THIS_CUBE_DIR, [fname for fname in glob('*.py') if fname != 'setup.py']],
-
- # client (web) files
- [join(THIS_CUBE_DIR, 'data'), listdir('data')],
- [join(THIS_CUBE_DIR, 'i18n'), listdir('i18n')],
-
- # server files
- [join(THIS_CUBE_DIR, 'migration'), listdir('migration')],
- ]
-
+ ]
# check for possible extended cube layout
- for dirname in ('entities', 'views', 'sobjects', 'schema'):
+ for dirname in ('entities', 'views', 'sobjects', 'schema', 'data', 'i18n', 'migration'):
if isdir(dirname):
data_files.append([join(THIS_CUBE_DIR, dirname), listdir(dirname)])
# Note: here, you'll need to add subdirectories if you want
@@ -62,4 +51,5 @@
cube_eid = None # <=== FIXME if you need direct bug-subscription
__use__ = (%(dependancies)s)
+__recommend__ = ()
--- a/skeleton/data/cubes.CUBENAME.css Tue Nov 25 17:44:54 2008 +0100
+++ b/skeleton/data/cubes.CUBENAME.css Tue Nov 25 17:45:11 2008 +0100
@@ -1,3 +1,1 @@
-@import url("cubicweb.css");
-
/* template specific CSS */
--- a/skeleton/setup.py Tue Nov 25 17:44:54 2008 +0100
+++ b/skeleton/setup.py Tue Nov 25 17:45:11 2008 +0100
@@ -52,7 +52,7 @@
"""setup entry point"""
return setup(name=distname,
version=version,
- license =license,
+ license=license,
description=short_desc,
long_description=long_desc,
author=author,
--- a/skeleton/site_cubicweb.py Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-"""this is where you could register procedures for instance"""
-
--- a/skeleton/sobjects.py Tue Nov 25 17:44:54 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-"""this contains the server-side objects"""
-
--- a/web/data/cubicweb.css Tue Nov 25 17:44:54 2008 +0100
+++ b/web/data/cubicweb.css Tue Nov 25 17:45:11 2008 +0100
@@ -155,6 +155,10 @@
border: 1px solid #ccc;
}
+input:focus {
+ border: 1px inset #ff7700;
+}
+
fieldset {
border: none;
}
@@ -401,7 +405,6 @@
}
input#rql{
- border: 1px solid #ccc;
width: 80%;
margin-left: 12px;
}
@@ -923,14 +926,17 @@
text-align: left;
}
-table.filter td {
+table.filter div.facet {
padding: 0.6em 0.2em;
+ margin: 0em 1em;
+ border: 1px solid #ccc;
}
-table.filter td select {
- padding:1px 2px;
+table.filter div.facetTitle {
+ font-weight: bold;
}
+
div#tableActionsBox {
direction:rtl;
float:right
--- a/web/views/baseviews.py Tue Nov 25 17:44:54 2008 +0100
+++ b/web/views/baseviews.py Tue Nov 25 17:45:11 2008 +0100
@@ -378,6 +378,7 @@
self.w(cut(entity.dc_title(),
self.req.property_value('navigation.short-line-size')))
+
class MetaDataView(EntityView):
"""paragraph view of some metadata"""
id = 'metadata'
@@ -400,19 +401,8 @@
self.w(u'<span class="value">%s</span>'
% self.format_date(entity.creation_date))
if entity.creator:
- creatoreid = entity.creator.eid
self.w(u' <span>%s</span> ' % _('by'))
self.w(u'<span class="value">%s</span>' % entity.creator.name())
- else:
- creatoreid = None
- try:
- owners = ','.join(u.name() for u in entity.owned_by
- if u.eid != creatoreid)
- if owners:
- self.w(u', <span>%s</span> ' % _('owned by'))
- self.w(u'<span class="value">%s</span>' % owners)
- except Unauthorized:
- pass
self.w(u'</div>')