# HG changeset patch # User Sylvain Thénault # Date 1287007807 -7200 # Node ID 2b3fa6fb647bd6b032d759ca9d5fe67827216116 # Parent c243c0f65f17aa7e3652dfbf9a6e01b6d8ba9cc5 [doc] kill deprecated french documentation diff -r c243c0f65f17 -r 2b3fa6fb647b doc/book/en/makefile --- a/doc/book/en/makefile Thu Oct 14 00:01:04 2010 +0200 +++ b/doc/book/en/makefile Thu Oct 14 00:10:07 2010 +0200 @@ -28,7 +28,6 @@ help: @echo "Please use \`make ' where is one of" @echo " all to make standalone HTML files, developer manual and API doc" - @echo " apidoc to make API doc" @echo " html to make standalone HTML files" @echo "--- " @echo " pickle to make pickle files (usable by e.g. sphinx-web)" @@ -38,21 +37,15 @@ @echo " linkcheck to check all external links for integrity" clean: - rm -rf apidoc/ rm -f *.html -rm -rf ${BUILDDIR}/* -rm -rf ${BUILDJS} -all: ${TARGET} apidoc html +all: ${TARGET} html %.html: %.txt ${MKHTML} ${MKHTMLOPTS} $< -#apydoc: -# epydoc --html -o epydoc/ -n ../server/*.py ../core/*.py ../common/*.py ../server/*/*.py ../modpython/*/*.py ../common/*/*.py -apidoc: - epydoc --html -o apidoc -n "cubicweb" --exclude=setup --exclude=__pkginfo__ ../../../ - # run sphinx ### html: js mkdir -p ${BUILDDIR}/html ${BUILDDIR}/doctrees diff -r c243c0f65f17 -r 2b3fa6fb647b doc/book/fr/.static/cubicweb.png Binary file doc/book/fr/.static/cubicweb.png has changed diff -r c243c0f65f17 -r 2b3fa6fb647b doc/book/fr/.static/logilab.png Binary file doc/book/fr/.static/logilab.png has changed diff -r c243c0f65f17 -r 2b3fa6fb647b doc/book/fr/.static/sphinx-default.css --- a/doc/book/fr/.static/sphinx-default.css Thu Oct 14 00:01:04 2010 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,860 +0,0 @@ -/** - * Sphinx Doc Design - */ - -html, body { - background: white; -} - -body { - font-family: Verdana, sans-serif; - font-size: 100%; - background-color: white; - color: black; - margin: 0; - padding: 0; -} - -/* :::: LAYOUT :::: */ - -div.logilablogo { - padding: 10px 10px 10px 10px; - height:75; -} - - -div.document { - background-color: white; -} - -div.documentwrapper { - float: left; - width: 100%; -} - -div.bodywrapper { - margin: 0 0 0 230px; -} - -div.body { - background-color: white; - padding: 0 20px 30px 20px; - border-left:solid; - border-left-color:#e2e2e2; - border-left-width:thin; -} - -div.sphinxsidebarwrapper { - padding: 10px 5px 0 10px; -} - -div.sphinxsidebar { - float: left; - width: 230px; - margin-left: -100%; - font-size: 90%; -} - -div.clearer { - clear: both; -} - -div.footer { - color: #ff4500; - width: 100%; - padding: 9px 0 9px 0; - text-align: center; - font-size: 75%; -} - -div.footer a { - color: #ff4500; - text-decoration: underline; -} - -div.related { - background-color: #ff7700; - color: white; - width: 100%; - height: 30px; - line-height: 30px; - font-size: 90%; -} - -div.related h3 { - display: none; -} - -div.related ul { - margin: 0; - padding: 0 0 0 10px; - list-style: none; -} - -div.related li { - display: inline; -} - -div.related li.right { - float: right; - margin-right: 5px; -} - -div.related a { - color: white; - font-weight:bold; -} - -/* ::: TOC :::: */ - -div.sphinxsidebar { - border-style:solid; - border-color: white; -/* background-color:#e2e2e2;*/ - padding-bottom:5px; -} - -div.sphinxsidebar h3 { - font-family: 'Verdanda', sans-serif; - color: black; - font-size: 1.2em; - font-weight: normal; - margin: 0; - padding: 0; - font-weight:bold; - font-style:italic; -} - -div.sphinxsidebar h4 { - font-family: 'Verdana', sans-serif; - color: black; - font-size: 1.1em; - font-weight: normal; - margin: 5px 0 0 0; - padding: 0; - font-weight:bold; - font-style:italic; -} - -div.sphinxsidebar p { - color: black; -} - -div.sphinxsidebar p.topless { - margin: 5px 10px 10px 10px; -} - -div.sphinxsidebar ul { - margin: 10px; - padding: 0; - list-style: none; - color: black; -} - -div.sphinxsidebar ul ul, -div.sphinxsidebar ul.want-points { - margin-left: 20px; - list-style: square; -} - -div.sphinxsidebar ul ul { - margin-top: 0; - margin-bottom: 0; -} - -div.sphinxsidebar a { - color: black; -} - -div.sphinxsidebar form { - margin-top: 10px; -} - -div.sphinxsidebar input { - border: 1px solid #e2e2e2; - font-family: sans-serif; - font-size: 1em; - padding-bottom: 5px; -} - -/* :::: MODULE CLOUD :::: */ -div.modulecloud { - margin: -5px 10px 5px 10px; - padding: 10px; - line-height: 160%; - border: 1px solid #cbe7e5; - background-color: #f2fbfd; -} - -div.modulecloud a { - padding: 0 5px 0 5px; -} - -/* :::: SEARCH :::: */ -ul.search { - margin: 10px 0 0 20px; - padding: 0; -} - -ul.search li { - padding: 5px 0 5px 20px; - background-image: url(file.png); - background-repeat: no-repeat; - background-position: 0 7px; -} - -ul.search li a { - font-weight: bold; -} - -ul.search li div.context { - color: #888; - margin: 2px 0 0 30px; - text-align: left; -} - -ul.keywordmatches li.goodmatch a { - font-weight: bold; -} - -/* :::: COMMON FORM STYLES :::: */ - -div.actions { - padding: 5px 10px 5px 10px; - border-top: 1px solid #cbe7e5; - border-bottom: 1px solid #cbe7e5; - background-color: #e0f6f4; -} - -form dl { - color: #333; -} - -form dt { - clear: both; - float: left; - min-width: 110px; - margin-right: 10px; - padding-top: 2px; -} - -input#homepage { - display: none; -} - -div.error { - margin: 5px 20px 0 0; - padding: 5px; - border: 1px solid #d00; - font-weight: bold; -} - -/* :::: INLINE COMMENTS :::: */ - -div.inlinecomments { - position: absolute; - right: 20px; -} - -div.inlinecomments a.bubble { - display: block; - float: right; - background-image: url(style/comment.png); - background-repeat: no-repeat; - width: 25px; - height: 25px; - text-align: center; - padding-top: 3px; - font-size: 0.9em; - line-height: 14px; - font-weight: bold; - color: black; -} - -div.inlinecomments a.bubble span { - display: none; -} - -div.inlinecomments a.emptybubble { - background-image: url(style/nocomment.png); -} - -div.inlinecomments a.bubble:hover { - background-image: url(style/hovercomment.png); - text-decoration: none; - color: #3ca0a4; -} - -div.inlinecomments div.comments { - float: right; - margin: 25px 5px 0 0; - max-width: 50em; - min-width: 30em; - border: 1px solid #2eabb0; - background-color: #f2fbfd; - z-index: 150; -} - -div#comments { - border: 1px solid #2eabb0; - margin-top: 20px; -} - -div#comments div.nocomments { - padding: 10px; - font-weight: bold; -} - -div.inlinecomments div.comments h3, -div#comments h3 { - margin: 0; - padding: 0; - background-color: #2eabb0; - color: white; - border: none; - padding: 3px; -} - -div.inlinecomments div.comments div.actions { - padding: 4px; - margin: 0; - border-top: none; -} - -div#comments div.comment { - margin: 10px; - border: 1px solid #2eabb0; -} - -div.inlinecomments div.comment h4, -div.commentwindow div.comment h4, -div#comments div.comment h4 { - margin: 10px 0 0 0; - background-color: #2eabb0; - color: white; - border: none; - padding: 1px 4px 1px 4px; -} - -div#comments div.comment h4 { - margin: 0; -} - -div#comments div.comment h4 a { - color: #d5f4f4; -} - -div.inlinecomments div.comment div.text, -div.commentwindow div.comment div.text, -div#comments div.comment div.text { - margin: -5px 0 -5px 0; - padding: 0 10px 0 10px; -} - -div.inlinecomments div.comment div.meta, -div.commentwindow div.comment div.meta, -div#comments div.comment div.meta { - text-align: right; - padding: 2px 10px 2px 0; - font-size: 95%; - color: #538893; - border-top: 1px solid #cbe7e5; - background-color: #e0f6f4; -} - -div.commentwindow { - position: absolute; - width: 500px; - border: 1px solid #cbe7e5; - background-color: #f2fbfd; - display: none; - z-index: 130; -} - -div.commentwindow h3 { - margin: 0; - background-color: #2eabb0; - color: white; - border: none; - padding: 5px; - font-size: 1.5em; - cursor: pointer; -} - -div.commentwindow div.actions { - margin: 10px -10px 0 -10px; - padding: 4px 10px 4px 10px; - color: #538893; -} - -div.commentwindow div.actions input { - border: 1px solid #2eabb0; - background-color: white; - color: #135355; - cursor: pointer; -} - -div.commentwindow div.form { - padding: 0 10px 0 10px; -} - -div.commentwindow div.form input, -div.commentwindow div.form textarea { - border: 1px solid #3c9ea2; - background-color: white; - color: black; -} - -div.commentwindow div.error { - margin: 10px 5px 10px 5px; - background-color: #fbe5dc; - display: none; -} - -div.commentwindow div.form textarea { - width: 99%; -} - -div.commentwindow div.preview { - margin: 10px 0 10px 0; - background-color: #70d0d4; - padding: 0 1px 1px 25px; -} - -div.commentwindow div.preview h4 { - margin: 0 0 -5px -20px; - padding: 4px 0 0 4px; - color: white; - font-size: 1.3em; -} - -div.commentwindow div.preview div.comment { - background-color: #f2fbfd; -} - -div.commentwindow div.preview div.comment h4 { - margin: 10px 0 0 0!important; - padding: 1px 4px 1px 4px!important; - font-size: 1.2em; -} - -/* :::: SUGGEST CHANGES :::: */ -div#suggest-changes-box input, div#suggest-changes-box textarea { - border: 1px solid #ccc; - background-color: white; - color: black; -} - -div#suggest-changes-box textarea { - width: 99%; - height: 400px; -} - - -/* :::: PREVIEW :::: */ -div.preview { - background-image: url(style/preview.png); - padding: 0 20px 20px 20px; - margin-bottom: 30px; -} - - -/* :::: INDEX PAGE :::: */ - -table.contentstable { - width: 90%; -} - -table.contentstable p.biglink { - line-height: 150%; -} - -a.biglink { - font-size: 1.3em; -} - -span.linkdescr { - font-style: italic; - padding-top: 5px; - font-size: 90%; -} - -/* :::: INDEX STYLES :::: */ - -table.indextable td { - text-align: left; - vertical-align: top; -} - -table.indextable dl, table.indextable dd { - margin-top: 0; - margin-bottom: 0; -} - -table.indextable tr.pcap { - height: 10px; -} - -table.indextable tr.cap { - margin-top: 10px; - background-color: #f2f2f2; -} - -img.toggler { - margin-right: 3px; - margin-top: 3px; - cursor: pointer; -} - -form.pfform { - margin: 10px 0 20px 0; -} - -/* :::: GLOBAL STYLES :::: */ - -.docwarning { - background-color: #ffe4e4; - padding: 10px; - margin: 0 -20px 0 -20px; - border-bottom: 1px solid #f66; -} - -p.subhead { - font-weight: bold; - margin-top: 20px; -} - -a { - color: black; - text-decoration: none; -} - -a:hover { - text-decoration: underline; -} - -div.body h1, -div.body h2, -div.body h3, -div.body h4, -div.body h5, -div.body h6 { - font-family: 'Verdana', sans-serif; - background-color: white; - font-weight: bold; - color: black; - border-bottom: 1px solid #ccc; - margin: 20px -20px 10px -20px; - padding: 3px 0 3px 10px; -} - -div.body h1 { margin-top: 0; font-size: 150%; } -div.body h2 { font-size: 120%; } -div.body h3 { font-size: 100%; } -div.body h4 { font-size: 80%; } -div.body h5 { font-size: 600%; } -div.body h6 { font-size: 40%; } - -a.headerlink { - color: #c60f0f; - font-size: 0.8em; - padding: 0 4px 0 4px; - text-decoration: none; - visibility: hidden; -} - -h1:hover > a.headerlink, -h2:hover > a.headerlink, -h3:hover > a.headerlink, -h4:hover > a.headerlink, -h5:hover > a.headerlink, -h6:hover > a.headerlink, -dt:hover > a.headerlink { - visibility: visible; -} - -a.headerlink:hover { - background-color: #c60f0f; - color: white; -} - -div.body p, div.body dd, div.body li { - text-align: justify; - line-height: 130%; -} - -div.body p.caption { - text-align: inherit; -} - -div.body td { - text-align: left; -} - -ul.fakelist { - list-style: none; - margin: 10px 0 10px 20px; - padding: 0; -} - -.field-list ul { - padding-left: 1em; -} - -.first { - margin-top: 0 !important; -} - -/* "Footnotes" heading */ -p.rubric { - margin-top: 30px; - font-weight: bold; -} - -/* "Topics" */ - -div.topic { - background-color: #eee; - border: 1px solid #ccc; - padding: 0 7px 0 7px; - margin: 10px 0 10px 0; -} - -p.topic-title { - font-size: 1.1em; - font-weight: bold; - margin-top: 10px; -} - -/* Admonitions */ - -div.admonition { - margin-top: 10px; - margin-bottom: 10px; - padding: 7px; -} - -div.admonition dt { - font-weight: bold; -} - -div.admonition dl { - margin-bottom: 0; -} - -div.admonition p { - display: inline; -} - -div.seealso { - background-color: #ffc; - border: 1px solid #ff6; -} - -div.warning { - background-color: #ffe4e4; - border: 1px solid #f66; -} - -div.note { - background-color: #eee; - border: 1px solid #ccc; -} - -p.admonition-title { - margin: 0px 10px 5px 0px; - font-weight: bold; - display: inline; -} - -p.admonition-title:after { - content: ":"; -} - -div.body p.centered { - text-align: center; - margin-top: 25px; -} - -table.docutils { - border: 0; -} - -table.docutils td, table.docutils th { - padding: 1px 8px 1px 0; - border-top: 0; - border-left: 0; - border-right: 0; - border-bottom: 1px solid #aaa; -} - -table.field-list td, table.field-list th { - border: 0 !important; -} - -table.footnote td, table.footnote th { - border: 0 !important; -} - -.field-list ul { - margin: 0; - padding-left: 1em; -} - -.field-list p { - margin: 0; -} - -dl { - margin-bottom: 15px; - clear: both; -} - -dd p { - margin-top: 0px; -} - -dd ul, dd table { - margin-bottom: 10px; -} - -dd { - margin-top: 3px; - margin-bottom: 10px; - margin-left: 30px; -} - -.refcount { - color: #060; -} - -dt:target, -.highlight { - background-color: #fbe54e; -} - -dl.glossary dt { - font-weight: bold; - font-size: 1.1em; -} - -th { - text-align: left; - padding-right: 5px; -} - -pre { - padding: 5px; - background-color: #efc; - color: #333; - border: 1px solid #ac9; - border-left: none; - border-right: none; - overflow: auto; -} - -td.linenos pre { - padding: 5px 0px; - border: 0; - background-color: transparent; - color: #aaa; -} - -table.highlighttable { - margin-left: 0.5em; -} - -table.highlighttable td { - padding: 0 0.5em 0 0.5em; -} - -tt { - background-color: #ecf0f3; - padding: 0 1px 0 1px; - font-size: 0.95em; -} - -tt.descname { - background-color: transparent; - font-weight: bold; - font-size: 1.2em; -} - -tt.descclassname { - background-color: transparent; -} - -tt.xref, a tt { - background-color: transparent; - font-weight: bold; -} - -.footnote:target { background-color: #ffa } - -h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { - background-color: transparent; -} - -.optional { - font-size: 1.3em; -} - -.versionmodified { - font-style: italic; -} - -form.comment { - margin: 0; - padding: 10px 30px 10px 30px; - background-color: #eee; -} - -form.comment h3 { - background-color: #326591; - color: white; - margin: -10px -30px 10px -30px; - padding: 5px; - font-size: 1.4em; -} - -form.comment input, -form.comment textarea { - border: 1px solid #ccc; - padding: 2px; - font-family: sans-serif; - font-size: 100%; -} - -form.comment input[type="text"] { - width: 240px; -} - -form.comment textarea { - width: 100%; - height: 200px; - margin-bottom: 10px; -} - -.system-message { - background-color: #fda; - padding: 5px; - border: 3px solid red; -} - -/* :::: PRINT :::: */ -@media print { - div.document, - div.documentwrapper, - div.bodywrapper { - margin: 0; - width : 100%; - } - - div.sphinxsidebar, - div.related, - div.footer, - div#comments div.new-comment-box, - #top-link { - display: none; - } -} diff -r c243c0f65f17 -r 2b3fa6fb647b doc/book/fr/.templates/layout.html --- a/doc/book/fr/.templates/layout.html Thu Oct 14 00:01:04 2010 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,195 +0,0 @@ -{%- block doctype -%} - -{%- endblock %} -{%- set reldelim1 = reldelim1 is not defined and ' »' or reldelim1 %} -{%- set reldelim2 = reldelim2 is not defined and ' |' or reldelim2 %} -{%- macro relbar %} - -{%- endmacro %} -{%- macro sidebar %} - {%- if builder != 'htmlhelp' %} -
-
- {%- block sidebarlogo %} - {%- if logo %} - - {%- endif %} - {%- endblock %} - {%- block sidebartoc %} - {%- if display_toc %} -

Table Of Contents

- {{ toc }} - {%- endif %} - {%- endblock %} - {%- block sidebarrel %} - {%- if prev %} -

Previous topic

-

{{ prev.title }}

- {%- endif %} - {%- if next %} -

Next topic

-

{{ next.title }}

- {%- endif %} - {%- endblock %} - {%- if sourcename %} -

This Page

- - {%- endif %} - {%- if customsidebar %} - {{ rendertemplate(customsidebar) }} - {%- endif %} - {%- block sidebarsearch %} - {%- if pagename != "search" %} -

{{ builder == 'web' and 'Keyword' or 'Quick' }} search

- - {%- if builder == 'web' %} -

Enter a module, class or function name.

- {%- endif %} - {%- endif %} - {%- endblock %} -
-
- {%- endif %} -{%- endmacro -%} - - - - - {%- if builder != 'htmlhelp' %} - {%- set titlesuffix = " — " + docstitle %} - {%- endif %} - {{ title|striptags }}{{ titlesuffix }} - {%- if builder == 'web' %} - - {%- for link, type, title in page_links %} - - {%- endfor %} - {%- else %} - - - {%- endif %} - {%- if builder != 'htmlhelp' %} - - - - - {%- if use_opensearch %} - - {%- endif %} - {%- if favicon %} - - {%- endif %} - {%- endif %} -{%- block rellinks %} - {%- if hasdoc('about') %} - - {%- endif %} - - - - {%- if hasdoc('copyright') %} - - {%- endif %} - - {%- if parents %} - - {%- endif %} - {%- if next %} - - {%- endif %} - {%- if prev %} - - {%- endif %} -{%- endblock %} -{%- block extrahead %}{% endblock %} - - - -{% block logilablogo %} - -{% endblock %} - -{%- block relbar1 %}{{ relbar() }}{% endblock %} - -{%- block sidebar1 %}{# possible location for sidebar #}{% endblock %} - -{%- block document %} -
-
- {%- if builder != 'htmlhelp' %} -
- {%- endif %} -
- {% block body %}{% endblock %} -
- {%- if builder != 'htmlhelp' %} -
- {%- endif %} -
-{%- endblock %} - -{%- block sidebar2 %}{{ sidebar() }}{% endblock %} -
-
- -{%- block relbar2 %}{{ relbar() }}{% endblock %} - -{%- block footer %} - -{%- endblock %} - - diff -r c243c0f65f17 -r 2b3fa6fb647b doc/book/fr/01-introduction.fr.txt --- a/doc/book/fr/01-introduction.fr.txt Thu Oct 14 00:01:04 2010 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,343 +0,0 @@ -.. -*- coding: utf-8 -*- - -.. _Overview: - -Aperçu rapide de `CubicWeb` -=========================== - -`CubicWeb` nous permet de développer des instances d'applications web -basées sur un ou plusieurs `cube`. - -Ce à quoi nous réferrons en parlant de `cube` est un modèle définissant -des types de données et des vues. Un `cube` est un composant re-utilisable -regroupé avec d'autres cubes sur le système de fichiers. - -Un `instance` réferre à une installation spécifique d'un ou plusieurs cubes -où sont regroupés tous les fichiers de configuration de l'application web finale. - -Dans ce document, nous allons vous montrer comment créer un cube et l'utiliser -dans une instance pour votre application web. - -Créez votre cube ----------------- - -Après avoir installé votre environement de développement `CubicWeb`, vous pouvez -commencer à construire votre premier cube: :: - - cubicweb-ctl newcube blog - -Cela va créer dans ``/path/to/forest/cubes`` une répertoire contenant :: - - 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 - -Toute modification apportée à votre modele de données devra -etre effectué dans ce répertoire. - - - -Définissez votre schéma de données ----------------------------------- - -Le modèle de données ou schéma est au coeur d'une application `CubicWeb`. -C'est là où vous allez devoir définir le type de contenu que votre application -devra gérer. - -Votre modele de données est défini dans le fichier ``schema.py`` de votre cube -``blog`` comme suit. - -:: - - 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='?*') - -Un ``Blog`` a un titre et une description. Le titre est une chaîne -de caractères requise par la classe parente EntityType et ne doit -pas excéder 50 caractères. La description est une chaîne de -caractères sans contraintes. - -Une ``BlogEntry`` a un titre, une date de publication et du texte -étant son contenu. Le titre est une chaîne de caractères qui ne -doit pas excéder 100 caractères. La date de publication est de type Date et a -pour valeur par défaut TODAY, ce qui signifie que lorsqu'une -``BlogEntry`` sera créée, sa date de publication sera la date -courante a moins de modifier ce champ. Le texte est une chaîne de -caractères qui sera indexée en plein texte et sans contraintes. - -Une ``BlogEntry`` a aussi une relation nommée ``entry_of`` qui la -relie à un ``Blog``. La cardinalité ``?*`` signifie que BlogEntry -peut faire partie de zero a un Blog (``?`` signifie `zero ou un`) et -qu'un Blog peut avoir une infinité de BlogEntry (``*`` signifie -`n'importe quel nombre incluant zero`). -Par soucis de complétude, nous rappellerons que ``+`` signifie -`un ou plus`. - - -Créez votre instance --------------------- - -:: - - cubicweb-ctl create blog blogdemo - -Cette commande va créer un répertoire ``~/etc/cubicweb.d/blogdemo`` -contenant tous les fichiers de configuration nécessaire au lancement -de votre application web. - -L'instance ``blogdemo`` est construite sur le cube ``blog``. - -Bienvenue dans votre application web ------------------------------------- - -Lancez votre application en exécutant : :: - - cubicweb-ctl start -D blogdemo - - -Vous pouvez à présent accéder à votre application web vous permettant de -créer des blogs et d'y poster des messages en visitant l'URL http://localhost:8080/. -Un premier formulaire d'authentification va vous être proposé. Par défaut, -l'application n'autorisera pas d'utilisateur anonyme à accéder a votre -application. Vous devrez donc utiliser l'utilisateur administrateur que -vous aurez crée lors de l'initialisation de votre base de données via -``cubicweb-ctl create``. - -.. image:: images/login-form.png - - -Une fois authentifié, vous pouvez commencer à jouer avec votre -application et créer des entités. Bravo ! - -.. image:: images/blog-demo-first-page.png - - -Rappelez-vous que pour le moment, tout a été géré par la plate-forme -`CubicWeb` et que la seule chose qui a été fournie est le schéma de -données. - -Créons des entités ------------------- - -Nous allons maintenant créer quelques entités dans notre application. - -Créez un Blog -~~~~~~~~~~~~~ - -Créons à présent quelques entités. Cliquez sur `[+]` sur la -droite du lien Blog. Appelez cette nouvelle entité Blog ``Tech-Blog`` -et tapez pour la description ``everything about technology``, -puis validez le formulaire d'édition en cliquant sur le bouton -``Validate``. - -.. image:: images/cbw-create-blog.fr.png - :alt: from to create blog - -En cliquant sur le logo situé dans le coin gauche de la fenêtre, -vous allez être redirigé vers la page d'accueil. Ensuite, si vous allez -sur le lien Blog, vous devriez voir la liste des entités Blog, en particulier -celui que vous venez juste de créer ``Tech-Blog``. - -.. image:: images/cbw-list-one-blog.fr.png - :alt: displaying a list of a single blog - -Si vous cliquez sur ``Tech-Blog`` vous devriez obtenir une description -détaillée, ce qui dans notre cas, n'est rien de plus que le titre -et la phrase ``everything about technology`` - -Maintenant retournons sur la page d'accueil et créons un nouveau -Blog ``MyLife`` et retournons sur la page d'accueil, puis suivons -le lien Blog et nous constatons qu'à présent deux blogs sont listés. - -.. image:: images/cbw-list-two-blog.fr.png - :alt: displaying a list of two blogs - -Créons un article -~~~~~~~~~~~~~~~~~ - -Revenons sur la page d'accueil et cliquons sur `[+]` à droite du lien -`articles`. Appellons cette nouvelle entité ``Hello World`` et introduisons -un peut de texte avant de ``Valider``. Vous venez d'ajouter un article -sans avoir précisé à quel Blog il appartenait. Dans la colonne de gauche -se trouve une boite intitulé ``actions``, cliquez sur le menu ``modifier``. -Vous êtes de retour sur le formulaire d'édition de l'article que vous -venez de créer, à ceci près que ce formulaire a maintenant une nouvelle -section intitulée ``ajouter relation``. Choisissez ``entry_of`` dans ce menu, -cela va faire apparaitre une deuxième menu déroulant dans lequel vous -allez pouvoir séléctionner le Blog ``MyLife``. - -Vous auriez pu aussi, au moment où vous avez crée votre article, sélectionner -``appliquer`` au lieu de ``valider`` et le menu ``ajouter relation`` serait apparu. - -.. image:: images/cbw-add-relation-entryof.fr.png - :alt: editing a blog entry to add a relation to a blog - -Validez vos modifications en cliquant sur ``Valider``. L'entité article -qui est listée contient maintenant un lien vers le Blog auquel il -appartient, ``MyLife``. - -.. image:: images/cbw-detail-one-blogentry.fr.png - :alt: displaying the detailed view of a blogentry - -Rappelez-vous que pour le moment, tout a été géré par la plate-forme -`CubicWeb` et que la seule chose qui a été fournie est le schéma de -données. D'ailleurs pour obtenir une vue graphique du schéma, visitez -le lien `Application schema`` a l'URL suivante : -http://localhost:8080/view?vid=schema - -.. image:: images/cbw-schema.fr.png - :alt: graphical view of the schema (aka data-model) - - -Définissez les vues de vos données ----------------------------------- - -Le principe de sélection des vues -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Une vue est une classe Python qui inclut: - - - un identifiant (tous les objets dans `CubicWeb` sont listés - dans un registre et cet identifiant est utilisé comme la clé) - - - un filtre de sélection de `result sets` auxquels il - peut s'appliquer - -`CubicWeb` fournit un ensemble de vues standard pour le type d'objet -`EntityView`. vous poubez les trouver listées dans ``cubicweb/web/views``. - -Une vue est appliquée sur un `result set` qui représente l'ensemble -des entités que nous cherchons à appliquer. `CubicWeb` utilise un -sélecteur qui permet de calculer un score et d'identifier la vue -la plus adaptée au `result set` que nous voulons afficher. La librarie -standard des sélecteurs se trouve dans ``cubicweb.common.selector`` -et une librairie des méthodes utilisées pour calculer les scores -est dans ``cubicweb.vregistry.vreq``. - - -Il est possible de définir plusieurs vues ayant le meme identifiant -et d'y associer des sélecteurs et des filtres afin de permettre à -l'application de s'adapter au mieux aux données que nous avons -besoin d'afficher. Nous verrons cela plus en détails dans :ref:`DefinitionVues`. - -On peut citer l'exemple de la vue nommée ``primary`` qui est celle utilisée -pour visualiser une entité seule. Nous allons vous montrer comment modifier -cette vue. - -Modification des vues -~~~~~~~~~~~~~~~~~~~~~ -Si vous souhaitez modifier la manière dont est rendue un article (`Blogentry`), -vous devez surcharger la vue ``primary`` définie dans le module ``views`` de -votre cube, ``cubes/blog/views.py``. - -Nous pourrions par exemple ajouter devant la date de publication un préfixe -indiquant que la date visualisée est la date de publication. - -Pour cela appliquez les modifications suivantes: - -:: - - from cubicweb.web.views import baseviews - - - class BlogEntryPrimaryView(baseviews.PrimaryView): - - accepts = ('BlogEntry',) - - def render_entity_title(self, entity): - self.w(u'

%s

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

%s

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

published on %s

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

%s

' % entity.content) - - # display relations - siderelations = [] - if self.main_related_section: - self.render_entity_relations(entity, siderelations) - -.. note:: - Lors qu'une vue est modifiée il n'est pas nécessaire de relancer - l'application. Sauvez juste le fichier Python et rechargez la page - dans votre navigateur afin de visualiser les modifications. - - -Nous pouvons voir que la date de publication est préfixée comme souhaitée. - - -.. image:: images/cbw-update-primary-view.fr.png - :alt: modified primary view - - - -Le code que nous avons modifié définit une vue primaire pour une entité de -type `BlogEntry`. - -Etant donné que les vues sont appliquées sur des `result sets` et que -les `result sets` peuvent être des tableaux de données, il est indispensable -de récupérer l'entité selon ses coordonnées (row,col). - -La méthode ``self.w()`` est utilisée pour afficher des données. En particulier -dans notre exemple, nous l'utilisons pour afficher des tags HTML et des valeurs -des attributs de notre entité. - - diff -r c243c0f65f17 -r 2b3fa6fb647b doc/book/fr/02-foundation.fr.txt --- a/doc/book/fr/02-foundation.fr.txt Thu Oct 14 00:01:04 2010 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,431 +0,0 @@ -.. -*- coding: utf-8 -*- - -Fondements `CubicWeb` -===================== -Un peu d'histoire... --------------------- - -`CubicWeb` est une plate-forme logicielle de développement d'application web -qui est développée par Logilab_ depuis 2001. - - -Entièrement développée en Python, `CubicWeb` publie des données provenant -de plusieurs sources telles que des bases de données SQL, des répertoire -LDAP et des systèmes de gestion de versions tels que subversion. - -L'interface utilisateur de `CubicWeb` a été spécialement conçue pour laisser -à l'utilisateur final toute latitude pour sélectionner puis présenter les données. -Elle permet d'explorer aisément la base de connaissances et d'afficher les -résultats avec la présentation la mieux adaptée à la tâche en cours. -La flexibilité de cette interface redonne à l'utilisateur le contrôle de -paramètres d'affichage et de présentation qui sont habituellement réservés -aux développeurs. - -Parmi les applications déjà réalisées, on dénombre un annuaire en ligne pour -le grand public (voir http://www.118000.fr/), un système de gestion d'études -numériques et de simulations pour un bureau d'études, un service de garde -partagée d'enfants (voir http://garde-partagee.atoukontact.fr/), la gestion -du développement de projets logiciels (voir http://www.logilab.org), etc. - -En 2008, `CubicWeb` a été porté pour un nouveau type de source: le datastore -de GoogleAppEngine_. - -.. _GoogleAppEngine: http://code.google.com/appengine/ - - -Architecture globale --------------------- -.. image:: images/archi_globale.png - -**Note**: en pratique la partie cliente et la partie serveur sont -généralement intégrées dans le même processus et communiquent donc -directement, sans nécessiter des appels distants via Pyro. Il est -cependant important de retenir que ces deux parties sont disjointes -et qu'il est même possible d'en exécuter plusieurs exemplaires dans -des processus distincts pour répartir la charge globale d'un site -sur une ou plusieurs machines. - -Concepts et vocabulaire ------------------------ - -*schéma* - le schéma définit le modèle de données d'une application sous forme - d'entités et de relations, grâce à la bibliothèque `yams`_. C'est - l'élément central d'une application. Il est initialement défini sur - le système de fichiers et est stocké dans la base de données lors de - la création d'une instance. `CubicWeb` fournit un certain nombres de - types d'entités inclus systématiquement car nécessaire au noyau - `CubicWeb` et une librairie de cubes devant être inclus - explicitement le cas échéant. - -*type d'entité* - une entité est un ensemble d'attributs ; l'attribut de - base de toute entité, qui est sa clef, est l'eid - -*type de relation* - les entités sont liées entre elles par des relations. Dans `CubicWeb` - les relations sont binaires : par convention on nomme le premier terme - d'une relation son 'sujet' et le second son 'objet'. - -*type d'entité final* - les types finaux correspondent aux types de bases comme les chaînes - de caractères, les nombres entiers... Une propriété de ces types est - qu'ils ne peuvent être utilisés qu'uniquement comme objet d'une - relation. Les attributs d'une entité (non finale) sont des entités - (finales). - -*type de relation finale* - une relation est dite finale si son objet est un type final. Cela revient à - un attribut d'une entité. - -*entrepôt* - ou *repository*, c'est la partie serveur RQL de `CubicWeb`. Attention à ne pas - confondre avec un entrepôt mercurial ou encore un entrepôt debian. - -*source* - une source de données est un conteneur de données quelquonque (SGBD, annuaire - LDAP...) intégré par l'entrepôt `CubicWeb`. Un entrepôt possède au moins une source - dite "system" contenant le schéma de l'application, l'index plein-texte et - d'autres informations vitales au système. - -*configuration* - il est possible de créer différentes configurations pour une instance : - - - ``repository`` : entrepôt uniquement, accessible pour les clients via Pyro - - ``twisted`` : interface web uniquement, communiquant avec un entrepôt via Pyro - - ``all-in-one`` : interface web et entrepôt dans un seul processus. L'entrepôt - peut ou non être accessible via Pyro - -*cube* - un cube est un modèle regroupant un ou plusieurs types de données et/ou - des vues afin de fournir une fonctionalité précise, ou une application `CubicWeb` - complète utilisant éventuellement d'autres cube. Les différents - cubes disponibles sur une machine sont installés dans - `/path/to/forest/cubicweb/cubes` - -*instance* - une instance est une installation spécifique d'un cube. Sont regroupes - dans une instance tous les fichiers de configurations necessaires au bon - fonctionnement de votre application web. Elle referrera au(x) cube(s) sur - le(s)quel(s) votre application se base. - Par exemple intranet/jpl et logilab.org sont deux instances du cube jpl que - nous avons developpes en interne. - Les instances sont définies dans le répertoire `~/etc/cubicweb.d`. - -*application* - le mot application est utilisé parfois pour parler d'une instance et parfois - d'un composant, en fonction du contexte... Mieux vaut donc éviter de - l'utiliser et utiliser plutôt *cube* et *instance*. - -*result set* - objet encaspulant les résultats d'une requête RQL et des informations sur - cette requête. - -*Pyro* - `Python Remote Object`_, système d'objets distribués pur Python similaire à - Java's RMI (Remote Method Invocation), pouvant être utilisé pour la - communication entre la partie web du framework et l'entrepôt RQL. - -.. _`Python Remote Object`: http://pyro.sourceforge.net/ -.. _`yams`: http://www.logilab.org/project/name/yams/ - - -Moteur `CubicWeb` ------------------ - -Le moteur web de `CubicWeb` consiste en quelques classes gérant un ensemble d'objets -chargés dynamiquement au lancement de `CubicWeb`. Ce sont ces objets dynamiques, issus -du modèle ou de la librairie, qui construisent le site web final. Les différents -composants dynamiques sont par exemple : - -* coté client et serveur - - - les définitions d'entités, contenant la logique permettant la manipulation des - données de l'application - -* coté client - - - les *vues* , ou encore plus spécifiquement - - - les boites - - l'en-tête et le pied de page - - les formulaires - - les gabarits de pages - - - les *actions* - - les *controleurs* - -* coté serveur - - - les crochets de notification - - les vues de notification - -Les différents composants du moteur sont : - -* un frontal web (seul twisted disponible pour le moment), transparent du point - de vue des objets dynamiques -* un objet encapsulant la configuration -* un `vregistry` (`cubicweb.cwvreg`) contenant les objets chargés dynamiquements - -Détail de la procédure d'enregistrement ---------------------------------------- -Au démarage le `vregistry` ou base de registres inspecte un certain nombre de -répertoires à la recherche de définition de classes "compatible". Après une -procédure d'enregistrement les objets sont affectés dans différents registres -afin d'être ensuite séléctionné dynamiquement pendant le fonctionnement de -l'application. - -La classe de base de tout ces objets est la classe `AppRsetObject` (module -`cubicweb.common.appobject`). - - -API Python/RQL --------------- - -Inspiré de la db-api standard, avec un object Connection possédant les méthodes -cursor, rollback et commit principalement. La méthode importante est la méthode -`execute` du curseur : - -`execute(rqlstring, args=None, eid_key=None, build_descr=True)` - -:rqlstring: la requête rql à éxécuter (unicode) -:args: si la requête contient des substitutions, un dictionnaire contenant les - valeurs à utiliser -:eid_key: - un détail d'implémentation du cache de requêtes RQL fait que si une substitution est - utilisée pour introduire un eid *levant des ambiguités dans la résolution de - type de la requête*, il faut spécifier par cet argument la clé correspondante - dans le dictionnaire - -C'est l'objet Connection qui possède les méthodes classiques `commit` et -`rollback`. Vous ne *devriez jamais avoir à les utiliser* lors du développement -d'interface web sur la base du framework `CubicWeb` étant donné que la fin de la -transaction est déterminée par celui-ci en fonction du succès d'éxécution de la -requête. - -NOTE : lors de l'éxécution de requêtes de modification (SET,INSERT,DELETE), si une -requête génère une erreur liée à la sécurité, un rollback est systématiquement -effectuée sur la transaction courante. - - -La classe `Request` (`cubicweb.web`) ------------------------------------- -Une instance de requête est créée lorsque une requête HTTP est transmise au -serveur web. Elle contient des informations telles que les paramètres de -formulaires, l'utilisateur connecté, etc. - -**De manière plus générale une requête représente une demande d'un utilisateur, -que se soit par HTTP ou non (on parle également de requête rql coté serveur par -exemple)** - -Une instance de la classe `Request` possède les attributs : - -* `user`, instance de`cubicweb.common.utils.User` correspondant à l'utilisateur - connecté -* `form`, dictionaire contenant les valeurs de formulaire web -* `encoding`, l'encodage de caractère à utiliser dans la réponse - -Mais encore : - -:Gestion des données de session: - * `session_data()`, retourne un dictionaire contenant l'intégralité des - données de la session - * `get_session_data(key, default=None)`, retourne la valeur associée à - la clé ou la valeur `default` si la clé n'est pas définie - * `set_session_data(key, value)`, associe une valeur à une clé - * `del_session_data(key)`, supprime la valeur associé à une clé - - -:Gestion de cookie: - * `get_cookie()`, retourne un dictionnaire contenant la valeur de l'entête - HTTP 'Cookie' - * `set_cookie(cookie, key, maxage=300)`, ajoute un en-tête HTTP `Set-Cookie`, - avec une durée de vie 5 minutes par défault (`maxage` = None donne un cooke - *de session"* expirant quand l'utilisateur ferme son navigateur - * `remove_cookie(cookie, key)`, fait expirer une valeur - -:Gestion d'URL: - * `url()`, retourne l'url complète de la requête HTTP - * `base_url()`, retourne l'url de la racine de l'application - * `relative_path()`, retourne chemin relatif de la requête - -:Et encore...: - * `set_content_type(content_type, filename=None)`, place l'en-tête HTTP - 'Content-Type' - * `get_header(header)`, retourne la valeur associé à un en-tête HTTP - arbitraire de la requête - * `set_header(header, value)`, ajoute un en-tête HTTP arbitraire dans la - réponse - * `cursor()` retourne un curseur RQL sur la session - * `execute(*args, **kwargs)`, raccourci vers .cursor().execute() - * `property_value(key)`, gestion des propriétés (`CWProperty`) - * le dictionaire `data` pour stocker des données pour partager de - l'information entre les composants *durant l'éxécution de la requête*. - -A noter que cette classe est en réalité abstraite et qu'une implémentation -concrète sera fournie par le *frontend* web utilisé (en l'occurent *twisted* -aujourd'hui). Enfin pour les vues ou autres qui sont éxécutés coté serveur, -la majeure partie de l'interface de `Request` est définie sur la session -associée au client. - - -La classe `AppObject` ---------------------- - -En général : - -* on n'hérite pas directement des cette classe mais plutôt d'une classe - plus spécifique comme par exemple `AnyEntity`, `EntityView`, `AnyRsetView`, - `Action`... - -* pour être enregistrable, un classe fille doit définir son registre (attribut - `__registry__`) et son identifiant (attribut `id`). Généralement on n'a pas à - s'occuper du registre, uniquement de l'identifiant `id` :) - -On trouve un certain nombre d'attributs et de méthodes définis dans cette classe -et donc commune à tous les objets de l'application : - -A l'enregistrement, les attributs suivants sont ajoutés dynamiquement aux -*classes* filles: - -* `vreg`, le `vregistry` de l'application -* `schema`, le schéma de l'application -* `config`, la configuration de l'application - -On trouve également sur les instances les attributs : - -* `req`, instance de `Request` -* `rset`, le "result set" associé à l'objet le cas échéant -* `cursor`, curseur rql sur la session - - -:Gestion d'URL: - * `build_url(method=None, **kwargs)`, retourne une URL absolue construites à - partir des arguments donnés. Le *controleur* devant gérer la réponse - peut-être spécifié via l'argument spécial `method` (le branchement est - théoriquement bien effectué automatiquement :). - - * `datadir_url()`, retourne l'url du répertoire de données de l'application - (contenant les fichiers statiques tels que les images, css, js...) - - * `base_url()`, raccourci sur `req.base_url()` - - * `url_quote(value)`, version *unicode safe* de de la fonction `urllib.quote` - -:Manipulation de données: - - * `etype_rset(etype, size=1)`, raccourci vers `vreg.etype_rset()` - - * `eid_rset(eid, rql=None, descr=True)`, retourne un objet result set pour - l'eid donné - * `entity(row, col=0)`, retourne l'entité correspondant à la position données - du "result set" associé à l'objet - - * `complete_entity(row, col=0, skip_bytes=True)`, équivalent à `entity` mais - appelle également la méthode `complete()` sur l'entité avant de la retourner - -:Formattage de données: - * `format_date(date, date_format=None, time=False)` - * `format_time(time)`, - -:Et encore...: - - * `external_resource(rid, default=_MARKER)`, accède à une valeur définie dans - le fichier de configuration `external_resource` - - * `tal_render(template, variables)`, - - -**NOTE IMPORTANTE** -Lorsqu'on hérite d'`AppObject` (même indirectement), il faut **toujours** -utiliser **super()** pour récupérer les méthodes et attributs des classes -parentes, et pas passer par l'identifiant de classe parente directement. -(sous peine de tomber sur des bugs bizarres lors du rechargement automatique -des vues). Par exemple, plutôt que d'écrire:: - - class Truc(PrimaryView): - def f(self, arg1): - PrimaryView.f(self, arg1) - -Il faut écrire:: - - class Truc(PrimaryView): - def f(self, arg1): - super(Truc, self).f(arg1) - - - - - - -Structure standard d'un cube ----------------------------- - -Un cube complexe est structuré selon le modèle suivant : - -:: - - moncube/ - | - |-- schema.py - | - |-- entities/ - | - |-- sobjects/ - | - |-- views/ - | - |-- test/ - | - |-- i18n/ - | - |-- data/ - | - |-- migration/ - | |- postcreate.py - | \- depends.map - | - |-- debian/ - | - \-- __pkginfo__.py - -On peut utiliser de simple module python plutôt que des répertoires (packages), -par ex.: - -:: - - moncube/ - | - |-- entities.py - |-- hooks.py - \-- views.py - - -où : - -* ``schema`` contient la définition du schéma (coté serveur uniquement) -* ``entities`` contient les définitions d'entités (coté serveur et interface web) -* ``sobjects`` contient les crochets et/ou vues de notification (coté serveur - uniquement) -* ``views`` contient les différents composants de l'interface web (coté interface - web uniquement) -* ``test`` contient les tests spécifiques à l'application (non installé) -* ``i18n`` contient les catalogues de messages pour les langues supportées (coté - serveur et interface web) -* ``data`` contient des fichiers de données arbitraires servis statiquement - (images, css, fichiers javascripts)... (coté interface web uniquement) -* ``migration`` contient le fichier d'initialisation de nouvelles instances - (``postcreate.py``) et générallement un fichier donnant les dépendances `CubicWeb` du - composant en fonction de la version de celui-ci (``depends.map``) -* ``debian`` contient les fichiers contrôlant le packaging debian (vous y - trouverez les fichiers classiques ``control``, ``rules``, ``changelog``... (non - installé) -* le fichier ``__pkginfo__.py`` donne un certain nombre de méta-données sur le - composant, notamment le nom de la distribution et la version courante (coté - serveur et interface web) ou encore les sous-cubes utilisés par ce - cube. - -Le strict minimum étant : - -* le fichier ``__pkginfo__.py`` -* la définition du schéma diff -r c243c0f65f17 -r 2b3fa6fb647b doc/book/fr/03-01-bis-installation.fr.txt --- a/doc/book/fr/03-01-bis-installation.fr.txt Thu Oct 14 00:01:04 2010 +0200 +++ /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 - - diff -r c243c0f65f17 -r 2b3fa6fb647b doc/book/fr/03-01-installation.fr.txt --- a/doc/book/fr/03-01-installation.fr.txt Thu Oct 14 00:01:04 2010 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,150 +0,0 @@ -.. -*- coding: utf-8 -*- - -Installation -============ - -Installation de Cubicweb et de ses dépendances ----------------------------------------------- - -`CubicWeb` est disponible via un entrepôt Mercurial utilisant l'extension forest. -Vous devez donc dans un premier temps vous assurer que Mercurial est bien installé -et que vous avez l'extension forest. - -Installation de Mercurial -````````````````````````` -Veuillez vous référer a la documentation en ligne du projet Mercurial_. - -.. _Mercurial: http://www.selenic.com/mercurial/wiki/ - -Installation de l'extension forest -`````````````````````````````````` -Dans un premier temps, récupérez une copie des sources via: http://hg.akoha.org/hgforest/. -Ensuite, ajoutez a votre ``~/.hgrc`` les lignes suivantes :: - - [extensions] - hgext.forest= - # or, if forest.py is not in the hgext dir: - # forest=/path/to/forest.py - -Récupération des sources -```````````````````````` -Clonez la foret dans votre répertoire de travail. - -:: - - hg fclone http://www.logilab.org/hg/forests/cubicweb - -.. note:: - Nous vous recommandons de créer un lien symbolique vers l'outil ``cubicweb-ctl`` - que vous allez etre amené a utiliser. - - :: - - $ ln -s /path/to/forest/cubicweb/bin/cubicweb-ctl ~/bin - -Installation de Postgres -```````````````````````` -Veuillez vous référer a la documentation en ligne du projet Postgres_. - -.. _Postgres: http://www.postgresql.org/ - -Vous allez devoir installer les trois paquets suivants: `postgres-8.3`, -`postgres-contrib-8.3` and `postgresql-plpython-8.3`. - - -On pourra ensuite installer les paquets suivants : - -* `pyro` si vous voulez que l'entrepôt soit accessible via Pyro ou si le client - et le serveur ne sont pas sur la même machine (auquel cas il faut installer ce - paquet sur les machines clientes et serveur) - -* `python-ldap` si vous voulez utiliser une source ldap sur le serveur - - -.. _ConfigurationEnv: - -Configuration de l'environnement --------------------------------- - -[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? - -Mettez à jour votre variable d'environemment PYTHONPATH afin d'y ajouter -le chemin d'acces a votre foret ``cubicweb``. - -Ajouter les lignes suivantes à son `.bashrc` ou `.bash_profile` pour configurer -votre environnement de développement :: - - export PYTHONPATH=/full/path/to/cubicweb-forest - - 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: - -Configuration Postgres ----------------------- -* Tout d'abord vous devez initialiser votre base de données Postgres via la - commande ``initidb``. - :: - - $ initdb -D /path/to/pgsql - - Une fois ces paquets installés vous pouvez lancer votre server de base de - données Postgres avec la commande suivante: :: - - $ postgres -D /path/to/psql - - Si vous ne pouvez exécuter cette commande pour des raisons de permissions - assurez-vous que votre utilisateur a droit d'écriture sur les la base de données. - - :: - - $ chown username /path/to/pgsql - -* Création d'un super utilisateur pour la création d'instance (**root**) :: - - createuser -s username - - Initialisez le mot de passe de ce superutilisateur ``username`` via - ``su - postgres`` puis ``psql``. - - Un mot de passe de connection pour cet utilisateur vous sera demandé. Il - faudra utiliser ce login / mot de passe à la création d'instance via - `cubicweb-ctl` - -[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 des extensions pour l'index plein texte :: - - cat /usr/share/postgresql/8.1/contrib/tsearch2.sql | psql -U pgadmin template1 - -* installation du langage plpythonu par défaut :: - - createlang -U pgadmin plpythonu template1 - - -Configuration Pyro ------------------- -Si vous utilisez Pyro, il est nécessaire d'avoir un serveur de noms Pyro -tournant sur votre réseau (par défaut celui-ci est repéré par une requête -broadcast). Pour cela il faut soit : - -* le lancer à la main avant le démarrage de erudi avec la commande `pyro-ns` - -* le lancer à la main avant le démarrage de erudi sous forme d'un serveur avec - la commande `pyro-nsd start` - -* éditer le fichier */etc/default/pyro-nsd* pour que le serveur de nom pyro soit - lancé automatiquement au démarrage de la machine - - diff -r c243c0f65f17 -r 2b3fa6fb647b doc/book/fr/03-02-create-instance.fr.txt --- a/doc/book/fr/03-02-create-instance.fr.txt Thu Oct 14 00:01:04 2010 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,131 +0,0 @@ -.. -*- coding: utf-8 -*- - -=================================== -Creation de votre premiere instance -=================================== - - -Qu'est-ce qu'une instance? -========================== - -Une instance CubicWeb consiste en un dossier situe dans ``~/etc/cubicweb.d`` -qui permettra de lancer une application web. Une instance est cree a partir -d'un ou plusieurs cubes. - -Nous recommandons de ne pas definir de schema, entites ou vues dans l'instance -meme si cela est possible dans un but de re-utilisabilite des entities et de leurs -vues. Nous conseillons plutot de developper des cubes qui pourront par la suite -etre utilises dans d'autres instances (approche modulaire). - -L'instance n'est qu'un conteneur referrant a des cubes et a des parametres -des configuration de l'application web. - -Qu'est-ce qu'un cube? -===================== - -Un cube definit des entities, leur vues, leur schemas et leur workflow -dans un repertoire independant situe dans ``/path/to/forest/cubicweb/cubes/``. - -Lors de la creation d'une instance, vous avez la possibilite de lister -le ou les cubes que votre instance va utiliser. Utiliser un cube signifie -avoir a disposition dans votre instance les entites definies dans le schema -de votre cube ainsi que les vues et les workflows. - - -.. note:: - Les commandes utilisees ci-apres sont detaillees dans la section - dediee a :ref:`cubicweb-ctl`. - - -Création d'un cube -================== - -Commençons par créer un squelette qui nous servira de base au développement de -notre cube ou application :: - - cd ~/hg - - cubicweb-ctl newtemplate moncube - - # répondre aux questions - cd moncube - hg init - hg add . - hg ci - -A partir de là si tout va bien, votre cube devrait être affiché par -`cubicweb-ctl list` dans la section *Available components*, si ce n'est pas le cas -revoir la section :ref:`ConfigurationEnv`. - - -Pour utiliser un cube, il faut le mentionner dans la variable -__use__ du fichier __pkginfo__ de l'application. Cette variable -contrôle à la fois le packaging de l'application (dépendances gérées -par les utilitaires système comme les outils APT) et les composants -effectivement utilisables lors de la création de la base -(import_erschema('Moncomposant') ne fonctionne pas sinon). - -FIXME - need example code :: - - __use__ = ('blog', 'file') - -Création d'une instance de développement -======================================== - -Maintenant que nous avons notre squelette de modèle, on peut en créer une -instance afin de voir ce que tout ça donne dans un simple navigateur web. -Nous allons utiliser une configuration `all-in-one` afin de simplifier les -choses :: - - cubicweb-ctl create -c all-in-one moncube moninstance - -Une série de questions vont être posées, la réponse par défaut est généralement -suffisante. Vous pourrez de toute façon modifier la configuration par la suite -en éditant les fichiers générés. Lorsqu'un login/mot de passe d'accès au sgbd -vous est demandé, il est recommandé d'utiliser l'utilisateur créé lors de la -:ref:`ConfigurationPostgres`. - -Il est important de distinguer ici l'utilisateur utilisé pour accéder au sgbd, -et l'utilisateur utilisé pour s'authentifier dans l'application cubicweb. Lorsque -l'application cubicweb démarre, elle utilise le login/mot de passe sgdb pour -récupérer le schéma et gérer les transactions bas-niveau. En revanche, lorsque -`cubicweb-ctl create` vous demande un login/mot de passe `manager` pour cubicweb, il -s'agit d'un utilisateur qui sera créé dans l'application `cubicweb` pour pouvoir -s'y connecter dans un premier temps et l'administrer. Il sera par la suite possible -de créer des utilisateurs différents pour l'application. - -A l'issue de cette commande, la définition de votre instance se trouve dans -*~/etc/cubicweb.d/moninstance/*. Pour la lancer, il suffit de taper :: - - cubicweb-ctl start -D moninstance - -L'option `-D` indique le *debug mode* : l'instance ne passe pas en mode serveur -et ne se déconnecte pas du terminal, ce qui simplifie le dépannage en cas de non -démarrage de l'instance. Vous pouvez ensuite allez voir ce que ça donne en -pointant votre navigateur sur l'url `http://localhost:8080` (le n° de port -dépend de votre configuration). Pour vous authentifier vous pouvez utiliser le -login/mot de passe administrateur que vous avez spécifié lors de la création de -l'instance. - -Pour arrêter l'instance, un Ctrl-C dans la fenêtre où vous l'avez lancé -suffit. Si l'option `-D` a été omise, il faut taper :: - - cubicweb-ctl stop moninstance - -Voilà, tout est en place pour démarrer le développement du modèle... - - -Utilisation de cubicweb-liveserver ----------------------------------- - -Afin de tester rapidement un nouveau cube, on peut également -utiliser le script `cubicweb-liveserver` qui permet de créer une -application en mémoire (utilisant une base de données SQLite par -défaut) et la rendre accessible via un serveur web:: - - cubicweb-ctl live-server moncomposant - -ou bien, pour utiliser une base de données existante (SQLite ou postgres):: - - cubicweb-ctl live-server -s monfichier_sources moncomposant - diff -r c243c0f65f17 -r 2b3fa6fb647b doc/book/fr/03-03-cubicweb-ctl.fr.txt --- a/doc/book/fr/03-03-cubicweb-ctl.fr.txt Thu Oct 14 00:01:04 2010 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,121 +0,0 @@ -.. -*- coding: utf-8 -*- - -.. _cubicweb-ctl: - -L'outil `cubicweb-ctl` -====================== -`cubicweb-ctl` est le couteau suisse pour la gestion d'instances CubicWeb. -La syntaxe générale est :: - - cubicweb-ctl [options commande] - -Pour voir les commandes disponibles :: - - cubicweb-ctl - cubicweb-ctl --help - -A noter que les commandes disponibles varient en fonction des parties d'CubicWeb -qui sont installées. - -Pour voir l'aide pour une commande spécifiques :: - - cubicweb-ctl --help - -Commandes pour la création d'un cube ------------------------------------- -* ``newcube``, crée un nouveau cube sur le système de fichiers - à partir du nom passé en paramètre. Cette commande crée le cube à partir - d'une squelette d'application, incluant également les fichiers pour le - packaging debian) - -Commandes pour la création d'une instance ------------------------------------------ -* ``create``, crée les fichiers de configuration d'une instance -* ``db-create``, crée la base de données système d'une instance (tables et - extensions uniquement) -* ``db-init``, initialise la base de données système d'une instance (schéma, - groupes, utilisateurs, workflows...) - -Par défaut ces trois commandes sont enchainées. - -Commande pour la création d'une instance pour Google App Engine ---------------------------------------------------------------- -* ``newgapp``, crée les fichiers de configuration d'une instance - -Cette commande doit être suivie de l'exécution de commandes -permettant l'initialisation de la base de données spécifique à -Google App Engine, appellée ``datastore``. - -Pour plus de détails veuillez vous référer à `LAX <>`_ - - -Commandes pour le lancement des instances ------------------------------------------ -* ``start``, démarre une, plusieurs, ou toutes les instances -* ``stop``, arrêt une, plusieurs, ou toutes les instances -* ``restart``, redémarre une, plusieurs, ou toutes les instances -* ``status``, donne l'état des instances - -Commandes pour la maintenance des instances -------------------------------------------- -* ``upgrade``, lance la migration d'instance(s) existante(s) lorsqu'une nouvelle - version d'CubicWeb ou du composant est installée -* ``shell``, ouvre un shell de migration pour la maintenance manuelle d'une instance -* ``db-dump``, crée un dump de la base de données système -* ``db-restore``, restore un dump de la base de données système -* ``db-check``, vérifie l'intégrité des données d'une instance. Si la correction - automatique est activée, il est conseillé de faire un dump avant cette - opération -* ``schema-sync``, , synchronise le schéma persistent d'une instance avec le schéma - de l'application. Il est conseillé de faire un dump avant cette opération - -Commandes pour la maintenance des catalogues i18n -------------------------------------------------- -* ``i18ncubicweb``, regénère les catalogues de messages de la librairie CubicWeb -* ``i18ncube``, regénère les catalogues de messages d'un composant -* ``i18ninstance``, recompile les catalogues de messages d'une instance. Cela est - effectué automatiquement lors d'une upgrade - -Cf :ref:`Internationalisation`. - -Autres commandes ----------------- -* ``list``, donne la liste des configurations, des composants et des instances - disponibles -* ``delete``, supprime une instance (fichiers de configuration et base de données) - - - -Exemples --------- - -Creation d'une instance a partir de cube existant -````````````````````````````````````````````````` - -Afin de creer une instance a partir d'un cube existant, executez la commande -suivant :: - - cubicweb-ctl create - -Cette commande va creer les fichiers de configuration d'une instance dans -``~/etc/cubicweb.d/``. -L'outil ``cubicweb-ctl`` va vous autoriser a executer au sein de ``create`` -les commandes ``db-create`` et ``db-init`` afin de completer la creation de -votre instance en une seule commande. - -Si vous decidez de ne pas le faire lorsque ``cubicweb-ctl create`` vous le -propose, alors n'oubliez pas de lancer ces commandes (``cubicweb-ctl db-create``, -``cubicweb-ctl db-init`` ) par la suite, sinon -votre installation ne sera pas complete. - - -Creation d'une instance a partir d'une nouveau cube -``````````````````````````````````````````````````` - -Creez avant tout votre nouveau cube :: - - cubicweb-ctl newcube - -Cette commande va creer un nouveau cube dans ``/path/to/forest/cubicweb/cubes/``. - - diff -r c243c0f65f17 -r 2b3fa6fb647b doc/book/fr/03-04-mercurial.fr.txt --- a/doc/book/fr/03-04-mercurial.fr.txt Thu Oct 14 00:01:04 2010 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,112 +0,0 @@ -.. -*- coding: utf-8 -*- - -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/ diff -r c243c0f65f17 -r 2b3fa6fb647b doc/book/fr/03-XX-external_resources.fr.txt --- a/doc/book/fr/03-XX-external_resources.fr.txt Thu Oct 14 00:01:04 2010 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,135 +0,0 @@ -.. -*- coding: utf-8 -*- - - -Les ressources externes -======================= - -Les ressources externes à une application regroupent l'ensemble des fichiers qui seront chargés dans l'entête des pages XHTML générées. -Elles sont donc constituées principalement des feuilles de styles, des scripts javascripts et de certaines ressources graphiques comme l'icône favicon par exemple. - - -Liste des feuilles de styles utilisées par défaut -------------------------------------------------- - -Les fichiers par défaut se trouve dans les sources du framework. En voici le tableau récapitulatif: - -+--------------------------------------+----------------------------------------------------+-----------------------------------+ -| Fichiers | Utilisation | Vues ou widget concernés | -+======================================+====================================================+===================================+ -| web/data/cubicweb.acl.css | formulaires pour le contrôle aux accès | editgroups, security | -| web/data/cubicweb.calendar.css | calendriers | onemonthcal, oneweekcal | -| web/data/cubicweb.calendar_popup.css | popup calendriers | DateWidget | -| web/data/cubicweb.css | gabarit principal de l'application | | -| web/data/cubicweb.facets.css | surcharge du `MIT Simile Exhibit Web Widgets`_ | filter_box | -| web/data/cubicweb.form.css | formulaires | creation, inline-creation, copya, | -| | | inline-edition, edition, muledit | -| web/data/cubicweb.html_tree.css | style pour les widgets d'arborescence | | -| web/data/cubicweb.ie.css | dédié aux comportements de Internet Explorer | | -| web/data/cubicweb.iprogress.css | style pour les widgets d'avancement | | -| web/data/cubicweb.login.css | page et popup d'authentification | logform | -| web/data/cubicweb.mailform.css | style utilisé dans les formulaires d'envoi de mail | | -| web/data/cubicweb.preferences.css | style pour la page des préférences utilisateurs | systemepropertiesform | -| web/data/cubicweb.print.css | style dédié à l'impression | | -| web/data/cubicweb.schema.css | style dédié au schéma de l'application | | -| web/data/cubicweb.suggest.css | surcharge utilisée pour les suggestions | | -| web/data/cubicweb.tablesorter.css | surcharge pour le tri dans les tableau | | -| web/data/cubicweb.tableview.css | surcharge pour le tri sélectif | | -| web/data/cubicweb.timetable.css | style pour le widget Timetable | timetable | -| web/data/jquery.autocomplete.css | surcharge pour le widget `jQuery autocompleter`_ | | -| web/data/jquery.treeview.css | surcharge pour le widget `jQuery treeview`_ | | -| web/data/pygments.css | style pour la coloration des blocs de code | | -| web/data/timeline-bundle.css | surcharge du `MIT Simile Timeline Web Widgets`_ | TimelineWidget | -| web/data/ui.tabs.css | surcharge pour le widget Tabs de `jQuery UI`_ | | -+--------------------------------------+----------------------------------------------------+-----------------------------------+ - -.. _MIT Simile Exhibit Web Widgets: http://code.google.com/p/simile-widgets/wiki/Exhibit -.. _MIT Simile Timeline Web Widgets: http://code.google.com/p/simile-widgets/wiki/Timeline -.. _jQuery autocompleter: http://www.dyve.net/jquery/?autocomplete -.. _jQuery treeview: http://plugins.jquery.com/project/treeview -.. _jQuery UI: http://docs.jquery.com/UI - -D'une manière générale, si vous réutiliser un nom de fichier existant, vous écrasez le contenu du fichier d'origine. - - -Changer les feuilles de styles ------------------------------- - -Configuration statique -~~~~~~~~~~~~~~~~~~~~~~ -Dans les sources de votre nouveau cube, vous devez éditer le fichier *data/external_resources* et définir la variable de configuration: - - # CSS stylesheets to include in HTML headers - # uncomment the line below to use template specific stylesheet - STYLESHEETS = DATADIR/cubicweb.css - -Les styles sont définis dans le fichier external_resources par 3 variables: - -- la variable STYLESHEETS est défine pour tous les types de médias -- la variable STYLESHEETS_PRINT sont les styles applicables pour l'impression -- la variable IE_STYLESHEETS s'appliquent uniquement aux versions d'Internet Explorer - -En copiant le fichier d'origine **cubicweb.css**, il est alors possible de modifier le gabarit de base du framework CubicWeb. -Il est également possible de réutiliser le fichier d'origine. - -En créant un nouveau fichier **cubes.(le_nom_du_cube).css** dans le répertoire **data/** et en ajoutant une directive css @import, il est possible de réutiliser les styles définis par défaut: - - @import url("cubicweb.css"); - - -Chargement dynamique de feuilles de style dans vos vues -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Il est possible de charger des css spécifiques pour une vue par l'utilisation de la méthode add_css(): - - self.req.add_css('mon_cube.css') - - -Les ressources graphiques de base ---------------------------------- - -Vous pouvez changer certaines ressources graphiques comme: - -- le logo du site: - - # path to the logo (relative to the application main script, seen as a - # directory, hence .. when you are not using an absolute path) - LOGO = DATADIR/logo.png - -- la 'favicon' du site: - - FAVICON = DATADIR/favicon.ico - -- le logo des flux RSS: - - RSS_LOGO = DATADIR/rss.png - -- l'icône permettant l'appel au widget 'calendrier': - - CALENDAR_ICON = DATADIR/calendar.png - -- l'icône utilisée pour la validation d'une recherche: - - SEARCH_GO = DATADIR/go.png - -- l'icône d'aide en ligne: - - HELP = DATADIR/help.png - - -Ajouter vos scripts javascripts -------------------------------- - -Configuration statique -~~~~~~~~~~~~~~~~~~~~~~ -Vous devez surcharger la variable JAVASCRIPTS dans le fichier *data/external_resources* de votre cube. - -Chargement dynamique de script javascript dans vos vues -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Il est possible de charger vos scripts par la méthode add_js(): - - self.req.add_js('mon_script.js') - - -Problèmes connus ----------------- - -Il est important de noter que la méthode de chargement dynamique ne marche pas avec les widgets Ajax. Vos fichiers devront déjà être au préalable avoir été chargés. diff -r c243c0f65f17 -r 2b3fa6fb647b doc/book/fr/03-setup.fr.txt --- a/doc/book/fr/03-setup.fr.txt Thu Oct 14 00:01:04 2010 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,15 +0,0 @@ -.. -*- coding: utf-8 -*- - -.. _MiseEnPlaceEnv: - -Installation et mise en place d'un environnement `CubicWeb` -=========================================================== - -.. toctree:: - :maxdepth: 1 - - 03-01-installation.fr.txt - 03-02-create-instance.fr.txt - 03-03-cubicweb-ctl.fr.txt - 03-04-mercurial.fr.txt - diff -r c243c0f65f17 -r 2b3fa6fb647b doc/book/fr/04-01-schema-stdlib.fr.txt --- a/doc/book/fr/04-01-schema-stdlib.fr.txt Thu Oct 14 00:01:04 2010 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,70 +0,0 @@ -.. -*- coding: utf-8 -*- - -Schémas prédéfinies dans la librairie -------------------------------------- - -La librairie définit un certain nombre de schémas d'entités nécessaires -au système ou bien couramment utilisées dans les application `cubicweb`. -Vous pouvez bien entendu étendre ces schémas au besoin. - - -Schémas "systèmes" -`````````````````` - -* `CWUser`, utilisateurs du système -* `CWGroup`, groupes d'utilisateurs -* `CWEType`, types d'entité -* `CWRType`, types de relation - -* `State`, état d'un workflow -* `Transition`, transition d'un workflow -* `TrInfo`, enregistrement d'un passage de transition pour une entité - -* `EmailAddress`, adresse électronique, utilisé par le système de notification - pour les utilisateurs et par d'autres schéma optionnels - -* `CWProperty`, utilisé pour configurer l'application -* `CWPermission`, utilisé pour configurer la sécurité de l'application - -* `Card`, fiche documentaire générique -* `Bookmark`, un type d'entité utilisé pour permetter à un utilisateur de - personnaliser ses liens de navigation dans l'application. - - -Composants de la librairie -`````````````````````````` -Une application est construite sur la base de plusieurs composants de base. -Parmi les composants de base disponible, on trouve par exemple : - -* `ecomment`, fournit le type d'entité `Comment` permettant de commenter les - entités du site - -* `emailinglist`, fournit le type d'entité `Mailinglist` regroupant des - informations sur une liste de discussion - -* `efile`, fournit les types d'entités `File` et `Image` utilisés pour - représenter des fichiers (texte ou binaire) avec quelques données - supplémentaires comme le type MIME ou l'encodage le cas échéant (). - -* `elink`, fournit le type d'entité lien internet (`Link`) - -* `eblog`, fournit le type d'entité weblog (`Blog`) - -* `eperson`, fournit le type d'entité personne physique (`Person`) - -* `eaddressbook`, fournit les types d'entités utilisés pour représenter des n° - de téléphone (`PhoneNumber`) et des adresses postales (`PostalAddress`) - -* `eclasstags`, système de classfication à base d'étiquettes (`Tag`) - -* `eclassfolders`, système de classification à base de dossiers hiérarchiques - destinés à créer des rubriques de navigation (`Folder`) - -* `eemail`, gestion d'archives de courriers électroniques (`Email`, `Emailpart`, - `Emailthread`) - -* `ebasket`, gestion de paniers (`Basket`) permettant de regrouper des entités - -Pour déclarer l'utilisation d'un composant, une fois celui-ci installé, ajoutez -le nom du composant à la variable `__use__` du fichier `__pkginfo__.py` de -votre propre composant. diff -r c243c0f65f17 -r 2b3fa6fb647b doc/book/fr/04-02-schema-definition.fr.txt --- a/doc/book/fr/04-02-schema-definition.fr.txt Thu Oct 14 00:01:04 2010 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,361 +0,0 @@ -.. -*- coding: utf-8 -*- - -Définition d'un type d'entité ------------------------------ - -Un type d'entité est définit par une classe python héritant de `EntityType`. Le -nom de la classe correspond au nom du type. Ensuite le corps de la classe -contient la description des attributs et des relations pour ce type d'entité, -par exemple :: - - class Personne(EntityType): - """une personne avec les propriétés et relations nécessaires à mon - application""" - - nom = String(required=True, fulltextindexed=True) - prenom = String(required=True, fulltextindexed=True) - civilite = String(vocabulary=('M', 'Mme', 'Mlle')) - date_naiss = Date() - travaille_pour = SubjectRelation('Company', cardinality='?*') - -* le nom de l'attribut python correspond au nom de l'attribut ou de la relation - dans cubicweb. - -* tout les types de bases sont disponibles nativement : `String`, `Int`, `Float`, - `Boolean`, `Date`, `Datetime`, `Time`, `Byte`. - -* Chaque type d'entité a au moins les méta-relations suivantes : - - - `eid` (`Int`) - - - `creation_date` (`Datetime`) - - - `modification_date` (`Datetime`) - - - `created_by` (`CWUser`) (quel utilisateur a créé l'entité) - - - `owned_by` (`CWUser`) (à qui appartient l'entité, par défaut le - créateur mais pas forcément et il peut exister plusieurs propriétaires) - - - `is` (`CWEType`) - - -* il est également possible de définir des relations dont le type d'entité est - l'objet en utilisant `ObjectRelation` plutôt que `SubjectRelation` - -* le premier argument de `SubjectRelation` et `ObjectRelation` donne - respectivement le type d'entité objet /sujet de la relation. Cela - peut être : - - * une chaine de caractères correspondant à un type d'entité - - * un tuple de chaines de caractères correspondant à plusieurs types d'entité - - * les chaînes de caractères spéciales suivantes : - - - "**" : tout les types d'entité - - "*" : tout les types d'entité non méta - - "@" : tout les types d'entité méta mais non "système" (i.e. servant à la - description du schema en base) - -* il est possible d'utiliser l'attribut possible `meta` pour marquer un type - d'entité comme étant "méta" (i.e. servant à décrire / classifier d'autre - entités) - -* propriétés optionnelles des attributs et relations : - - - `description` : chaine de caractères décrivant un attribut ou une - relation. Par défaut cette chaine sera utilisée dans le formulaire de saisie - de l'entité, elle est donc destinée à aider l'utilisateur final et doit être - marquée par la fonction `_` pour être correctement internationalisée. - - - `constraints` : liste de contraintes devant être respecté par la relation - (c.f. `Contraintes`_) - - - `cardinality` : chaine de 2 caractères spécifiant la cardinalité de la - relation. Le premier caractère donne la cardinalité de la relation sur le - sujet, le 2eme sur l'objet. Quand une relation possède plusieurs sujets ou - objets possibles, la cardinalité s'applique sur l'ensemble et non un à un (et - doit donc à priori être cohérente...). Les valeurs possibles sont inspirées - des expressions régulières : - - * `1`: 1..1 - * `?`: 0..1 - * `+`: 1..n - * `*`: 0..n - - - `meta` : booléen indiquant que la relation est une méta relation (faux par - défaut) - -* propriétés optionnelles des attributs : - - - `required` : booléen indiquant si l'attribut est obligatoire (faux par - défaut) - - - `unique` : booléen indiquant si la valeur de l'attribut doit être unique - parmi toutes les entités de ce type (faux par défaut) - - - `indexed` : booléen indiquant si un index doit être créé dans la base de - données sur cette attribut (faux par défaut). C'est utile uniquement si vous - savez que vous allez faire de nombreuses recherche sur la valeur de cet - attribut. - - - `default` : valeur par défaut de l'attribut. A noter que dans le cas des - types date, les chaines de caractères correspondant aux mots-clés RQL - `TODAY` et `NOW` sont utilisables. - - - `vocabulary` : spécifie statiquement les valeurs possibles d'un attribut - -* propriétés optionnelles des attributs de type `String` : - - - `fulltextindexed` : booléen indiquant si l'attribut participe à l'index plein - texte (faux par défaut) (*valable également sur le type `Byte`*) - - - `internationalizable` : booléen indiquant si la valeur de cet attribut est - internationalisable (faux par défaut) - - - `maxsize` : entier donnant la taille maximum de la chaine (pas de limite par - défaut) - -* propriétés optionnelles des relations : - - - `composite` : chaîne indiquant que le sujet (composite == 'subject') est - composé de ou des objets de la relation. Pour le cas opposé (l'objet est - composé de ou des sujets de la relation, il suffit de mettre 'object' comme - valeur. La composition implique que quand la relation est supprimé (et donc - aussi quand le composite est supprimé), le ou les composés le sont - également. - -Contraintes -``````````` -Par défaut les types de contraintes suivant sont disponibles : - -* `SizeConstraint` : permet de spécifier une taille minimale et/ou maximale sur - les chaines de caractères (cas générique de `maxsize`) - -* `BoundConstraint` : permet de spécifier une valeur minimale et/ou maximale sur - les types numériques - -* `UniqueConstraint` : identique à "unique=True" - -* `StaticVocabularyConstraint` : identique à "vocabulary=(...)" - -* `RQLConstraint` : permet de spécifier une requête RQL devant être satisfaite - par le sujet et/ou l'objet de la relation. Dans cette requête les variables `S` - et `O` sont préféfinies respectivement comme l'entité sujet et objet de la - relation - -* `RQLVocabularyConstraint` : similaire à la précédente, mais exprimant une - contrainte "faible", i.e. servant uniquement à limiter les valeurs apparaissant - dans la liste déroulantes du formulaire d'édition, mais n'empêchant pas une - autre entité d'être séléctionnée - - -Définition d'un type de relation --------------------------------- - -Un type de relation est définit par une classe python héritant de `RelationType`. Le -nom de la classe correspond au nom du type. Ensuite le corps de la classe -contient la description des propriétés de ce type de relation, ainsi -qu'éventuellement une chaine pour le sujet et une autre pour l'objet permettant -de créer des définitions de relations associées (auquel cas il est possibles de -donner sur la classe les propriétés de définition de relation explicitées -ci-dessus), par exemple :: - - class verrouille_par(RelationType): - """relation sur toutes les entités applicatives indiquant que celles-ci sont vérouillées - inlined = True - cardinality = '?*' - subject = '*' - object = 'CWUser' - -En plus des permissions, les propriétés propres aux types de relation (et donc -partagés par toutes les définitions de relation de ce type) sont : - -* `inlined` : booléen contrôlant l'optimisation physique consistant à stocker la - relation dans la table de l'entité sujet au lieu de créer une table spécifique - à la relation. Cela se limite donc aux relations dont la cardinalité - sujet->relation->objet vaut 0..1 ('?') ou 1..1 ('1') - -* `symmetric` : booléen indiquant que la relation est symétrique. i.e. - `X relation Y` implique `Y relation X` - -Dans le cas de définitions de relations simultanée, `sujet` et `object` peuvent -tout deux valoir la même chose que décrite pour le 1er argument de -`SubjectRelation` et `ObjectRelation`. - -A partir du moment où une relation n'est ni mise en ligne, ni symétrique, et -ne nécessite pas de permissions particulières, sa définition (en utilisant -`SubjectRelation` ou `ObjectRelation`) est suffisante. - - -Définition des permissions --------------------------- - -La définition des permissions se fait à l'aide de l'attribut `permissions` des -types d'entité ou de relation. Celui-ci est un dictionnaire dont les clés sont -les types d'accès (action), et les valeurs les groupes ou expressions autorisées. - -Pour un type d'entité, les actions possibles sont `read`, `add`, `update` et -`delete`. - -Pour un type de relation, les actions possibles sont `read`, `add`, et `delete`. - -Pour chaque type d'accès, un tuple indique le nom des groupes autorisés et/ou -une ou plusieurs expressions RQL devant être vérifiées pour obtenir -l'accès. L'accès est donné à partir du moment où l'utilisateur fait parti d'un -des groupes requis ou dès qu'une expression RQL est vérifiée. - -Les groupes standards sont : - -* `guests` - -* `users` - -* `managers` - -* `owners` : groupe virtuel correspondant au propriétaire d'une entité. Celui-ci - ne peut être utilisé que pour les actions `update` et `delete` d'un type - d'entité. - -Il est également possible d'utiliser des groupes spécifiques devant être pour -cela créés dans le precreate de l'application (`migration/precreate.py`). - -Utilisation d'expression RQL sur les droits en écriture -``````````````````````````````````````````````````````` -Il est possible de définir des expressions RQL donnant des droits de -modification (`add`, `delete`, `update`) sur les types d'entité et de relation. - -Expression RQL pour les permissions sur un type d'entité : - -* il faut utiliser la classe `ERQLExpression` - -* l'expression utilisée correspond à la clause WHERE d'une requête RQL - -* dans cette expression, les variables X et U sont des références prédéfinies - respectivement sur l'entité courante (sur laquelle l'action est vérifiée) et - sur l'utilisateur ayant effectué la requête - -* il est possible d'utiliser dans cette expression les relations spéciales - "has__permission" dont le sujet est l'utilisateur et l'objet une - variable quelquonque, signifiant ainsi que l'utilisateur doit avoir la - permission d'effectuer l'action sur la ou les entités liées cette - variable - -Pour les expressions RQL sur un type de relation, les principes sont les mêmes -avec les différences suivantes : - -* il faut utiliser la classe `RRQLExpression` dans le cas d'une relation non - finale - -* dans cette expression, les variables S, O et U sont des références - prédéfinies respectivement sur le sujet et l'objet de la relation - courante (sur laquelle l'action est vérifiée) et sur l'utilisateur - ayant effectué la requête - -* On peut aussi définir des droits sur les attributs d'une entité (relation non - finale), sachant les points suivants : - - - pour définir des expressions rql, il faut utiliser la classe `ERQLExpression` - dans laquelle X représentera l'entité auquel appartient l'attribut - - - les permissions 'add' et 'delete' sont équivalentes. En pratique seul - 'add'/'read' son pris en considération - - -En plus de cela, le type d'entité `CWPermission` de la librairie standard permet -de construire des modèles de sécurités très complexes et dynamiques. Le schéma -de ce type d'entité est le suivant : :: - - - class CWPermission(MetaEntityType): - """entity type that may be used to construct some advanced security configuration - """ - name = String(required=True, indexed=True, internationalizable=True, maxsize=100) - require_group = SubjectRelation('CWGroup', cardinality='+*', - description=_('groups to which the permission is granted')) - require_state = SubjectRelation('State', - description=_("entity'state in which the permission is applyable")) - # can be used on any entity - require_permission = ObjectRelation('**', cardinality='*1', composite='subject', - description=_("link a permission to the entity. This " - "permission should be used in the security " - "definition of the entity's type to be useful.")) - - -Exemple de configuration extrait de *jpl* :: - - ... - - 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 - -Cette configuration suppose indique qu'une entité `CWPermission` de nom -"add_version" peut-être associée à un projet et donner le droit de créer des -versions sur ce projet à des groupes spécifiques. Il est important de noter les -points suivants : - -* dans ce cas il faut protéger à la fois le type d'entité "Version" et la - relation liant une version à un projet ("version_of") - -* du fait de la généricité du type d'entité `CWPermission`, il faut effectuer - l'unification avec les groupes et / ou les états le cas échéant dans - l'expression ("U in_group G, P require_group G" dans l'exemple ci-dessus) - - -Utilisation d'expression RQL sur les droits en lecture -`````````````````````````````````````````````````````` -Les principes sont les mêmes mais avec les restrictions suivantes : - -* on ne peut de `RRQLExpression` sur les types de relation en lecture - -* les relations spéciales "has__permission" ne sont pas utilisables - - -Note sur l'utilisation d'expression RQL sur la permission 'add' -``````````````````````````````````````````````````````````````` -L'utilisation d'expression RQL sur l'ajout d'entité ou de relation pose -potentiellement un problème pour l'interface utilisateur car si l'expression -utilise l'entité ou la relation à créer, on est pas capable de vérifier les -droits avant d'avoir effectué l'ajout (noter que cela n'est pas un problème coté -serveur rql car la vérification des droits est effectuée après l'ajout -effectif). Dans ce cas les méthodes de vérification des droits (check_perm, -has_perm) peuvent inidquer qu'un utilisateur n'a pas le droit d'ajout alors -qu'il pourrait effectivement l'obtenir. Pour palier à ce soucis il est en général -nécessaire dans tel cas d'utiliser une action reflétant les droits du schéma -mais permettant de faire la vérification correctement afin qu'elle apparaisse -bien le cas échéant. - -Mise à jour du schema -````````````````````` - -Il faut ensuite lancer son cubicweb en mode shell :: - - cubicweb-ctl shell moninstance - -Et taper :: - - add_entity_type('Personne') - -Et on relance l'application! diff -r c243c0f65f17 -r 2b3fa6fb647b doc/book/fr/04-define-schema.fr.txt --- a/doc/book/fr/04-define-schema.fr.txt Thu Oct 14 00:01:04 2010 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,21 +0,0 @@ -.. -*- coding: utf-8 -*- - -Définition du modèle de données (*schéma*) -========================================== - -Le schéma est l'élément central d'une application d'CubicWeb, définissant le modèle -de données manipulé. Il est généralement défini à partir de type d'entités -existants dans la librairie et d'autres spécifiques, généralement décrites dans -un ou plusieurs fichiers python dans le sous-répertoire `schema` du modèle. - -A ce niveau il est important de noter la différence entre type de relation et -définition de relation : un type de relation est uniquement un nom de relation -avec éventuellement quelques propriétés supplémentaires (voir plus bas), alors -qu'une définition de relation est un triplet complet " - ". Eventuellement un type de relation -sera créé implicitement si aucun n'est associé à une définition de relation du -schema. - -.. include:: 04-01-schema-stdlib.fr.txt -.. include:: 04-02-schema-definition.fr.txt - diff -r c243c0f65f17 -r 2b3fa6fb647b doc/book/fr/05-01-views-stdlib.fr.txt --- a/doc/book/fr/05-01-views-stdlib.fr.txt Thu Oct 14 00:01:04 2010 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -.. -*- coding: utf-8 -*- - -Vues prédéfinies dans la librairie ----------------------------------- -Un certain nombre de vues sont utilisées pour construire l'interface web, qui -s'appliquent à une ou plusieurs entités. On les distingue par leur identifiant, -et les principales sont : - -:primary: - vue principale pour une entité, elle est appelée par défaut lorsqu'il n'y a - qu'un seul élément correspondant à la recherche. Cette vue est censée - afficher le maximum d'informations à propos de l'objet. -:secondary: - vue secondaire d'une entité. Par défaut, Elle affiche les deux premiers - attributs de l'entité sous la forme d'un lien cliquable amenant sur la vue - primaire. -:oneline: - similaire à la vue `secondary`, mais appelée dans des cas où l'on désire que - la vue tient sur une ligne, ou de manière générale juste avoir une vue plus - abbrégée. Par défaut, cette vue utilise le paramètre de configuration - `MAX_LINE_CHAR` pour contrôler la taille du résultat. -:text: - similaire à la vue `oneline`, mais ne devant pas contenir de html. -:incontext, outofcontext: - similaire à la vue `secondary`, mais appelé si l'entité est considérée comme - en dehors ou dans son contexte. Par défault renvoie respectivement le - résultat de `textincontext` et `textoutofcontext` entouré par un lien - permettant d'accéder à la vue primaire de l'entité -:textincontext, textoutofcontext: - similaire à la vue `text`, mais appelé si l'entité est considérée comme - en dehors ou dans son contexte. Par défault renvoie respectivement le - résultat des méthodes `.dc_title` et `.dc_long_title` de l'entité -:list: - crée une liste html (
    ) et appelle la vue `listitem` pour chaque entité -:listitem: - redirige par défaut vers la vue `outofcontext` -:rss: - crée unvue RSS/XML et appelle la vue `rssitem` pour chaque entité -:rssitem: - crée unvue RSS/XML pour une entité à partir des résultats renvoyés par les - méthodes dublin core de l'objet (`dc_*`) - -Vues de départ : - -:index: - page d'acceuil -:schema: - affiche le schéma de l'application - -Vues particulières : - -:noresult: - appelé si le result set est vide -:finall: - affiche la valeur de la cellule sans transformation (dans le cas d'une - entité non finale, on voit son eid). Appelable sur n'importe quel result - set. -:table: - crée une table html () et appelle la vue `cell` pour chaque cellule - du résultat. Appelable sur n'importe quel result set. -:cell: - par défaut redirige sur la vue `final` si c'est une entité finale - ou sur la vue `outofcontext` sinon -:null: - vue toujours appelable et ne retournant rien diff -r c243c0f65f17 -r 2b3fa6fb647b doc/book/fr/05-define-views.fr.txt --- a/doc/book/fr/05-define-views.fr.txt Thu Oct 14 00:01:04 2010 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,247 +0,0 @@ -.. -*- coding: utf-8 -*- - -.. _DefinitionVues: - -Définition de vues -================== - -Les classes de base des vues ----------------------------- - -La class `View` (`cubicweb.common.view`) -```````````````````````````````````````` -Un vue écrit dans son flux de sortie via son attribut `w` (`UStreamIO`). - -L'interface de base des vues est la suivante : - -* `dispatch(**context)`, appelle ("rend") la vue en appellent `call` ou - `cell_call` en fonction des arguments passé -* `call(**kwargs)`, appelle la vue pour un result set complet ou nul -* `cell_call(row, col, **kwargs)`, appelle la vue pour une cellule donnée d'un - result set -* `url()`, retourne l'url permettant d'obtenir cette vue avec le result set en - cours -* `view(__vid, rset, __fallback_vid=None, **kwargs)`, appelle la vue - d'identificant `__vid` sur le result set donné. Il est possible de données un - identificant de vue de "fallback" qui sera utilisé si la vue demandée n'est - pas applicable au result set - -* `wview(__vid, rset, __fallback_vid=None, **kwargs)`, pareil que `view` mais - passe automatiquement le flux en argument - -* `html_headers()`, retourne une liste d'en-tête HTML à placer par le template - principal - -* `page_title()`, retourne le titre à utiliser dans l'en tête HTML `title` - -* `creator(eid)`, retourne l'eid et le login du créateur de l'entité ayant - l'eid passé en argument - -Autres classes de base : - -* `EntityView`, vue s'appliquant à aux lignes ou cellule contenant une entité - (eg un eid) -* `StartupView`, vue de départ n'ayant pas besoin de result set -* `AnyRsetView`, vue s'appliquant à n'importe quelle result set - -Le mecanisme de selection de vues ---------------------------------- - -Pour un identifiant de vue donne, plusieurs vues peuvent etre definies. -`CubicWeb` utilise un selecteur qui permet de calculer un score et d'identifier -la vue la plus appropriee a appliquer dans le contexte. La librairie du selecteur -se trouve dans ``cubicweb.common.selector`` et une librairie des methodes utilisees -pour calculer les scores est dans ``cubicweb.vregistry.vreq``. - -[FROM-LAX-BOOK] - -Tip: when modifying views, you do not need to restart the local -server. Just save the file in your editor and reload the page in your -browser to see the changes. - -With `LAX`, views are defined by Python classes. 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 - -`LAX` provides a lot of standard views, for a complete list, you -will have to read the code in directory ``ginco/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.rset.get_entity(row, col) - 09. self.w(u'

    %s

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

    published on %s in category %s

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

    %s

    ' % entity.text) - -The above source code defines a new primary view (`line 03`) for -``BlogEntry`` (`line 05`). - -Since views are applied to 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.fr.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.rset.get_entity(row, col) - 07. self.w(u'

    %s

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

    %s

    ' % entity.description) - 09. rset = self.req.execute('Any E WHERE E entry_of B, B eid "%s"' % entity.eid) - 10. self.wview('primary', rset) - -In the above source code, `lines 01-08` are similar to the previous -view we defined. - -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.fr.png - :alt: a blog and all its entries - -**Before we move forward, remember that the selection/view principle is -at the core of `LAX`. 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 ginco.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] - -Les templates ou patron ------------------------ - -Les patrons (ou *template*) sont des cas particulier de vue ne dépendant a -priori pas d'un result set. La classe de base `Template` (`cubicweb.common.view`) -est une classe dérivée de la classe `View`. - -Pour construire une page HTML, un *template principal* est utilisé. Généralement -celui possédant l'identifiant 'main' est utilisé (ce n'est pas le cas lors -d'erreur dans celui-ci ou pour le formulaire de login par exemple). Ce patron -utilise d'autres patrons en plus des vues dépendants du contenu pour générer la -page à renvoyer. - -C'est ce template qui est chargé : - -1. d'éxécuter la requête RQL des données à afficher le cas échéant -2. éventuellement de déterminer la vue à utiliser pour l'afficher si non - spécifiée -3. de composer la page à retourner - - -Le patron principal par défaut (`cubicweb.web.views.basetemplates.TheMainTemplate`) ------------------------------------------------------------------------------------ - -Le template principal par défaut construit la page selon la décomposition -suivante : - -.. image:: images/main_template_layout.png - -Le rectancle contenant le `view.dispatch()` représente l'emplacement où est -inséré la vue de contenu à afficher. Les autres représentent des sous-templates -appelé pour construire la page. Les implémentations par défaut de tout ces -templates sont dans le module `cubicweb.web.views.basetemplates`. Vous pouvez -évidemment surcharger l'un des sous-templates pour modifier l'aspect visuel -d'une partie désirée de la page. - -On peut également contrôler certains comportements du template principal à -l'aide des paramètres de formulaire suivante : - -* `__notemplate`, si présente (quelque soit la valeur associée), seule la vue de - contenu est renvoyée -* `__force_display`, si présente et contient une valeur non nulle, pas de - navigation quelque soit le nombre d'entités à afficher -* `__method`, si le result set à afficher ne contient qu'une entité et que ce - paramètre est spécifié, celui-ci désigne une méthode à appeler sur l'entité - en lui donnant en argument le dictionnaire des paramètres de formulaire, avant - de reprendre le comportement classique (s'insère entre les étapes 1. et - 2. décrites ci-dessus) - - -.. include:: 05-01-views-stdlib.fr.txt - - -Vues xml, binaires... ---------------------- -Pour les vues générants autre que du html (une image générée dynamiquement par -exemple), et qui ne peuvent donc généralement pas être incluse dans la page -HTML générée par le template principal (voir ci-dessus), il faut : - -* placer l'attribut `templatable` de la classe à `False` -* indiquer via l'attribut `content_type` de la classe le type MIME généré par la - vue 'application/octet-stream' - -Pour les vues générants un contenu binaire (une image générée dynamiquement par -exemple), il faut également placer l'attribut `binary` de la classe à `True` (ce -qui implique `templatable == False` afin que l'attribut `w` de la vue soit -remplacé par un flux binaire plutôt que unicode. - - -Quelques trucs (X)HTML à respecter ----------------------------------- -Certains navigateurs (dont firefox) n'aime pas les `
    ` vides (par vide -j'entend sans contenu dans la balise, il peut y avoir des attributs), faut -toujours mettre `
    ` même s'il n'y a rien dedans, et non `
    `. diff -r c243c0f65f17 -r 2b3fa6fb647b doc/book/fr/06-define-workflows.fr.txt --- a/doc/book/fr/06-define-workflows.fr.txt Thu Oct 14 00:01:04 2010 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,129 +0,0 @@ -.. -*- coding: utf-8 -*- - -Définition de workflow -====================== - -Avant-propos ------------- - -Un worflow décrit comment les entités vont être utilisés à travers différents états. Nous avons donc pour un workflow donné un ensemble d'états, un "graphe de transition" c'est-à-dire la liste des transitions possibles d'un état à un autre. - -Nous allons définir ici un simple workflow pour l'exemple du blog avec seulement deux états: `en attente` et `publié`. Il est nécessaire d'avoir préalablement créé une application simple *CubicWeb* en dix minutes (voir :ref:`BlogFiveMinutes`). - -Mise en place du workflow -------------------------- - -Nous allons créer un workflow pour contrôler la qualité des BlogEntry soumis à l'instance. Lorsque un BlogEntry est créé par un utilisateur, son état doit être `en attente`. Pour être visible par tous, il doit être ensuite mis à l'état `publié`. Pour le changement d'état d'`en attente` à `publié`, nous avons besoin d'une transition que nous appellerons `approuve_blogentry`. - -Un état BlogEntry ne doit pas pouvoir être modifiable par les utilisateurs. Nous allons donc créé un groupe de modération `moderateurs` et ce groupe aura les permissions idoines pour publier un BlogEntry. - -Il existe deux manières de créer un workflow: depuis l'interface utilisateur ou en le définissant dans le fichier ``migration/postcreate.py``. -Ce script est exécuté à chaque lancement de la commande ``cubicweb-ctl db-init``. -Nous encourageons vivement la création dans ``migration/postcreate.py`` que nous allons vous montrer ici. Lire `Sous le capot`_ pour en comprendre les raisons. - -L'état d'une entité est sauvegardé par l'attribut `in_state` qui peut être ajouté à votre schéma d'entité par deux façons: - -* héritage direct en utilisant la classe `cubicweb.schema.WorkflowableEntityType` -* par délégation en utilisant `cubicweb.schema.make_worflowable` (utilisable comme un décorateur également) - -Pour notre exemple de BlogEntry, nous devons avoir: - -.. sourcecode:: python - - from cubicweb.schema import WorkflowableEntityType - - class BlogEntry(EntityType, WorkflowableEntityType): - ... - - -Création des états, transitions et les permissions de groupe -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Le script ``postcreate.py`` est exécuté dans un environnement spécial où plusieurs primitives *CubicWeb* peuvent être utilsées. -Elles sont toutes définies dans ``class ServerMigrationHelper``. -Nous allons maintenant voir dans le prochain example celles utilisées pour créer un workflow. - -Pour définir notre workflow pour BlogDemo, veuillez ajouter les lignes suivantes au script ``migration/postcreate.py``: - -.. sourcecode:: python - - _ = unicode - - moderators = add_entity('CWGroup', name=u"modérateurs") - -Cela va ajouter le groupe utilisateur `moderators`. - -.. sourcecode:: python - - wf = add_workflow(u'une description succincte de votre workflow', 'BlogEntry') - -Ceci va premièrement instancier un nouvel objet workflow avec une description sommaire mais pertinente et le type d'entité concerné (un tuple pour être utilisé pour des valeurs multiples). - -.. sourcecode:: python - - submitted = wf.add_state(_('submitted'), initial=True) - published = wf.add_state(_('published')) - -``add_state`` attend comme premier argument le nom de l'état que vous voulez créer et un argument optionnel pour signifier si c'est l'état initial supposé pour ce type d'entité. - -.. sourcecode:: python - - wf.add_transition(_('approuve_blogentry'), (submitted,), published, ('moderators', 'managers'),) - -``add_transition`` attend: - - * comme premier argument le nom de la transition - * ensuite la liste des états pour lesquels les transitions peuvent être tirées, - * l'état attendu en fin de transition, - * et les permissions - (c'est-à-dire la liste des goupes utilisateurs qui peuvnet appliquer la transition; l'utilisateur devant appartenir à l'un des groupes listés pour être autoriser à exécuter l'action). - -.. sourcecode:: python - - - checkpoint() - -.. note:: - 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. - -En complément de condition sur des groupes utilisateur dont l'utilisateur doit appartenir à l'in d'entre eux, vous pouvez utiliser une RQL condition. -Dans ce cas, l'utilisateur peut seulement exécuter une action si les deux conditions sont satisfaites. - -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 - -.. image:: ../../images/03-transitions-view.en.png - -Vous pouvez remarqué que dans la boîte d'action d'un BlogEntry, l'état est maintenant listé ainsi que les possibles transitions définis pour l'état en cours dans le workflow. Les transitions ne sont seulement affichées pour les utilisateurs ayant les bonnes permissions. -Dans notre exemple, la transition `approuve_blogentry` sera seulement affichée pour les utilisateurs appartenant au groupe `moderators` or `managers`. - - -Sous le capot -~~~~~~~~~~~~~ - -Un workflow est une collection d'entités de type `State`` et ``Transition`` qui sont des types d'entités standards de *CubicWeb*. - -Par exemple, les lignes précédentes: - -.. sourcecode:: python - - submitted = wf.add_state(_('en attente'), initial=True) - published = wf.add_state(_('publié')) - -vont créé deux entités de type ``State``, l'une avec le nom 'submitted' et l'autre avec le nom 'published'. Tandis que: - -.. sourcecode:: python - - wf.add_transition(_('approuve_blogentry'), (submitted,), published, ('moderators', 'managers'),) - -va créé une entité de type ``Transition`` avec le nom `approuve_blogentry` qui sera relié aux entités ``State`` créées précédemment. - -Dès lors, nous pouvons utiliser l'interface d'administration pour ces opérations. Mais ce n'est pas recommandé à cause de la complexité superflue et du fait que ces changements ne seront locaux qu'à cette instance. - -En effet, si vous créez les états et les transitions à travers l'interface utilisateur, la prochaine initialisation de la base de données vous oblige à recréer toutes les entités. -L'interface utilisateur devrait être seulement connu par vous pour la visualisation des états et transitions, mais ce n'est pas celle appropriée pour définir vos workflows applicatifs. - - diff -r c243c0f65f17 -r 2b3fa6fb647b doc/book/fr/07-01-define-entities.fr.txt --- a/doc/book/fr/07-01-define-entities.fr.txt Thu Oct 14 00:01:04 2010 +0200 +++ /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_` 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. diff -r c243c0f65f17 -r 2b3fa6fb647b doc/book/fr/07-data-as-objects.fr.txt --- a/doc/book/fr/07-data-as-objects.fr.txt Thu Oct 14 00:01:04 2010 +0200 +++ /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 :: - - , ,