Binary file doc/book/en/.static/cubicweb.png has changed
Binary file doc/book/en/.static/logilab.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/.static/sphinx-default.css Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,860 @@
+/**
+ * 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;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/.templates/layout.html Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,195 @@
+{%- block doctype -%}
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+{%- endblock %}
+{%- set reldelim1 = reldelim1 is not defined and ' »' or reldelim1 %}
+{%- set reldelim2 = reldelim2 is not defined and ' |' or reldelim2 %}
+{%- macro relbar %}
+ <div class="related">
+ <h3>Navigation</h3>
+ <ul>
+ {%- for rellink in rellinks %}
+ <li class="right" {% if loop.first %}style="margin-right: 10px"{% endif %}>
+ <a href="{{ pathto(rellink[0]) }}" title="{{ rellink[1]|striptags }}"
+ accesskey="{{ rellink[2] }}">{{ rellink[3] }}</a>
+ {%- if not loop.first %}{{ reldelim2 }}{% endif %}</li>
+ {%- endfor %}
+ {%- block rootrellink %}
+ <li><a href="{{ pathto('index') }}">{{ shorttitle }}</a>{{ reldelim1 }}</li>
+ {%- endblock %}
+ {%- for parent in parents %}
+ <li><a href="{{ parent.link|e }}" accesskey="U">{{ parent.title }}</a>{{ reldelim1 }}</li>
+ {%- endfor %}
+ {%- block relbaritems %}{% endblock %}
+ </ul>
+ </div>
+{%- endmacro %}
+{%- macro sidebar %}
+ {%- if builder != 'htmlhelp' %}
+ <div class="sphinxsidebar">
+ <div class="sphinxsidebarwrapper">
+ {%- block sidebarlogo %}
+ {%- if logo %}
+ <p class="logo"><img class="logo" src="{{ pathto('_static/' + logo, 1) }}" alt="Logo"/></p>
+ {%- endif %}
+ {%- endblock %}
+ {%- block sidebartoc %}
+ {%- if display_toc %}
+ <h3>Table Of Contents</h3>
+ {{ toc }}
+ {%- endif %}
+ {%- endblock %}
+ {%- block sidebarrel %}
+ {%- if prev %}
+ <h4>Previous topic</h4>
+ <p class="topless"><a href="{{ prev.link|e }}" title="previous chapter">{{ prev.title }}</a></p>
+ {%- endif %}
+ {%- if next %}
+ <h4>Next topic</h4>
+ <p class="topless"><a href="{{ next.link|e }}" title="next chapter">{{ next.title }}</a></p>
+ {%- endif %}
+ {%- endblock %}
+ {%- if sourcename %}
+ <h3>This Page</h3>
+ <ul class="this-page-menu">
+ {%- if builder == 'web' %}
+ <li><a href="#comments">Comments ({{ comments|length }} so far)</a></li>
+ <li><a href="{{ pathto('@edit/' + sourcename)|e }}">Suggest Change</a></li>
+ <li><a href="{{ pathto('@source/' + sourcename)|e }}">Show Source</a></li>
+ {%- elif builder == 'html' %}
+ <li><a href="{{ pathto('_sources/' + sourcename, true)|e }}">Show Source</a></li>
+ {%- endif %}
+ </ul>
+ {%- endif %}
+ {%- if customsidebar %}
+ {{ rendertemplate(customsidebar) }}
+ {%- endif %}
+ {%- block sidebarsearch %}
+ {%- if pagename != "search" %}
+ <h3>{{ builder == 'web' and 'Keyword' or 'Quick' }} search</h3>
+ <form class="search" action="{{ pathto('search') }}" method="get">
+ <input type="text" name="q" size="18" /> <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ {%- if builder == 'web' %}
+ <p style="font-size: 90%">Enter a module, class or function name.</p>
+ {%- endif %}
+ {%- endif %}
+ {%- endblock %}
+ </div>
+ </div>
+ {%- endif %}
+{%- endmacro -%}
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ {%- if builder != 'htmlhelp' %}
+ {%- set titlesuffix = " — " + docstitle %}
+ {%- endif %}
+ <title>{{ title|striptags }}{{ titlesuffix }}</title>
+ {%- if builder == 'web' %}
+ <link rel="stylesheet" href="{{ pathto('index') }}?do=stylesheet{%
+ if in_admin_panel %}&admin=yes{% endif %}" type="text/css" />
+ {%- for link, type, title in page_links %}
+ <link rel="alternate" type="{{ type|e(true) }}" title="{{ title|e(true) }}" href="{{ link|e(true) }}" />
+ {%- endfor %}
+ {%- else %}
+ <link rel="stylesheet" href="{{ pathto('_static/' + style, 1) }}" type="text/css" />
+ <link rel="stylesheet" href="{{ pathto('_static/pygments.css', 1) }}" type="text/css" />
+ {%- endif %}
+ {%- if builder != 'htmlhelp' %}
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '{{ pathto("", 1) }}',
+ VERSION: '{{ release }}',
+ COLLAPSE_MODINDEX: false,
+ FILE_SUFFIX: '{{ file_suffix }}'
+ };
+ </script>
+ <script type="text/javascript" src="{{ pathto('_static/jquery.js', 1) }}"></script>
+ <script type="text/javascript" src="{{ pathto('_static/interface.js', 1) }}"></script>
+ <script type="text/javascript" src="{{ pathto('_static/doctools.js', 1) }}"></script>
+ {%- if use_opensearch %}
+ <link rel="search" type="application/opensearchdescription+xml"
+ title="Search within {{ docstitle }}"
+ href="{{ pathto('_static/opensearch.xml', 1) }}"/>
+ {%- endif %}
+ {%- if favicon %}
+ <link rel="shortcut icon" href="{{ pathto('_static/' + favicon, 1) }}"/>
+ {%- endif %}
+ {%- endif %}
+{%- block rellinks %}
+ {%- if hasdoc('about') %}
+ <link rel="author" title="About these documents" href="{{ pathto('about') }}" />
+ {%- endif %}
+ <link rel="contents" title="Global table of contents" href="{{ pathto('contents') }}" />
+ <link rel="index" title="Global index" href="{{ pathto('genindex') }}" />
+ <link rel="search" title="Search" href="{{ pathto('search') }}" />
+ {%- if hasdoc('copyright') %}
+ <link rel="copyright" title="Copyright" href="{{ pathto('copyright') }}" />
+ {%- endif %}
+ <link rel="top" title="{{ docstitle }}" href="{{ pathto('index') }}" />
+ {%- if parents %}
+ <link rel="up" title="{{ parents[-1].title|striptags }}" href="{{ parents[-1].link|e }}" />
+ {%- endif %}
+ {%- if next %}
+ <link rel="next" title="{{ next.title|striptags }}" href="{{ next.link|e }}" />
+ {%- endif %}
+ {%- if prev %}
+ <link rel="prev" title="{{ prev.title|striptags }}" href="{{ prev.link|e }}" />
+ {%- endif %}
+{%- endblock %}
+{%- block extrahead %}{% endblock %}
+ </head>
+ <body>
+
+{% block logilablogo %}
+<div class="logilablogo">
+ <a class="logogo" href="http://www.cubicweb.org"><img border="0" src="{{ pathto('_static/cubicweb.png', 1) }}"/></a>
+ </div>
+{% endblock %}
+
+{%- block relbar1 %}{{ relbar() }}{% endblock %}
+
+{%- block sidebar1 %}{# possible location for sidebar #}{% endblock %}
+
+{%- block document %}
+ <div class="document">
+ <div class="documentwrapper">
+ {%- if builder != 'htmlhelp' %}
+ <div class="bodywrapper">
+ {%- endif %}
+ <div class="body">
+ {% block body %}{% endblock %}
+ </div>
+ {%- if builder != 'htmlhelp' %}
+ </div>
+ {%- endif %}
+ </div>
+{%- endblock %}
+
+{%- block sidebar2 %}{{ sidebar() }}{% endblock %}
+ <div class="clearer"></div>
+ </div>
+
+{%- block relbar2 %}{{ relbar() }}{% endblock %}
+
+{%- block footer %}
+ <div class="footer">
+ {%- if hasdoc('copyright') %}
+ © <a href="{{ pathto('copyright') }}">Copyright</a> {{ copyright }}.
+ {%- else %}
+ © Copyright {{ copyright }}.
+ {%- endif %}
+ {%- if last_updated %}
+ Last updated on {{ last_updated }}.
+ {%- endif %}
+ {%- if show_sphinx %}
+ Created using <a href="http://sphinx.pocoo.org/">Sphinx</a>.
+ {%- endif %}
+ </div>
+{%- endblock %}
+ </body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/01-introduction.en.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,343 @@
+.. -*- 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.en.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.en.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.en.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.en.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.en.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.en.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'<h1>%s</h1>' % html_escape(entity.dc_title()))
+
+ def content_format(self, entity):
+ return entity.view('reledit', rtype='content_format')
+
+ def cell_call(self, row, col):
+ entity = self.entity(row, col)
+
+ # display entity attributes with prefixes
+ self.w(u'<h1>%s</h1>' % entity.title)
+ self.w(u'<p>published on %s</p>' % entity.publish_date.strftime('%Y-%m-%d'))
+ self.w(u'<p>%s</p>' % entity.content)
+
+ # display relations
+ siderelations = []
+ if self.main_related_section:
+ self.render_entity_relations(entity, siderelations)
+
+.. note::
+ 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.en.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é.
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/02-foundation.en.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,431 @@
+.. -*- 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 (`EProperty`)
+ * 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/03-01-bis-installation.en.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,79 @@
+.. -*- coding: utf-8 -*-
+
+.. _installationGAE:
+
+Installation de `CubicWeb` pour GoogleAppEngine
+===============================================
+
+Qu'est-ce que `LAX` ?
+=======================
+
+`LAX` (Logilab Appengine eXtension) est un framework d'application
+web basé sur `Google AppEngine`.
+
+`LAX` est un portage de la partie web de la plate-forme applicative
+développée par Logilab depuis 2001. Cette plate-forme publie des
+données tirées de bases SQL, d'annuaires LDAP et de systèmes de
+gestion de version. En avril 2008, elle a été portée pour fonctionner
+sur le "datastore" de `Google AppEngine`.
+
+XXX: faire un parallèle entre Django/GAE et LAX/GAE
+
+
+Téléchargement des sources
+==========================
+
+- Les sources de `Google AppEngine` peuvent être récupérées à l'adresse
+ suivante : http://code.google.com/appengine/downloads.html
+
+- Les sources de `LAX` se trouvent à l'adresse suivante :
+ http://lax.logilab.org/
+
+
+Installation
+============
+
+Une fois décompactée, l'archive `lax-0.1.0-alpha.tar.gz`, on obtient
+l'arborescence suivante::
+
+ .
+ |-- app.yaml
+ |-- custom.py
+ |-- data
+ |-- ginco/
+ |-- i18n/
+ |-- logilab/
+ |-- main.py
+ |-- mx/
+ |-- rql/
+ |-- schema.py
+ |-- simplejson/
+ |-- tools/
+ | |-- generate_schema_img.py
+ | `-- i18ncompile.py
+ |-- views.py
+ |-- yams/
+ `-- yapps/
+
+
+On retrouve le squelette d'une application web de `Google AppEngine`
+(fichiers ``app.yaml``, ``main.py`` en particulier) avec les dépendances
+supplémentaires nécessaires à l'utilisation du framework `LAX`
+
+
+Lancement de l'application de base
+==================================
+
+Plusieurs répertoires doivent être accessibles via la variable
+d'environnement ``PYTHONPATH`` ::
+
+ $ export PYTHONPATH=/path/to/google_appengine:/path/to/google_appengine/lib/yaml/lib:/path/to/myapp/
+
+Le répertoire yaml n'est nécessaire que pour le lancement des scripts
+qui se trouvent dans lax/tools et pour l'exécution des tests unitaires.
+
+Pour démarrer::
+
+ $ python /path/to/google_appengine/dev_appserver.py /path/to/lax
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/03-01-installation.en.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,150 @@
+.. -*- 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
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/03-02-create-instance.en.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,127 @@
+.. -*- 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
+ hg init moncube
+ cd moncube
+ 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).
+
+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
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/03-03-cubicweb-ctl.en.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,121 @@
+.. -*- 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 <commande> [options commande] <arguments commandes>
+
+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 <commande> --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
+-------------------------------------------------
+* ``i18nlibupdate``, regénère les catalogues de messages de la librairie CubicWeb
+* ``i18nupdate``, regénère les catalogues de messages d'un composant
+* ``i18ncompile``, 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 <nom_cube> <nom_instance>
+
+Cette commande va creer les fichiers de configuration d'une instance dans
+``~/etc/cubicweb.d/<nom_instance>``.
+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 <nom_cube>
+
+Cette commande va creer un nouveau cube dans ``/path/to/forest/cubicweb/cubes/<nom_cube>``.
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/03-04-mercurial.en.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,112 @@
+.. -*- 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/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/03-setup.en.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,15 @@
+.. -*- coding: utf-8 -*-
+
+.. _MiseEnPlaceEnv:
+
+Installation et mise en place d'un environnement `CubicWeb`
+===========================================================
+
+.. toctree::
+ :maxdepth: 1
+
+ 03-01-installation.en.txt
+ 03-02-create-instance.en.txt
+ 03-03-cubicweb-ctl.en.txt
+ 03-04-mercurial.en.txt
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/04-01-schema-stdlib.en.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,70 @@
+.. -*- 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"
+``````````````````
+
+* `EUser`, utilisateurs du système
+* `EGroup`, groupes d'utilisateurs
+* `EEType`, types d'entité
+* `ERType`, 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
+
+* `EProperty`, utilisé pour configurer l'application
+* `EPermission`, 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.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/04-02-schema-definition.en.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,348 @@
+.. -*- 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` (`EUser`) (quel utilisateur a créé l'entité)
+
+ - `owned_by` (`EUser`) (à qui appartient l'entité, par défaut le
+ créateur mais pas forcément et il peut exister plusieurs propriétaires)
+
+ - `is` (`EEType`)
+
+
+* 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 = 'EUser'
+
+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')
+
+* `symetric` : 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_<ACTION>_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 <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é `EPermission` 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 EPermission(MetaEntityType):
+ """entity type that may be used to construct some advanced security configuration
+ """
+ name = String(required=True, indexed=True, internationalizable=True, maxsize=100)
+ require_group = SubjectRelation('EGroup', cardinality='+*',
+ description=_('groups to which the permission is granted'))
+ require_state = SubjectRelation('State',
+ description=_("entity'state in which the permission is applyable"))
+ # can be used on any entity
+ require_permission = ObjectRelation('**', cardinality='*1', composite='subject',
+ description=_("link a permission to the entity. This "
+ "permission should be used in the security "
+ "definition of the entity's type to be useful."))
+
+
+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é `EPermission` 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é `EPermission`, 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_<ACTION>_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.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/04-define-schema.en.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,21 @@
+.. -*- 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 "<type d'entité sujet>
+<type de relation> <type d'entité objet>". 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.en.txt
+.. include:: 04-02-schema-definition.en.txt
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/05-01-views-stdlib.en.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,65 @@
+.. -*- 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 (<ul>) 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 (<table>) 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/05-define-views.en.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,247 @@
+.. -*- 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.entity(row, col)
+ 09. self.w(u'<h1>%s</h1>' % entity.title)
+ 10. self.w(u'<p>published on %s in category %s</p>' % \
+ 11. (entity.publish_date.strftime('%Y-%m-%d'), entity.category))
+ 12. self.w(u'<p>%s</p>' % entity.text)
+
+The above source code defines a new primary view (`line 03`) for
+``BlogEntry`` (`line 05`).
+
+Since views are applied to resultsets and resulsets can be tables of
+data, it is needed to recover the entity from its (row,col)
+coordinates (`line 08`). We will get to this in more detail later.
+
+The view has a ``self.w()`` method that is used to output data. Here `lines
+09-12` output HTML tags and values of the entity's attributes.
+
+When displaying same blog entry as before, you will notice that the
+page is now looking much nicer.
+
+.. image:: images/lax-book.09-new-view-blogentry.en.png
+ :alt: blog entries now look much nicer
+
+Let us now improve the primary view of a blog ::
+
+ 01. class BlogPrimaryView(baseviews.PrimaryView):
+ 02.
+ 03. accepts = ('Blog',)
+ 04.
+ 05. def cell_call(self, row, col):
+ 06. entity = self.entity(row, col)
+ 07. self.w(u'<h1>%s</h1>' % entity.title)
+ 08. self.w(u'<p>%s</p>' % entity.description)
+ 09. rset = self.req.execute('Any E WHERE E entry_of B, B eid "%s"' % entity.eid)
+ 10. self.wview('primary', rset)
+
+In the above source code, `lines 01-08` are similar to the previous
+view we defined.
+
+At `line 09`, a simple request in made to build a resultset with all
+the entities linked to the current ``Blog`` entity by the relationship
+``entry_of``. The part of the framework handling the request knows
+about the schema and infer that such entities have to be of the
+``BlogEntry`` kind and retrieves them.
+
+The request returns a selection of data called a resultset. At
+`line 10` the view 'primary' is applied to this resultset to output
+HTML.
+
+**This is to be compared to interfaces and protocols in object-oriented
+languages. Applying a given view to all the entities of a resultset only
+requires the availability, for each entity of this resultset, of a
+view with that name that can accepts the entity.**
+
+Assuming we added entries to the blog titled `MyLife`, displaying it
+now allows to read its description and all its entries.
+
+.. image:: images/lax-book.10-blog-with-two-entries.en.png
+ :alt: a blog and all its entries
+
+**Before we move forward, remember that the selection/view principle is
+at the core of `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.en.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 `<div>` vides (par vide
+j'entend sans contenu dans la balise, il peut y avoir des attributs), faut
+toujours mettre `<div></div>` même s'il n'y a rien dedans, et non `<div/>`.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/06-define-workflows.en.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,154 @@
+.. -*- coding: utf-8 -*-
+
+Définition de workflow
+======================
+On peut mettre une condition rql ou/et un groupe auquel doit appartenir l'utilisateur.
+
+Si on met à la fois un(ou plusieurs) groupe et une condition RQL, il faut que les deux soient respectés.
+
+Si on met plusieurs groupes, il faut que l'utilisateur soit dans un des groupes.
+
+Pour la condition RQL sur une transition, on peut y mettre les substitutions suivantes :
+
+* `%(eid)s`, eid de l'objet
+* `%(ueid)s`, eid de l'utilisateur qui fait la requête
+* `%(seid)s`, eid de l'état courant de l'objet
+
+Dans le script de création d'un workflow, penser à mettre `_()` autour des noms d'états et de transitions
+pour que ceux si soient pris en compte par les scripts de gestion des catalogues i18n.
+
+General
+-------
+
+A workflow can be defined in a `LAX` application thanks to the system
+entities ``State`` and ``Transition``. Those are defined within all
+LAX application and can be set-up through the main administrator interface.
+
+Once your schema is defined, you can start creating the set of states and
+the required transitions for your applications entities.
+
+You first need to define the states and then the transitions between those
+to complete your workflow.
+
+A ``State`` defines the status of an entity. While creating a new state,
+you will be first given the option to select the entity type the state
+can be applied to. By choosing ``Apply``, a new section will be displayed
+in the editing screen to enable you to add relation to the state you are
+creating.
+
+A ``Transition`` is also based on an entity type it can be applied to.
+By choosing ``Apply``, a new section will be displayed in the editing
+screen to enable you to add relation to the transition you are
+creating.
+
+At the transition level you will also define the group of user which can
+aplly this transition to an object.
+
+
+Example of a simple workflow
+----------------------------
+
+Please see the tutorial to view and example of a simple workflow.
+
+
+[Create a simple workflow for BlogDemo, to have a moderator approve new blog
+entry to be published. This implies, specify a dedicated group of blog
+moderator as well as hide the view of a blog entry to the user until
+it reaches the state published]
+
+Set-up a workflow
+-----------------
+
+Before starting, make sure you refresh your mind by reading [link to
+definition_workflow chapter].
+
+We want to create a workflow to control the quality of the BlogEntry
+submitted on your application. When a BlogEntry is created by a user
+its state should be `submitted`. To be visible to all, it needs to
+be in the state `published`. To move from `submitted` to `published`
+we need a transition that we can name `approve_blogentry`.
+
+We do not want every user to be allowed to change the state of a
+BlogEntry. We need to define a group of user, `moderators`, and
+this group will have appropriate permissions to approve BlogEntry
+to be published and visible to all.
+
+There are two ways to create a workflow, form the user interface,
+and also by defining it in ``migration/postcreate.py``. This script
+is executed each time a new ``./bin/laxctl db-init`` is done.
+If you create the states and transitions through the user interface
+this means that next time you will need to initialize the database
+you will have to re-create all the entities.
+We strongly recommand you create the workflow in ``migration\postcreate.py``
+and we will now show you how.
+The user interface would only be a reference for you to view the states
+and transitions but is not the appropriate interface to define your
+application workflow.
+
+Update the schema
+~~~~~~~~~~~~~~~~~
+To enable a BlogEntry to have a State, we have to define a relation
+``in_state`` in the schema of BlogEntry. Please do as follows, add
+the line ``in_state (...)``::
+
+ class BlogEntry(EntityType):
+ title = String(maxsize=100, required=True)
+ publish_date = Date(default='TODAY')
+ text_format = String(meta=True, internationalizable=True, maxsize=50,
+ default='text/rest', constraints=[format_constraint])
+ text = String(fulltextindexed=True)
+ category = String(vocabulary=('important','business'))
+ entry_of = SubjectRelation('Blog', cardinality='?*')
+ in_state = SubjectRelation('State', cardinality='1*')
+
+As you updated the schema, you will have re-execute ``./bin/laxctl db-init``
+to initialize the database and migrate your existing entities.
+[WRITE ABOUT MIGRATION]
+
+Create states, transitions and group permissions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+At the time the ``postcreate.py`` script is executed, several methods
+can be used. They are all defined in the ``class ServerMigrationHelper``.
+We will only discuss the method we use to create a wrokflow here.
+
+To define our workflow for BlogDemo, please add the following lines
+to ``migration/postcreate.py``::
+
+ _ = unicode
+
+ moderators = add_entity('EGroup', name=u"moderators")
+
+ submitted = add_state(_('submitted'), 'BlogEntry', initial=True)
+ published = add_state(_('published'), 'BlogEntry')
+
+ add_transition(_('approve_blogentry'), 'BlogEntry', (submitted,), published, ('moderators', 'managers'),)
+
+ checkpoint()
+
+``add_entity`` is used here to define the new group of users that we
+need to define the transitions, `moderators`.
+If this group required by the transition is not defined before the
+transition is created, it will not create the relation `transition
+require the group moderator`.
+
+``add_state`` expects as the first argument the name of the state you are
+willing to create, then the entity type on which the state can be applied,
+and an optionnal argument to set if the state is the initial state
+of the entity type or not.
+
+``add_transition`` expects as the first argument the name of the
+transition, then the entity type on which we can apply the transition,
+then the list of possible initial states from which the transition
+can be applied, the target state of the transition, and the permissions
+(e.g. list of the groups of users who can apply the transition).
+
+.. image:: images/lax-book.03-transitions-view.en.png
+
+You can now notice that in the actions box of a BlogEntry, the state
+is now listed as well as the possible transitions from this state
+defined by the workflow. This transition, as defined in the workflow,
+will only being displayed for the users belonging to the group
+moderators of managers.
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/07-01-define-entities.en.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,168 @@
+.. -*- coding: utf-8 -*-
+
+Paramétrages et extensions spécifiques
+--------------------------------------
+
+Valeurs par défaut dynamiques
+`````````````````````````````
+Il est possible de définir dans le schéma des valeurs par défaut *statiques*.
+Il est également possible de définir des valeurs par défaut *dynamiques* en
+définissant sur la classe d'entité une méthode `default_<nom attribut>` pour
+un attribut donnée.
+
+
+Contrôle des attributs chargés et du tri par défaut
+```````````````````````````````````````````````````
+* l'attribut de classe `fetch_attrs` permet de définir sur une classe d'entité
+ la liste des noms des attributs ou relations devant être chargés
+ automatiquement lors de la récupération d'entité(s) de ce type. Dans le cas
+ des relations, on est limité aux relations *sujets de cardinalité `?` ou `1`*.
+
+* la méthode de classe `fetch_order(attr, var)` prend en argument un nom
+ d'attribut (ou de relation) et un nom de variable et doit retourner une chaine
+ à utiliser dans la close "ORDERBY" d'une requête RQL pour trier
+ automatiquement les listes d'entités de ce type selon cet attribut, ou `None`
+ si l'on ne veut pas de tri sur l'attribut passé en argument. Par défaut les
+ entités sont triées selon leur date de création
+
+* la méthode de classe `fetch_unrelated_order(attr, var)` est similaire à la
+ méthode `fetch_order` mais est utilisée essentiellement pour contrôler le tri
+ des listes déroulantes permettant de créer des relations dans la vue d'édition
+ d'une entité
+
+La fonction `fetch_config(fetchattrs, mainattr=None)` permet de simplifier la
+définition des attributs à précharger et du tri en retournant une liste des
+attributs à précharger (en considérant ceux de la classe `AnyEntity`
+automatiquement) et une fonction de tri sur l'attribut "principal" (le 2eme
+argument si spécifié ou sinon le premier attribut de la liste `fetchattrs`).
+Cette fonction est définie dans le package `ginco.entities`.
+
+Par exemple : ::
+
+ class Transition(AnyEntity):
+ """..."""
+ id = 'Transition'
+ fetch_attrs, fetch_order = fetch_config(['name'])
+
+Indique que pour le type d'entité "Transition" il faut précharger l'attribut
+"name" et trier par défaut selon cet attribut.
+
+
+Contrôle des formulaires d'édition
+``````````````````````````````````
+Il est possible de contrôler les attributs/relations dans la vue d'édition
+simple ou multiple à l'aide des *rtags* suivants :
+
+* `primary`, indique qu'un attribut ou une relation doit être incorporé dans
+ les formulaires d'édition simple et multiple. Dans le cas d'une relation,
+ le formulaire d'édition de l'entité liée sera inclus dans le formulaire
+
+* `secondary`, indique qu'un attribut ou une relation doit être incorporé dans
+ le formulaire d'édition simple uniquement. Dans le cas d'une relation,
+ le formulaire d'édition de l'entité liée sera inclus dans le formulaire
+
+* `generic`, indique qu'une relation doit être incorporé dans le formulaire
+ d'édition simple dans la boite générique d'ajout de relation
+
+* `generated`, indique qu'un attribut est caculé dynamiquement ou autre, et
+ qu'il ne doit donc pas être présent dans les formulaires d'édition
+
+Au besoin il est possible de surcharger la méthode
+`relation_category(rtype, x='subject')` pour calculer dynamiquement la catégorie
+d'édition d'une relation.
+
+
+Contrôle de la boîte "add_related"
+``````````````````````````````````
+La boite `add related` est une boite automatique proposant de créer une entité
+qui sera automatiquement liée à l'entité de départ (le contexte dans lequel
+s'affiche la boite). Par défaut, les liens présents dans cette boite sont
+calculés en fonction des propriétés du schéma de l'entité visualisée, mais il
+est possible de les spécifier explicitement à l'aide des *rtags* suivants :
+
+* `link`, indique qu'une relation est généralement créée vers une entité
+ existante et qu'il ne faut donc pas faire apparaitre de lien pour cette
+ relation
+
+* `create`, indique qu'une relation est généralement créée vers de nouvelles
+ entités et qu'il faut donc faire apparaitre un lien pour créer une nouvelle
+ entité et la lier automatiquement
+
+Au besoin il est possible de surcharger la méthode
+`relation_mode(rtype, targettype, x='subject')` pour caculer dynamiquement la
+catégorie de création d'une relation.
+
+A noter également que si au moins une action dans la catégorie "addrelated" est
+trouvée pour le contexte courant, le fonctionnement automatique est désactivé
+en faveur du fonctionnement explicite (i.e. affichage des actions de la
+catégorie "addrelated" uniquement).
+
+Contrôle des formulaires de filtrage de table
+`````````````````````````````````````````````
+La vue "table" par défaut gère dynamiquement un formulaire de filtrage du
+contenu de celle-ci. L'algorithme est le suivant :
+
+1. on considère que la première colonne contient les entités à restreindre
+2. on recupère la première entité de la table (ligne 0) pour "représenter"
+ toutes les autres
+3. pour toutes les autres variables définies dans la requête originale :
+
+ 1. si la variable est liée à la variable principale par au moins une
+ n'importe quelle relation
+ 2. on appelle la méthode `filterform_vocabulary(rtype, x)` sur l'entité
+ et si rien est retourné (ou plus exactement un tuple de valeur `None`,
+ voir ci-dessous) on passe à la variable suivante, sinon un élément de
+ formulaire de filtrage sera créé avec les valeurs de vocabulaire
+ retournées
+
+4. il n'y a pas d'autres limitations sur le rql, il peut comporter des clauses
+ de tris, de groupes... Des fonctions javascripts sont utilisées pour
+ regénérer une requête à partir de la requête de départ et des valeurs
+ séléctionnées dans les filtres de formulaire.
+
+
+La méthode `filterform_vocabulary(rtype, x, var, rqlst, args, cachekey)` prend
+en argument le nom d'une relation et la "cible", qui indique si l'entité sur
+laquelle la méthode est appellée est sujet ou objet de la relation. Elle doit
+retourner :
+
+* un 2-uple de None si elle ne sait pas gérer cette relation
+
+* un type et une liste contenant le vocabulaire
+
+ * la liste doit contenir des couples (valeur, label)
+ * le type indique si la valeur désigne un nombre entier (`type == 'int'`), une
+ chaîne de caractères (`type == 'string'`) ou une entité non finale (`type
+ == 'eid'`)
+
+Par exemple dans notre application de gestion de tickets, on veut pouvoir
+filtrés ceux-ci par :
+
+* type
+* priorité
+* état (in_state)
+* étiquette (tags)
+* version (done_in)
+
+On définit donc la méthode suivante : ::
+
+
+ class Ticket(AnyEntity):
+
+ ...
+
+ def filterform_vocabulary(self, rtype, x, var, rqlst, args, cachekey):
+ _ = self.req._
+ if rtype == 'type':
+ return 'string', [(x, _(x)) for x in ('bug', 'story')]
+ if rtype == 'priority':
+ return 'string', [(x, _(x)) for x in ('minor', 'normal', 'important')]
+ if rtype == 'done_in':
+ rql = insert_attr_select_relation(rqlst, var, rtype, 'num')
+ return 'eid', self.req.execute(rql, args, cachekey)
+ return super(Ticket, self).filterform_vocabulary(rtype, x, var, rqlst,
+ args, cachekey)
+
+
+NOTE: Le support du filtrage sur les étiquettes et l'état est installé
+automatiquement, pas besoin de le gérer ici.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/07-data-as-objects.en.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,142 @@
+.. -*- coding: utf-8 -*-
+
+
+Manipulation des données stockées
+=================================
+
+Les classes `Entity` et `AnyEntity`
+-----------------------------------
+Pour fournir un comportement spécifique à un type d'entité, il suffit de définir
+une classe héritant de la class `ginco.entities.AnyEntity`. En général il faut
+définir ces classes dans un module du package `entities` d'une application pour
+qu'elle soit disponible à la fois coté serveur et coté client.
+
+La classe `AnyEntity` est une classe chargée dynamiquement héritant de la classe
+de base `Entity` (`ginco.common.entity`). On définit une sous-classe pour
+ajouter des méthodes ou spécialiser les comportements d'un type d'entité donné.
+
+Des descripteurs sont ajoutés à l'enregistrement pour initialiser la classe en
+fonction du schéma :
+
+* on peut accéder aux attributs définis dans le schéma via les attributs de même
+ nom sur les instances (valeur typée)
+
+* on peut accéder aux relations définies dans le schéma via les attributs de même
+ nom sur les instances (liste d'instances d'entité)
+
+Les méthodes définies sur la classe `AnyEntity` ou `Entity` sont les suivantes :
+
+* `has_eid()`, retourne vrai si l'entité à un eid affecté (i.e. pas en cours de
+ création)
+
+* `check_perm(action)`, vérifie que l'utilisateur à le droit d'effectuer
+ l'action demandée sur l'entité
+
+:Formattage et génération de la sortie:
+
+ * `view(vid, **kwargs)`, applique la vue donnée à l'entité
+
+ * `absolute_url(**kwargs)`, retourne une URL absolue permettant d'accéder à la
+ vue primaire d'une entité
+
+ * `rest_path()`, renvoie une l'URL REST relative permettant d'obtenir l'entité
+
+ * `format(attr)`, retourne le format (type MIME) du champ passé en argument
+
+ * `printable_value(attr, value=_marker, attrtype=None, format='text/html')`,
+ retourne une chaine permettant l'affichage dans un format donné de la valeur
+ d'un attribut (la valeur est automatiquement récupérée au besoin)
+
+ * `display_name(form='')`, retourne une chaîne pour afficher le type de
+ l'entité, en spécifiant éventuellement la forme désirée ('plural' pour la
+ forme plurielle)
+
+:Gestion de données:
+
+ * `as_rset()`, transforme l'entité en un resultset équivalent simulant
+ le résultat de la requête `Any X WHERE X eid _eid_`
+
+ * `complete(skip_bytes=True)`, effectue une requête permettant de récupérer d'un
+ coup toutes les valeurs d'attributs manquant sur l'entité
+
+ * `get_value(name)`, récupere la valeur associée à l'attribut passé en argument
+
+ * `related(rtype, x='subject', limit=None, entities=False)`, retourne une liste
+ des entités liées à l'entité courant par la relation donnée en argument
+
+ * `unrelated(rtype, targettype, x='subject', limit=None)`, retourne un result set
+ des entités not liées à l'entité courante par la relation donnée en argument
+ et satisfaisants les contraintes de celle-ci
+
+ * `set_attributes(**kwargs)`, met à jour la liste des attributs avec
+ les valeurs correspondantes passées sous forme d'arguments nommés
+
+ * `copy_relations(ceid)`, copie les relations de l'entité ayant l'eid passé en
+ argument sur l'entité courante
+
+ * `last_modified(view)`, retourne la date à laquelle on doit considérer
+ l'objet comme modifié (utiliser par la gestion de cache HTTP)
+
+ * `delete()` permet de supprimer l'entité représentée
+
+:Meta-données standard (Dublin Core):
+
+ * `dc_title()`, retourne une chaine unicode correspondant à la méta-donnée
+ 'Title' (utilise par défaut le premier attribut non 'meta' du schéma de
+ l'entité)
+
+ * `dc_long_title()`, comme dc_title mais peut retourner un titre plus détaillé
+
+ * `dc_description(format='text/plain')`, retourne une chaine unicode
+ correspondant à la méta-donnée 'Description' (cherche un attribut
+ 'description' par défaut)
+
+ * `dc_authors()`, retourne une chaine unicode correspondant à la méta-donnée
+ 'Authors' (propriétaires par défaut)
+
+ * `dc_date(date_format=None)`, retourne une chaine unicode
+ correspondant à la méta-donnée 'Date' (date de modification par défaut)
+
+:Contrôle du vocabulaire pour les relations:
+
+ * `vocabulary(rtype, x='subject', limit=None)`, appelée notamment
+ par les vues d'édition d'erudi, elle renvoie une liste de couple
+ (label, eid) des entités qui pourraient être liées à l'entité
+ via la relation `rtype`
+ * `subject_relation_vocabulary(rtype, limit=None)`, appelée
+ en interne par `vocabulary` dans le cas d'une relation sujet
+ * `object_relation_vocabulary(rtype, limit=None)`, appelée
+ en interne par `vocabulary` dans le cas d'une relation objet
+ * `relation_vocabulary(rtype, targettype, x, limit=None)`, appelé
+ en interne par `subject_relation_vocabulary` et `object_relation_vocabulary`
+
+
+Les *rtags*
+-----------
+Les *rtags* permettent de spécifier certains comportements propres aux relations
+d'un type d'entité donné (voir plus loin). Ils sont définis sur la classe
+d'entité via l'attribut `rtags` qui est un dictionnaire dont les clés sont un
+triplet ::
+
+ <type de relation>, <type d'entité cible>, <position du contexte ("subject" ou "object"
+
+et les valeurs un `set` ou un tuple de marqueurs définissant des propriétés
+s'appliquant à cette relation.
+
+Il est possible de simplifier ce dictionnaire :
+
+* si l'on veut spécifier un seul marqueur, il n'est pas nécessaire d'utiliser
+ un tuple comme valeur, le marqueur seul (chaine de caractères) suffit
+* si l'on s'intéresse uniquement à un type de relation et non à la cible et à la
+ position du contexte (ou que celui-ci n'est pas ambigüe), on peut simplement
+ utiliser le nom du type de relation comme clé
+* si l'on veut qu'un marqueur s'applique quelque soit le type d'entité cible, il
+ faut utiliser la chaine `*` comme type d'entité cible
+
+A noter également que ce dictionnaire est *traité à la création de la classe*.
+Il est automatiquement fusionné avec celui de la ou des classe(s) parentes (pas
+besoin de copier celui de la classe parent pour le modifier). De même modifier
+celui-ci après création de la classe n'aura aucun effet...
+
+
+.. include:: 07-01-define-entities.en.txt
--- a/doc/book/en/08-rql.en.txt Mon Nov 17 14:38:30 2008 -0800
+++ b/doc/book/en/08-rql.en.txt Tue Nov 18 01:16:30 2008 +0100
@@ -90,7 +90,7 @@
variables must be grouped or aggregated.
Examples - search
-`````````````````
+~~~~~~~~~~~~~~~~~
::
Any X WHERE X eid 53
@@ -101,7 +101,7 @@
Advanced features
-`````````````````
+~~~~~~~~~~~~~~~~~
* Aggregate functions: `COUNT`, `MIN`, `MAX`, `SUM`.
* String functions:`UPPER`, `LOWER`.
* Optional relations:
@@ -120,7 +120,7 @@
Any C,P WHERE C is Card, P? documented_by C
Negation
-````````
+~~~~~~~~
* A query such as `Document X WHERE NOT X owned_by U` is equivalent to
"the documents which do not have relation `owned_by`".
* Whereas the query `Document X WHERE NOT X owned_by U, U login "syt"`
@@ -129,7 +129,7 @@
Identity
-````````
+~~~~~~~~
We could use the special relation `identity` in a query in order to add a
condition of identity between two variables. This is equivalent to ``is``
@@ -154,7 +154,7 @@
returned by the condition*.
Examples - insertion
-`````````````````````
+~~~~~~~~~~~~~~~~~~~~~
* Insertion of a new person named 'bidule'::
INSERT Person X: X name 'bidule'
@@ -179,7 +179,7 @@
returned by the condition*.
Examples - update
-`````````````````
+~~~~~~~~~~~~~~~~~
* Renaming of the person named 'bidule' to 'toto', with change on the first name::
SET X name 'toto', X firstname 'original' WHERE X is 'Person', X name 'bidule'
@@ -200,7 +200,7 @@
Examples
-````````
+~~~~~~~~
* Deletion of the person named 'toto'::
DELETE Person X WHERE X name 'toto'
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/08-site-config.en.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,94 @@
+.. -*- coding: utf-8 -*-
+
+Interface de configuration du site
+==================================
+
+.. image:: images/lax-book.03-site-config-panel.en.png
+
+This panel allows you to configure the appearance of your application site.
+Six menus are available and we will go through each of them to explain how
+to use them.
+
+Navigation
+~~~~~~~~~~
+This menu provides you a way to adjust some navigation options depending on
+your needs, such as the number of entities to display by page of results.
+Follows the detailled list of available options :
+
+* navigation.combobox-limit : maximum number of entities to display in related
+ combo box (sample format: 23)
+* navigation.page-size : maximum number of objects displayed by page of results
+ (sample format: 23)
+* navigation.related-limit : maximum number of related entities to display in
+ the primary view (sample format: 23)
+* navigation.short-line-size : maximum number of characters in short description
+ (sample format: 23)
+
+UI
+~~
+This menu provides you a way to customize the user interface settings such as
+date format or encoding in the produced html.
+Follows the detailled list of available options :
+
+* ui.date-format : how to format date in the ui ("man strftime" for format description)
+* ui.datetime-format : how to format date and time in the ui ("man strftime" for format
+ description)
+* ui.default-text-format : default text format for rich text fields.
+* ui.encoding : user interface encoding
+* ui.fckeditor :should html fields being edited using fckeditor (a HTML WYSIWYG editor).
+ You should also select text/html as default text format to actually get fckeditor.
+* ui.float-format : how to format float numbers in the ui
+* ui.language : language of the user interface
+* ui.main-template : id of main template used to render pages
+* ui.site-title : site title, which is displayed right next to the logo in the header
+* ui.time-format : how to format time in the ui ("man strftime" for format description)
+
+
+Actions
+~~~~~~~
+This menu provides a way to configure the context in which you expect the actions
+to be displayed to the user and if you want the action to be visible or not.
+You must have notice that when you view a list of entities, an action box is
+available on the left column which display some actions as well as a drop-down
+menu for more actions.
+
+The context available are :
+
+* mainactions : actions listed in the left box
+* moreactions : actions listed in the `more` menu of the left box
+* addrelated : add actions listed in the left box
+* useractions : actions listed in the first section of drop-down menu
+ accessible from the right corner user login link
+* siteactions : actions listed in the second section of drop-down menu
+ accessible from the right corner user login link
+* hidden : select this to hide the specific action
+
+Boxes
+~~~~~
+The application has already a pre-defined set of boxes you can use right away.
+This configuration section allows you to place those boxes where you want in the
+application interface to customize it.
+
+The available boxes are :
+
+* actions box : box listing the applicable actions on the displayed data
+
+* boxes_blog_archives_box : box listing the blog archives
+
+* possible views box : box listing the possible views for the displayed data
+
+* rss box : RSS icon to get displayed data as a RSS thread
+
+* search box : search box
+
+* startup views box : box listing the configuration options available for
+ the application site, such as `Preferences` and `Site Configuration`
+
+Components
+~~~~~~~~~~
+[WRITE ME]
+
+Contextual components
+~~~~~~~~~~~~~~~~~~~~~
+[WRITE ME]
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/09-instance-config.en.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,162 @@
+.. -*- coding: utf-8 -*-
+
+Configuration d'une instance
+============================
+
+À la création d'une instance, un fichier de configuration est généré dans ::
+
+ $(CW_REGISTRY)/<instance>/<nom configuration>.conf
+
+par exemple ::
+
+ /etc/cubicweb.d/jpl/all-in-one.conf
+
+C'est un simple fichier texte au format INI. Dans la description suivante,
+chaque nom d'option est préfixé de sa section et suivi de sa valeur par défaut
+le cas échéant, e.g. "`<section>.<option>` [valeur]".
+
+
+Configuration du serveur web
+----------------------------
+:`web.auth-mode` [cookie]:
+ mode d'authentification, cookie ou http
+:`web.realm`:
+ realm de l'application en mode d'authentification http
+:`web.http-session-time` [0]:
+ délai d'inactivité d'une session HTTP avant sa fermeture automatique. Durée
+ en secondes, 0 signifiant pas d'expiration (ou plus exactement lors de la
+ fermeture du navigateur du client)
+
+:`main.anonymous-user`, `main.anonymous-password`:
+ login et mot de passe à utiliser pour se connecter au serveur RQL lors des
+ connexions HTTP anonymes. Il faut que le compte EUser associé existe.
+
+:`main.base-url`:
+ url de base du site, à utiliser pour générer les urls des pages web
+
+Configuration https
+```````````````````
+Il est possible de rendre un site accessible en http pour les connections
+anonymes et en https pour les utilisateurs authentifié. Il faut pour cela
+utiliser apache (par ex.) pour la redirection et la variable `main.https-url` du
+fichier de configuration.
+
+:Exemple:
+
+ pour une redirection apache d'un site accessible via `http://localhost/demo`
+ et `https://localhost/demo` et qui tourne en réalité sur le port 8080, il
+ faut avoir pour la version http : ::
+
+ RewriteCond %{REQUEST_URI} ^/demo
+ RewriteRule ^/demo$ /demo/
+ RewriteRule ^/demo/(.*) http://127.0.0.1:8080/$1 [L,P]
+
+ et pour la version https : ::
+
+ RewriteCond %{REQUEST_URI} ^/demo
+ RewriteRule ^/demo$ /demo/
+ RewriteRule ^/demo/(.*) http://127.0.0.1:8080/https/$1 [L,P]
+
+
+ et on aura dans le fichier all-in-one.conf de l'instance : ::
+
+ base-url = http://localhost/demo
+ https-url = `https://localhost/demo`
+
+Configuration de l'interface web
+--------------------------------
+:`web.embed-allowed`:
+ expression régulière correspondant aux sites pouvant être "incorporé" dans
+ le site (controleur 'embed')
+:`web.submit-url`:
+ url à laquelle les bugs rencontrés dans l'application peuvent être posté
+
+
+Configuration du serveur RQL
+----------------------------
+:`main.host`:
+ nom de l'hôte s'il ne peut être détecter correctement
+:`main.pid-file`:
+ fichier où sera écrit le pid du serveur
+:`main.uid`:
+ compte utilisateur à utiliser pour le lancement du serveur quand il est
+ lancé en root par init
+:`main.session-time [30*60]`:
+ temps d'expiration d'une session RQL
+:`main.query-log-file`:
+ fichier dans lequel écrire toutes les requêtes RQL éxécutées par le serveur
+
+
+Configuration Pyro pour l'instance
+-----------------------------------
+Coté serveur web :
+
+:`pyro-client.pyro-application-id`:
+ identifiant pyro du serveur RQL (e.g. le nom de l'instance)
+
+Coté serveur RQL :
+
+:`pyro-server.pyro-port`:
+ numéro de port pyro. Si aucune valeur n'est spécifiée, un port est attribué
+ automatiquement.
+
+Coté serveur RQL et serveur web :
+
+:`pyro-name-server.pyro-ns-host`:
+ nom de l'hôte hébergeant le serveur de nom pyro. Si aucune valeur n'est
+ spécifié, il est localisé par une requête de broadcast
+:`pyro-name-server.pyro-ns-group` [cubicweb]:
+ groupe pyro sous lequel enregistrer l'application
+
+
+Configuration courriel
+----------------------
+Coté serveur RQL et serveur web :
+
+:`email.mangle-emails [no]`:
+ indique si les adresses email doivent être affichées telle quelle ou
+ transformée
+
+Coté serveur RQL :
+
+:`email.smtp-host [mail]`:
+ nom de l'hôte hébergeant le serveur SMTP à utiliser pour le courriel sortant
+:`email.smtp-port [25]`:
+ port du serveur SMTP à utiliser pour le courriel sortant
+:`email.sender-name`:
+ nom à utiliser pour les courriels sortant de l'application
+:`email.sender-addr`:
+ adresse à utiliser pour les courriels sortant de l'application
+:`email.default-dest-addrs`:
+ adresses de destination par défaut, si utilisé par la configuration de la
+ diffusion du modèle (séparées par des virgules)
+:`email.supervising-addrs`:
+ addresses de destination des courriels de supervision (séparées par des
+ virgules)
+
+
+Configuration journalisation
+----------------------------
+:`main.log-threshold`:
+ niveau de filtrage des messages (DEBUG, INFO, WARNING, ERROR)
+:`main.log-file`:
+ fichier dans lequel écrire les messages
+
+
+Configuration Eproperties
+-------------------------
+D'autres paramètres de configuration sont sous la forme d'entités `EProperty`
+dans la base de données. Il faut donc les éditer via l'interface web ou par des
+requêtes rql.
+
+:`ui.encoding`:
+ encodage de caractères à utiliser pour l'interface web
+:`navigation.short-line-size`: # XXX should be in ui
+ nombre de caractères maximum pour les affichages "courts"
+:`navigation.page-size`:
+ nombre d'entités maximum à afficher par page de résultat
+:`navigation.related-limit`:
+ nombre d'entités liées maximum à afficher sur la vue primaire d'une entité
+:`navigation.combobox-limit`:
+ nombre d'entités non liées maximum à afficher sur les listes déroulantes de
+ la vue d'édition d'une entité
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/10-form-management.en.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,133 @@
+.. -*- coding: utf-8 -*-
+
+Gestion de formulaires
+======================
+
+Contrôle de la génération automatique de formulaire pour les entités manipulée
+------------------------------------------------------------------------------
+XXX FILLME
+
+* les formulaires 'edition' et 'creation'
+
+Le formulaire généré par défaut ne vous convient pas ? Vous êtes peut-être pas
+obligé de le refaire à la main ! :)
+
+* rtags primary, secondary, generated, generic,
+ `Entity.relation_category(rtype, x='subject')`
+* inline_view (now a rtag?)
+* spécification widget
+
+
+Fonctionnement du contrôleur d'édition par défaut (id: 'edit')
+--------------------------------------------------------------
+
+Contrôle de l'édition
+`````````````````````
+Prérequis: les paramètres liés aux entités à éditer sont spécifiés de la forme ::
+
+ <nom de champ>:<eid de l'entité>
+
+où l'eid de l'entité pourra être une lettre dans le cas d'une entité à créer. On
+dénommera ces paramètres comme *qualifié*.
+
+1. récupération des entités à éditer en cherchant les paramètres de formulaire
+ commençant par 'eid:' ayant également un paramètre '__type' associé
+ (également *qualifié* par l'eid évidemment)
+
+2. pour tous les attributs et relations de chaque entité à éditer
+
+ 1. recherche d'un paramètre 'edits-<nom relation>' ou 'edito-<nom relation>'
+ qualifié dans le cas d'une relation dont l'entité est objet
+ 2. si trouvé, la valeur récupérée est considérée comme la valeur originale
+ pour cette relation, et on cherche la (ou les) nouvelle(s) valeur(s) dans
+ le paramètre <nom relation> (qualifié)
+ 3. si la valeur est différente de l'originale, une requête de modification en
+ base est effectuée
+
+3. pour chaque entité à éditer
+
+ 1. si un paramètre `__linkto` qualifié est spécifié, sa valeur doit être une
+ chaine (ou une liste de chaine) de la forme : ::
+
+ <relation type>:<eids>:<target>
+
+ où <target> vaut 'subject' ou 'object' et chaque eid peut-être séparé d'un
+ autre par un '_'. Target spécifie *l'entité éditée* est sujet ou objet de la
+ relation et chaque relation ainsi spécifiée sera insérée.
+
+ 2. si un paramètre `__cloned_eid` qualifié est spécifié pour une entité, les
+ relations de l'entité spécifiée en valeur de cette argument sont copiées sur
+ l'entité éditée
+
+
+ 3. si un paramètre `__delete` qualifié est spécifié, sa valeur doit être une
+ chaine (ou une liste de chaine) de la forme : ::
+
+ <subject eids>:<relation type>:<object eids>
+
+ où chaque eid sujet ou objet peut-être séparé d'un autre par un '_'. Chaque
+ relation ainsi spécifiée sera supprimée.
+
+ 4. si un paramètre `__insert` qualifié est spécifié, sa valeur doit être de
+ même format que pour `__delete`, mais chaque relation ainsi spécifiée sera
+ insérée.
+
+4. si les paramètres `__insert` et/ou `__delete` sont trouvés non qualifiés,
+ ils sont interprétés comme décrit ci-dessus (quelque soit le nombre d'entité
+ édité)
+
+5. si aucune entité n'est éditée mais que le formulaire contient les paramètres
+ `__linkto` et `eid`, celui-ci est interprété en prenant la valeur spécifié
+ par le paramètre `eid` pour désigner l'entité sur laquelle ajouter les
+ relations
+
+
+A noter que :
+
+* si le paramètre `__action_delete` est trouvé, toutes les entités comme
+ spécifiées à éditer seront supprimées
+
+* si le paramètre `__action_cancel` est trouvé, aucune action n'est effectuée
+
+* si le paramètre `__action_apply` est trouvé, l'édition est effectuée
+ normalement mais la redirection sera effectuée sur le formulaire (cf `Contrôle
+ de la redirection`_)
+
+* le paramètre `__method` est également supporté comme sur le template principal
+ (XXX not very consistent, maybe __method should be dealed in the view controller)
+
+* si aucune entité à éditer n'est trouvée et qu'il n'y a pas de paramètre
+ `__action_delete`, `__action_cancel`, `__linkto`, `__delete` ou `__insert`,
+ une erreur est levée
+
+* placer dans le formulaire le paramètre `__message` permettra d'utiliser la
+ valeur de ce paramètre comme message d'information à l'utilisateur une fois
+ l'édition effectuée.
+
+
+Contrôle de la redirection
+``````````````````````````
+Une fois que l'édition s'est bien passé, reste un problème : c'est bien beau
+tout ça, mais où qu'on va maintenant ?? Si rien n'est spécifié, le controlleur
+se débrouille, mais comme il fait pas toujours ce qu'on voudrait, on peut
+controller ça en utilisant les paramètres suivant :
+
+* `__redirectpath`: chemin de l'url (relatif à la racine du site, sans paramètre
+ de formulaire
+
+* `__redirectparams`: paramètres de formulaires à ajouter au chemin
+
+* `__redirectrql`: requête RQL de redirection
+
+* `__redirectvid`: identifiant de vue de redirection
+
+* `__errorurl`: url du formulaire original, utilisé pour la redirection en cas
+ d'erreur de validation pendant l'édition. Si celui-ci n'est pas spécifié, une
+ page d'erreur sera présentée plutot qu'un retour sur le formulaire (qui est le
+ cas échéant responsable d'afficher les erreurs)
+
+* `__form_id`: identifiant de vue du formulaire original, utilisée si
+ `__action_apply` est trouvé
+
+En général on utilise soit `__redirectpath et `__redirectparams` soit
+`__redirectrql` et `__redirectvid`.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/11-ajax-json.en.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,16 @@
+.. -*- coding: utf-8 -*-
+
+AJAX
+====
+JSON bla bla
+XXX FILLME
+
+
+Le contrôleur 'json'
+--------------------
+XXX FILLME
+
+
+API Javascript
+--------------
+XXX FILLME
--- a/doc/book/en/11-faq.en.txt Mon Nov 17 14:38:30 2008 -0800
+++ b/doc/book/en/11-faq.en.txt Tue Nov 18 01:16:30 2008 +0100
@@ -52,3 +52,59 @@
This can be fixed by applying the patch described in :
http://code.google.com/p/googleappengine/issues/detail?id=48
[ADD MORE FAQ]
+.. -*- coding: utf-8 -*-
+
+Frequently Asked Questions
+==========================
+
+* Why does not LAX have a template language ?
+
+ It does. Actually, you can use your preferred template language if you
+ want. [explain how to use a template language]
+
+ The reason template languages are not used in this book is that
+ experience has proved us that using pure python was more efficient.
+
+* Why do you think using pure python is better than using a template language ?
+
+ [copy answer from forum]
+
+ code is easier to maintain, does not have to learn a new dialect
+ each time, real function/classes etc -> real development
+
+* Why do you use the GPL license to prevent me from doing X ?
+
+ [copy answer from forum]
+
+* LAX looks pretty recent. Is it stable ?
+
+ [answer that framework has evolved over the past seven years and that
+ data migrated from one schema to the other ever since]
+
+* Why is the RQL query language looking similar to X ?
+
+ [copy answer from forum, explain why similar to sparql and why better
+ than django and SQL]
+
+* which ajax library
+
+ [we use mochikit and things on top of that]
+
+* `Error while publishing rest text ...`
+
+ While modifying the description of an entity, you get an error message in
+ the application `Error while publishing ...` for Rest text and plain text.
+ The server returns a traceback like as follows ::
+
+ 2008-10-06 15:05:08 - (erudi.rest) ERROR: error while publishing ReST text
+ Traceback (most recent call last):
+ File "/home/sandrine/src/blogdemo/ginco/common/rest.py", line 217, in rest_publish
+ (...)
+ File "/usr/lib/python2.5/codecs.py", line 817, in open
+ file = __builtin__.open(filename, mode, buffering)
+ TypeError: __init__() takes at most 3 arguments (4 given)
+
+ This can be fixed by applying the patch described in :
+ `Google group appengine <http://code.google.com/p/googleappengine/issues/detail?id=48>`_
+
+[ADD MORE FAQ]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/12-ui-components.en.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,14 @@
+Autres composants de l'interface web
+====================================
+
+Actions
+-------
+XXXFILLME
+
+Component, VComponent
+---------------------
+XXXFILLME
+
+EProperty
+---------
+XXXFILLME
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/13-security.en.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,45 @@
+.. -*- coding: utf-8 -*-
+
+Utilisateurs de l'application : Le contrôle d'accès
+===================================================
+
+
+Vocabulaire
+-----------
+* Personne, Societe définissent deux *types* d'entité
+* "Personne travaille_pour Societé" déclare qu'une relation
+ travaille_pour peut exister entre une entité de type Personne et une
+ entité de type Societe. L'ensemble des règles de ce type appliqué
+ à la relation "travaille_pour" définit le schéma de la relation
+ "travaille_pour"
+
+
+Description du modèle de sécurité
+---------------------------------
+
+Le modèle de sécurité de CubicWeb est un modèle fondé sur des `Access
+Control List`. Les notions sont les suivantes :
+
+* utilisateurs et groupes d'utilisateurs
+* un utilisateur appartient à au moins un groupe
+* droits (lire, modifier, créer, supprimer)
+* les droits sont attribués aux groupes (et non aux utilisateurs)
+
+Pour CubicWeb plus spécifiquement :
+
+* on associe les droits au niveau des schemas d'entites / relations
+* pour chaque type d'entité, on distingue les droits de lecture,
+ ajout, modification et suppression
+* pour chaque type de relation, on distingue les droits de lecture,
+ ajout et suppression (on ne peut pas modifer une relation)
+* les groupes de base sont : Administrateurs, Utilisateurs, Invités
+* les utilisateurs font par défaut parti du groupe Utilisateurs
+* on a un groupe virtuel "Utilisateurs Propriétaires", auquel on peut
+ associer uniquement les droits de suppression et de modification
+* on ne peut pas mettre d'utilisateurs dans ce groupe, ils y sont
+ ajoutés implicitement dans le contexte des objets dont ils sont
+ propriétaires
+* les droits de ce groupe ne sont vérifiés que sur
+ modification / suppression si tous les autres groupes auxquels
+ l'utilisateur appartient se sont vu interdir l'accès
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/14-hooks.en.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,31 @@
+.. -*- coding: utf-8 -*-
+
+Les crochets (*hooks*)
+======================
+
+XXX FILLME
+
+Les crochets sont appelés avant ou après la mise à jour d'une entité ou d'une
+relations dans le dépot
+
+Leur prototypes sont les suivants
+
+
+ * after_add_entity (session, entity)
+ * after_update_entity (session, entity)
+ * after_delete_entity (session, eid)
+ * before_add_entity (session, entity)
+ * before_update_entity (session, entity)
+ * before_delete_entity (session, eid)
+
+ * after_add_relation (session, fromeid, rtype, toeid)
+ * after_delete_relation (session, fromeid, rtype, toeid)
+ * before_add_relation (session, fromeid, rtype, toeid)
+ * before_delete_relation (session, fromeid, rtype, toeid)
+
+ * server_startup
+ * server_shutdown
+
+ * session_open
+ * session_close
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/15-notifications.en.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,6 @@
+.. -*- coding: utf-8 -*-
+
+Gestion de notifications
+========================
+
+XXX FILLME
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/16-rql.en.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,11 @@
+.. -*- coding: utf-8 -*-
+
+Le langage RQL (Relation Query Language)
+========================================
+
+Voir la `documentation de RQL <file:///home/sandrine/src/fcubicweb/rql/doc/build/html/index.html>`_ .
+
+
+[TODO]
+Specific link to RQL complete documentation to remove duplicated content.
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/17-migration.en.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,218 @@
+.. -*- coding: utf-8 -*-
+
+
+Migration
+=========
+
+Une des idées de base d'Erudi est la création incrémentale d'application, et
+pour cela de nombreuses actions sont fournies afin de facilement faire évoluer
+une application et tout particulièrement le modèle de données manipulé sans
+perdre les données des instances existantes.
+
+La version courante d'un modèle d'application est données dans le fichier
+`__pkginfo__.py` sous forme d'un tuple de 3 entiers.
+
+
+Gestion des scripts de migrations
+---------------------------------
+Les scripts des migrations doivent être placés dans le répertoire `migration` de
+l'application, et nommé de la manière suivante :
+
+::
+
+ <n° de version X.Y.Z>[_<description>]_<mode>.py
+
+dans lequel :
+
+* X.Y.Z correspond au n° de version du modèle vers lequel le script permet de
+ migrer,
+
+* le *mode* (entre le dernier "_" et l'extension ".py") indique à quelle partie
+ de l'application (serveur RQL, serveur web) le script s'applique en cas
+ d'installation distribuée. Il peut valoir :
+
+ * `common`, s'applique aussi bien sur le serveur RQL que sur le serveur web,
+ et met à jour des fichiers sur le disque (migration de fichier de
+ configuration par exemple).
+
+ * `web`, s'applique uniquement sur le serveur web, et met à jour des fichiers
+ sur le disque
+
+ * `repository`, s'applique uniquement sur le serveur RQL, et met à jour des
+ fichiers sur le disque
+
+ * `Any`, s'applique uniquement sur le serveur RQL, et met à jour des
+ données en base (migrations de schéma et de données par ex.)
+
+
+Toujours dans le répertoire `migration`, le fichier spécial `depends.map` permet
+d'indiquer que pour migrer vers une version spécifique du modèle, il faut tout
+d'abord avoir migrer vers une version données de erudi. Ce fichier peut contenir
+des commentaires (lignes commençant par un "#"), et une dépendance est notée sur
+une ligne de la manière suivante : ::
+
+ <n° de version du modèle X.Y.Z> : <n° de version erudi X.Y.Z>
+
+Par exemple ::
+
+ 0.12.0: 2.26.0
+ 0.13.0: 2.27.0
+ # 0.14 works with 2.27 <= erudi <= 2.28 at least
+ 0.15.0: 2.28.0
+
+
+Contexte de base
+----------------
+Les identifiants suivants sont préféfinis dans les scripts de migration :
+
+* `config`, configuration de l'instance
+
+* `interactive_mode`, booléen indiquant si le script est éxécuté en mode
+ interactif ou non
+
+* `appltemplversion`, version du modèle d'application de l'instance
+
+* `applerudiversion`, version erudi de l'instance
+
+* `templversion`, version du modéle d'application installée
+
+* `erudiversion`, version erudi installée
+
+* `confirm(question)`, fonction posant une question et retournant vrai si
+ l'utilisateur a répondu oui, faux sinon (retourne toujours vrai en mode non
+ interactif)
+
+* `_`, fonction équivalente à `unicode` permettant de marquer des chaines à
+ internationaliser dans les scripts de migration
+
+Dans les scripts "repository", les identifiants suivant sont également définis :
+
+* `checkpoint`, demande confirmant et effectue un "commit" au point d'appel
+
+* `repo_schema`, schéma persistent de l'instance (i.e. schéma de l'instance en
+ cours de migration)
+
+* `newschema`, schéma installé sur le système de fichier (i.e. schéma de la
+ version à jour du modèle et de erudi)
+
+* `sqlcursor`, un curseur SQL pour les très rares cas où il est réellement
+ nécessaire ou avantageux de passer par du sql
+
+* `repo`, l'objet repository
+
+
+Migration de schéma
+-------------------
+Les fonctions de migration de schéma suivantes sont disponibles dans les scripts
+"repository" :
+
+* `add_attribute(etype, attrname, attrtype=None, commit=True)`, ajoute un
+ nouvel attribut à un type d'entité existante. Si le type de celui-ci n'est pas
+ spécifié il est extrait du schéma à jour.
+
+* `drop_attribute(etype, attrname, commit=True)`, supprime un
+ attribut à un type d'entité existante.
+
+* `rename_attribute(etype, oldname, newname, commit=True)`, renomme un attribut
+
+* `add_entity_type(etype, auto=True, commit=True)`, ajoute un nouveau type
+ d'entité. Si `auto` est vrai, toutes les relations utilisant ce type d'entité
+ et ayant un type d'entité connu à l'autre extrémité vont également être
+ ajoutées.
+
+* `drop_entity_type(etype, commit=True)`, supprime un type d'entité et toutes
+ les relations l'utilisant.
+
+* `rename_entity_type(oldname, newname, commit=True)`, renomme un type d'entité
+
+* `add_relation_type(rtype, addrdef=True, commit=True)`, ajoute un nouveau type
+ de relation. Si `addrdef` est vrai, toutes les définitions de relation de ce
+ type seront également ajoutées.
+
+* `drop_relation_type(rtype, commit=True)`, supprime un type de relation et
+ toutes les définitions de ce type.
+
+* `rename_relation(oldname, newname, commit=True)`, renomme une relation.
+
+* `add_relation_definition(subjtype, rtype, objtype, commit=True)`, ajoute une
+ définition de relation.
+
+* `drop_relation_definition(subjtype, rtype, objtype, commit=True)`, supprime
+ une définition de relation.
+
+* `synchronize_permissions(ertype, commit=True)`, synchronise les permissions
+ d'un type d'entité ou de relation
+
+* `synchronize_rschema(rtype, commit=True)`, synchronise les propriétés et
+ permissions d'un type de relation.
+
+* `synchronize_eschema(etype, commit=True)`, synchronise les propriétés et
+ permissions d'un type d'entité.
+
+* `synchronize_schema(commit=True)`, synchronise le schéma persistent avec le
+ schéma à jour (mais sans ajouter ni supprimer de nouveaux types d'entités ou
+ de relations ni de définitions de relation).
+
+* `change_relation_props(subjtype, rtype, objtype, commit=True, **kwargs)`, change
+ les propriétés d'une definition de relation en utilisant les arguments nommés
+ pour les propriétés à changer.
+
+* `set_widget(etype, rtype, widget, commit=True)`, change le widget à utiliser
+ pour la relation <rtype> du type d'entité <etype>
+
+* `set_size_constraint(etype, rtype, size, commit=True)`, change la contrainte
+ de taille pour la relation <rtype> du type d'entité <etype>
+
+
+Migration de données
+--------------------
+Les fonctions de migration de données suivantes sont disponibles dans les scripts
+"repository" :
+
+* `rql(rql, kwargs=None, cachekey=None, ask_confirm=True)`, éxécute une
+ requête rql arbitraire, d'interrogation ou de modification. Un objet result
+ set est retourné.
+
+* `add_entity(etype, *args, **kwargs)`, ajoute une nouvelle entité du type
+ données. La valeur des attributs et relations est spécifiée en utilisant les
+ arguments nommés et positionnels.
+
+
+Création de workflow
+--------------------
+Les fonctions de création de workflow suivantes sont disponibles dans les scripts
+"repository" :
+
+* `add_state(name, stateof, initial=False, commit=False, **kwargs)`, ajoute un
+ nouvel état de workflow
+
+* `add_transition(name, transitionof, fromstates, tostate, requiredgroups=(), commit=False, **kwargs)`,
+ ajoute une nouvelle transtion de workflow
+
+Migration de configuration
+--------------------------
+Les fonctions de migration de configuration suivantes sont disponibles dans tout
+les scripts :
+
+* `option_renamed(oldname, newname)`, indique qu'une option a été renommée
+
+* `option_group_change(option, oldgroup, newgroup)`, indique qu'une option a
+ changé de groupe
+
+* `option_added(oldname, newname)`, indique qu'une option a été ajoutée
+
+* `option_removed(oldname, newname)`, indique qu'une option a été supprimée
+
+
+Autres fonctions de migration
+-----------------------------
+Ces fonctions ne sont utilisés que pour des opérations de bas niveau
+irréalisables autrement ou pour réparer des bases cassées lors de session
+interactive. Elles sont disponibles dans les scripts "repository".
+
+* `sqlexec(sql, args=None, ask_confirm=True)`, éxécute une requête sql
+ arbitraire, à n'utiliser
+
+* `add_entity_type_table(etype, commit=True)`
+* `add_relation_type_table(rtype, commit=True)`
+* `uninline_relation(rtype, commit=True)`
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/18-tests.en.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,38 @@
+.. -*- coding: utf-8 -*-
+
+Tests
+=====
+
+Écriture de tests unitaires
+---------------------------
+Le framework de test fournit principalement deux classes de tests dans le module
+`ginco.devtools.apptest`:
+
+* `EnvBasedTC`, pour simuler un environnement complet (web + repository)
+* `RepositoryBasedTC`, pour simuler un environnement de repository uniquement
+
+Ces deux classes ont quasiment la même interface et proposent un certain nombre de méthodes
+rendant l'écriture de test puissante et rapide.
+
+XXXFILLME describe API
+
+Dans la plupart des cas, vous allez vouloir hériter de `EnvBasedTC` pour écrire des tests
+unitaires ou fonctionnels pour vos entités, vues, crochets...
+
+
+Test des courriels de notifications
+```````````````````````````````````
+Lors de l'éxécution de tests les courriels potentiellement générés ne sont pas réellement
+envoyé mais se retrouve dans la liste `MAILBOX` du module `ginco.devtools.apptest`. Cette
+liste est remise à zéro au *setUp* de chaque test (par le setUp des classes `EnvBasedTC`
+et `RepositoryBasedTC`).
+
+Vous pouvez donc tester vos notifications en analysant le contenu de cette liste, qui
+contient des objets ayant deux attributs :
+* `recipients`, la liste des destinataires
+* `msg`, l'objet email.Message
+
+
+Tests automatiques
+------------------
+XXXFILLME
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/19-i18n.en.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,71 @@
+.. -*- coding: utf-8 -*-
+
+.. _Internationalisation:
+
+
+Internationalisation
+====================
+
+Le système d'internationalisation de l'interface web de CubicWeb est basé sur le
+système `GNU gettext`_.
+
+.. _`GNU gettext`: http://www.gnu.org/software/gettext/
+
+Messages à internationaliser
+----------------------------
+
+Marquage des messages à internaliser
+````````````````````````````````````
+Les chaines de caractères à internationaliser sont marqués par l'appel à la
+fonction `_` *OU* par la méthode équivalent de la requête dans le code python ou
+dans les expressions python de template TAL.
+
+Dans les templates cubicweb-tal, il est également possible d'insérer une chaine à
+traduire via les balises `i18n:content` et `i18n:replace`.
+
+De plus des messages correspondant aux entités/relations utilisés par le schéma
+de l'application seront automatiquement ajoutés.
+
+Renvoi d'un message internationalisé lors de la construction d'une page
+```````````````````````````````````````````````````````````````````````
+La fonction *built-in* `_` ne doit servir qu'**à marquer les messages à
+traduire**, non pas à récupérer une traduction. Il faut pour cela utiliser la
+méthode `_` de l'objet requête, sans quoi vous récupérerez l'identifiant de
+message au lieu de sa traduction dans la langue propre à la requête.1
+
+
+Gestion des catalogues de traduction
+------------------------------------
+Une fois l'application rendu internationalisable coté code, reste à gérer les
+catalogues de traductions. cubicweb-ctl intègre pour cela les commandes suivantes :
+
+* `i18nlibupdate`, met à jour les catalogues de messages *de la librairie
+ cubicweb*. Sauf si vous développez sur le framework (et non votre propre
+ application), vous ne devriez pas avoir à utiliser cette commande
+
+* `i18nupdate`, met à jour les catalogues de messages *du composant* (ou de tous
+ les composants). A la suite de cette commande, vous devez mettre à jour les
+ fichiers de traduction *.po* dans le sous-répertoire "i18n" de votre
+ template. Évidemment les traductions précédentes toujours utilisées ont été
+ conservées.
+
+* `i18ncompile`, recompile les catalogues de messages *d'une instance* (ou de
+ toutes les instances) après mise à jour des catalogues de son composant. Cela
+ est effectué automatiquement lors d'une création ou d'une mise à jour. Les
+ catalogues de messages compilés se trouvent dans le répertoire
+ "i18n/<lang>/LC_MESSAGES/cubicweb.mo" de l'application où `lang` est
+ l'identifiant de la langue sur 2 lettres ('en' ou 'fr' par exemple)
+
+
+Le cas classique
+````````````````
+Vous avez ajouté et/ou modifié des messages d'un composant utilisé par votre
+application (en ajoutant une nouvelle vue ou en ayant modifié le schéma par
+exemple) :
+
+1. `cubicweb-ctl i18nupdate <composant>`
+2. éditer les fichiers <composant>/xxx.po dans pour y rajouter les traductions
+ manquantes (`msgstr` vide)
+3. `hg ci -m "updated i18n catalogs"`
+4. `cubicweb-ctl i18n compile <monapplication>`
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/20-gae.en.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,19 @@
+.. -*- coding: utf-8 -*-
+
+.. _contents:
+
+==========================
+Google AppEngine Datastore
+==========================
+
+
+.. include:: 01-intro.en.txt
+.. include:: 02-install.en.txt
+.. include:: 03-create-app.en.txt
+.. include:: 04-develop-views.en.txt
+.. include:: 05-components.en.txt
+.. include:: 06-maintemplate.en.txt
+.. include:: 07-rss-xml.en.txt
+.. include:: 08-rql.en.txt
+.. include:: 09-urlrewrite.en.txt
+.. include:: 10-security.en.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/21-01-architecture.en.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,14 @@
+.. -*- coding: utf-8 -*-
+
+
+Architecture du serveur
+-----------------------
+
+.. image:: images/server-class-diagram.png
+
+`Diagramme ArgoUML`_
+
+[FIXME]
+Make a downloadable source of zargo file.
+
+.. _`Diagramme ArgoUML`: cubicweb.zargo
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/21-02-querier.en.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,62 @@
+.. -*- coding: utf-8 -*-
+
+Déroulement de l'éxecution d'une requête en multi-source avec insertion de sécurité
+```````````````````````````````````````````````````````````````````````````````````
+
+* 3 sources (system, ldap (Euser) et rql (Card)
+* permission en lecture Card is elle appartient à l'utilisateur
+
+Soit la requête de départ: ::
+
+ Any X,T WHERE X owned_by U, U login "syt", X title T
+
+1. récupération arbre de syntaxe et solution (+cache) ::
+
+ -> {X: Card, U: Euser}, {X: Blog, U: Euser}, {X: Bookmark, U: Euser}
+
+2. insertion sécurité ::
+
+ -> Any X,T WHERE X owned_by U, U login "syt", X title T, EXISTS(X owned_by UEID) / {X: Card, U: Euser}
+ Any X,T WHERE X owned_by U, U login "syt", X title T / {X: Blog, U: Euser}, {X: Bookmark, U: Euser}
+
+3. construction plan
+ 0. preprocessing (annotation des arbres de syntaxe)
+
+ 1. Any U WHERE U login "syt" / {U: Euser}
+ [system+ldap] => table1/varmap1{U:U2}
+
+ 2. Any X,T WHERE X owned_by U2, X title T / {X: Blog, U: Euser}, {X: Bookmark, U: Euser}
+ [varmap1|system] => TABLE2
+
+ 3 Deux alernatives:
+
+ 1. Any X,T WHERE X is Card, X title T {X: Card} ::
+
+ [system+rql] => table3/varmap3{X:X3, T:T3}
+
+ Any X3,T3 WHERE X3 owned_by U2, X3 title T3, EXISTS(X owned_by UEID) / {X3: Card, U2: Euser} ::
+
+ [(varmap1, varmap3)|system] => TABLE2
+
+ 2 Any X WHERE X is Card X owned_by U2, EXISTS(X owned_by UEID) / {X: Card, U2: Euser} ::
+
+ [varmap1|system] => EIDS
+
+ Any X,T WHERE X title T, X eid IN(EIDS) {X: Card} ::
+
+ [system+rql] => TABLE2
+
+ 4. renvoie contenu TABLE2.
+ Note : si aggrégat / tri / distinct TABLE2 est nécessairement une table temporaire et besoin d'une
+ étape AggrStep supplémentaire
+
+4. éxécution du plan
+
+5. [construction description]
+
+6. renvoie ResultSet
+
+Notes sur UNION
+```````````````
+
+* en multi-sources, les résultats des unions peuvent être mélangés
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/21-03-modules.en.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,253 @@
+.. -*- coding: utf-8 -*-
+
+
+:mod:`cubes.addressbook`
+========================
+
+.. automodule:: cubes.addressbook
+ :members:
+
+:mod:`cubes.basket`
+========================
+
+.. automodule:: cubes.basket
+ :members:
+
+:mod:`cubes.blog`
+========================
+
+.. automodule:: cubes.blog
+ :members:
+
+:mod:`cubes.book`
+========================
+
+.. automodule:: cubes.book
+ :members:
+
+:mod:`cubes.comment`
+========================
+
+.. automodule:: cubes.comment
+ :members:
+
+:mod:`cubes.company`
+========================
+
+.. automodule:: cubes.company
+ :members:
+
+
+:mod:`cubes.conference`
+========================
+
+.. automodule:: cubes.conference
+ :members:
+
+:mod:`cubes.email`
+========================
+
+.. automodule:: cubes.email
+ :members:
+
+:mod:`cubes.event`
+========================
+
+.. automodule:: cubes.event
+ :members:
+
+:mod:`cubes.expense`
+========================
+
+.. automodule:: cubes.expense
+ :members:
+
+
+:mod:`cubes.file`
+========================
+
+.. automodule:: cubes.file
+ :members:
+
+:mod:`cubes.folder`
+========================
+
+.. automodule:: cubes.folder
+ :members:
+
+:mod:`cubes.i18ncontent`
+========================
+
+.. automodule:: cubes.i18ncontent
+ :members:
+
+:mod:`cubes.invoice`
+========================
+
+.. automodule:: cubes.invoice
+ :members:
+
+:mod:`cubes.keyword`
+========================
+
+.. automodule:: cubes.keyword
+ :members:
+
+:mod:`cubes.link`
+========================
+
+.. automodule:: cubes.link
+ :members:
+
+:mod:`cubes.mailinglist`
+========================
+
+.. automodule:: cubes.mailinglist
+ :members:
+
+:mod:`cubes.person`
+========================
+
+.. automodule:: cubes.person
+ :members:
+
+:mod:`cubes.shopcart`
+========================
+
+.. automodule:: cubes.shopcart
+ :members:
+
+:mod:`cubes.skillmat`
+========================
+
+.. automodule:: cubes.skillmat
+ :members:
+
+:mod:`cubes.tag`
+========================
+
+.. automodule:: cubes.tag
+ :members:
+
+:mod:`cubes.task`
+========================
+
+.. automodule:: cubes.task
+ :members:
+
+:mod:`cubes.workcase`
+========================
+
+.. automodule:: cubes.workcase
+ :members:
+
+:mod:`cubes.workorder`
+========================
+
+.. automodule:: cubes.workorder
+ :members:
+
+:mod:`cubes.zone`
+========================
+
+.. automodule:: cubes.zone
+ :members:
+
+:mod:`cubicweb`
+===============
+
+.. automodule:: cubicweb
+ :members:
+
+:mod:`cubicweb.common`
+======================
+
+.. automodule:: cubicweb.common
+ :members:
+
+:mod:`cubicweb.devtools`
+========================
+
+.. automodule:: cubicweb.devtools
+ :members:
+
+:mod:`cubicweb.entities`
+========================
+
+.. automodule:: cubicweb.entities
+ :members:
+
+:mod:`cubicweb.etwist`
+======================
+
+.. automodule:: cubicweb.etwist
+ :members:
+
+:mod:`cubicweb.goa`
+===================
+
+.. automodule:: cubicweb.goa
+ :members:
+
+:mod:`cubicweb.schemas`
+=======================
+
+.. automodule:: cubicweb.schemas
+ :members:
+
+:mod:`cubicweb.server`
+======================
+
+.. automodule:: cubicweb.server
+ :members:
+
+:mod:`cubicweb.sobjects`
+========================
+
+.. automodule:: cubicweb.sobjects
+ :members:
+
+:mod:`cubicweb.web`
+===================
+
+.. automodule:: cubicweb.web
+ :members:
+
+:mod:`cubicweb.web.views`
+=========================
+
+.. automodule:: cubicweb.web.views
+ :members:
+
+
+:mod:`cubicweb.wsgi`
+====================
+
+.. automodule:: cubicweb.wsgi
+ :members:
+
+:mod:`indexer`
+==============
+
+.. automodule:: indexer
+ :members:
+
+:mod:`logilab`
+==============
+
+.. automodule:: logilab
+ :members:
+
+
+
+:mod:`rql`
+==========
+
+.. automodule:: rql
+ :members:
+
+:mod:`yams`
+===========
+
+.. automodule:: yams
+ :members:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/21-references.en.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,13 @@
+.. -*- coding: utf-8 -*-
+
+.. _contents:
+
+Références
+==========
+
+.. toctree::
+ :maxdepth: 1
+
+ 21-01-architecture.en.txt
+ 21-02-querier.en.txt
+ 21-03-modules.en.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/22-faq.en.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,55 @@
+.. -*- coding: utf-8 -*-
+
+Foire Aux Questions
+===================
+
+[FILL ME]
+
+* A quoi servent les crochets?
+
+ Les crochets sont appeles lorsqu'une requete RQL est executee. Cela
+ permet d'executer des actions specifiques lors d'un acces a la base
+ de donnees, ce qui donne un controle de la base de donnees afin de
+ prevenir l'insertion de `mauvaises` entites dans la base.
+
+* Quand utiliser un template HTML plutot qu'un composant graphique?
+
+ Un template HTML ne peut contenir de logique, il ne permettra donc
+ que de definir une vue statique. Un composant permet lui de gerer
+ plus de logique et d'operations sur le contexte dans lequel il
+ s'applique. Il faut donc bien reflechir avant de decider de l'un ou
+ de l'autre, mais vous avez la possibilite de choisir.
+
+* Comment mettre à jour une base de données après avoir modifié le schéma?
+
+ Cela dépend de ce qui a été modifié dans le schéma.
+
+ * Modification d'une relation non finale
+
+ * Modification d'une relation finale
+
+[TO COMPLETE]
+
+* Comment créer un utilisateur anonyme?
+
+ Cela vous permet d'acceder a votre site sans avoir besoin de vous authentifier.
+ Dans le fichier ``all-in-one.conf`` de votre instance, définir l'utilisateur
+ anonyme en initilisant les valeurs des variables suivantes ::
+
+ # login of the Erudi user account to use for anonymous user (if you want to
+ # allow anonymous)
+ anonymous-user=anon
+
+ # password of the Erudi user account matching login
+ anonymous-password=anon
+
+ Vous devez aussi vous assurer que cet utilisateur `anon` existe dans la base
+ de données, le plus simple étant de s'identifier sur votre application en
+ administrateur et de rajouter l'utilisateur `anon` via l'interface d'administration.
+
+* Quelle est la différence entre `AppRsetObject` et `AppObject` ?
+
+ La différence entre la classe `AppRsetObject` et la classe `AppObject` est que
+ les instances de la premières sont séléctionnées pour une requête et un "result
+ set" et alors que les secondes ne sont séléctionnées qu'en fonction de leur
+ identifiant.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/MERGE_ME-tut-create-app.en.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,386 @@
+.. -*- coding: utf-8 -*-
+
+
+Tutoriel : créer votre première application web pour Google AppEngine
+=====================================================================
+
+[TRANSLATE ME TO FRENCH]
+
+This tutorial will guide you step by step to build a blog application
+and discover the unique features of `LAX`. It assumes that you followed
+the :ref:`installation` guidelines and that both the `AppEngine SDK` and the
+`LAX` framework are setup on your computer.
+
+Creating a new application
+--------------------------
+
+We choosed in this tutorial to develop a blog as an example of web application
+and will go through each required steps/actions to have it running with `LAX`.
+When you installed `LAX`, you saw a directory named ``skel``. Make a copy of
+this directory and call it ``BlogDemo``.
+
+The location of this directory does not matter. But once decided, make sure your ``PYTHONPATH`` is properly set (:ref:`installation`).
+
+
+Defining a schema
+-----------------
+
+With `LAX`, the schema/datamodel is the core of the application. This is where
+you will define the type of content you have to hanlde in your application.
+
+Let us start with something simple and improve on it iteratively.
+
+In schema.py, we define two entities: ``Blog`` and ``BlogEntry``.
+
+::
+
+ class Blog(EntityType):
+ title = String(maxsize=50, required=True)
+ description = String()
+
+ class BlogEntry(EntityType):
+ title = String(maxsize=100, required=True)
+ publish_date = Date(default='TODAY')
+ text = String(fulltextindexed=True)
+ category = String(vocabulary=('important','business'))
+ entry_of = SubjectRelation('Blog', cardinality='?*')
+
+A Blog has a title and a description. The title is a string that is
+required by the class EntityType and must be less than 50 characters.
+The description is a string that is not constrained.
+
+A BlogEntry has a title, a publish_date and a text. The title is a
+string that is required and must be less than 100 characters. The
+publish_date is a Date with a default value of TODAY, meaning that
+when a BlogEntry is created, its publish_date will be the current day
+unless it is modified. The text is a string that will be indexed in
+the full-text index and has no constraint.
+
+A BlogEntry also has a relationship ``entry_of`` that link it to a
+Blog. The cardinality ``?*`` means that a BlogEntry can be part of
+zero or one Blog (``?`` means `zero or one`) and that a Blog can
+have any number of BlogEntry (``*`` means `any number including
+zero`). For completeness, remember that ``+`` means `one or more`.
+
+Running the application
+-----------------------
+
+Defining this simple schema is enough to get us started. Make sure you
+followed the setup steps described in detail in the installation
+chapter (especially visiting http://localhost:8080/_load as an
+administrator), then launch the application with the command::
+
+ python dev_appserver.py BlogDemo
+
+and point your browser at http://localhost:8080/ (if it is easier for
+you, use the on-line demo at http://lax.appspot.com/).
+
+.. image:: images/lax-book.00-login.en.png
+ :alt: login screen
+
+After you log in, you will see the home page of your application. It
+lists the entity types: Blog and BlogEntry. If these links read
+``blog_plural`` and ``blogentry_plural`` it is because
+internationalization (i18n) is not working for you yet. Please ignore
+this for now.
+
+.. image:: images/lax-book.01-start.en.png
+ :alt: home page
+
+Creating system entities
+------------------------
+You can only create new users if you decided not to use google authentication.
+
+
+[WRITE ME : create users manages permissions etc]
+
+
+
+Creating application entites
+----------------------------
+
+Create a Blog
+~~~~~~~~~~~~~
+
+Let us create a few of these entities. Click on the [+] at the right
+of the link Blog. Call this new Blog ``Tech-blog`` and type in
+``everything about technology`` as the description, then validate the
+form by clicking on ``Validate``.
+
+.. image:: images/lax-book.02-create-blog.en.png
+ :alt: from to create blog
+
+Click on the logo at top left to get back to the home page, then
+follow the Blog link that will list for you all the existing Blog.
+You should be seeing a list with a single item ``Tech-blog`` you
+just created.
+
+.. image:: images/lax-book.03-list-one-blog.en.png
+ :alt: displaying a list of a single blog
+
+Clicking on this item will get you to its detailed description except
+that in this case, there is not much to display besides the name and
+the phrase ``everything about technology``.
+
+.. image:: images/lax-book.04-detail-one-blog.en.png
+ :alt: displaying the detailed view of a blog
+
+Now get back to the home page by clicking on the top-left logo, then
+create a new Blog called ``MyLife`` and get back to the home page
+again to follow the Blog link for the second time. The list now
+has two items.
+
+.. image:: images/lax-book.05-list-two-blog.en.png
+ :alt: displaying a list of two blogs
+
+
+Create a BlogEntry
+~~~~~~~~~~~~~~~~~~
+
+Get back to the home page and click on [+] at the right of the link
+BlogEntry. Call this new entry ``Hello World`` and type in some text
+before clicking on ``Validate``. You added a new blog entry without
+saying to what blog it belongs. There is a box on the left entitled
+``actions``, click on the menu item ``modify``. You are back to the form
+to edit the blog entry you just created, except that the form now has
+another section with a combobox titled ``add relation``. Chose
+``entry_of`` in this menu and a second combobox appears where you pick
+``MyLife``.
+
+You could also have, at the time you started to fill the form for a
+new entity BlogEntry, hit ``Apply`` instead of ``Validate`` and the
+combobox titled ``add relation`` would have showed up.
+
+.. image:: images/lax-book.06-add-relation-entryof.en.png
+ :alt: editing a blog entry to add a relation to a blog
+
+Validate the changes by clicking ``Validate``. The entity BlogEntry
+that is displayed now includes a link to the entity Blog named
+``MyLife``.
+
+.. image:: images/lax-book.07-detail-one-blogentry.en.png
+ :alt: displaying the detailed view of a blogentry
+
+Remember that all of this was handled by the framework and that the
+only input that was provided so far is the schema. To get a graphical
+view of the schema, run the ``laxctl genschema BlogDemo`` command as
+explained in the installation section and point your browser to the
+URL http://localhost:8080/schema
+
+.. image:: images/lax-book.08-schema.en.png
+ :alt: graphical view of the schema (aka data-model)
+
+Site configuration
+------------------
+
+.. image:: images/lax-book.03-site-config-panel.en.png
+
+This panel allows you to configure the appearance of your application site.
+Six menus are available and we will go through each of them to explain how
+to use them.
+
+Navigation
+~~~~~~~~~~
+This menu provides you a way to adjust some navigation options depending on
+your needs, such as the number of entities to display by page of results.
+Follows the detailled list of available options:
+
+* navigation.combobox-limit: maximum number of entities to display in related
+ combo box (sample format: 23)
+* navigation.page-size: maximum number of objects displayed by page of results
+ (sample format: 23)
+* navigation.related-limit: maximum number of related entities to display in
+ the primary view (sample format: 23)
+* navigation.short-line-size: maximum number of characters in short description
+ (sample format: 23)
+
+UI
+~~
+This menu provides you a way to customize the user interface settings such as
+date format or encoding in the produced html.
+Follows the detailled list of available options:
+
+* ui.date-format : how to format date in the ui ("man strftime" for format description)
+* ui.datetime-format : how to format date and time in the ui ("man strftime" for format
+ description)
+* ui.default-text-format : default text format for rich text fields.
+* ui.encoding : user interface encoding
+* ui.fckeditor : should html fields being edited using fckeditor (a HTML WYSIWYG editor).
+ You should also select text/html as default text format to actually get fckeditor.
+* ui.float-format : how to format float numbers in the ui
+* ui.language : language of the user interface
+* ui.main-template : id of main template used to render pages
+* ui.site-title : site title, which is displayed right next to the logo in the header
+* ui.time-format : how to format time in the ui ("man strftime" for format description)
+
+
+Actions
+~~~~~~~
+This menu provides a way to configure the context in which you expect the actions
+to be displayed to the user and if you want the action to be visible or not.
+You must have notice that when you view a list of entities, an action box is
+available on the left column which display some actions as well as a drop-down
+menu for more actions.
+
+The context available are:
+
+* mainactions : actions listed in the left box
+* moreactions : actions listed in the `more` menu of the left box
+* addrelated : add actions listed in the left box
+* useractions : actions listed in the first section of drop-down menu
+ accessible from the right corner user login link
+* siteactions : actions listed in the second section of drop-down menu
+ accessible from the right corner user login link
+* hidden : select this to hide the specific action
+
+Boxes
+~~~~~
+The application has already a pre-defined set of boxes you can use right away.
+This configuration section allows you to place those boxes where you want in the
+application interface to customize it.
+
+The available boxes are:
+
+* actions box : box listing the applicable actions on the displayed data
+
+* boxes_blog_archives_box : box listing the blog archives
+
+* possible views box : box listing the possible views for the displayed data
+
+* rss box : RSS icon to get displayed data as a RSS thread
+
+* search box : search box
+
+* startup views box : box listing the configuration options available for
+ the application site, such as `Preferences` and `Site Configuration`
+
+Components
+~~~~~~~~~~
+[WRITE ME]
+
+Contextual components
+~~~~~~~~~~~~~~~~~~~~~
+[WRITE ME]
+
+Set-up a workflow
+-----------------
+
+Before starting, make sure you refresh your mind by reading [link to
+definition_workflow chapter].
+
+We want to create a workflow to control the quality of the BlogEntry
+submitted on your application. When a BlogEntry is created by a user
+its state should be `submitted`. To be visible to all, it needs to
+be in the state `published`. To move from `submitted` to `published`
+we need a transition that we can name `approve_blogentry`.
+
+We do not want every user to be allowed to change the state of a
+BlogEntry. We need to define a group of user, `moderators`, and
+this group will have appropriate permissions to approve BlogEntry
+to be published and visible to all.
+
+There are two ways to create a workflow, form the user interface,
+and also by defining it in ``migration/postcreate.py``. This script
+is executed each time a new ``./bin/laxctl db-init`` is done.
+If you create the states and transitions through the user interface
+this means that next time you will need to initialize the database
+you will have to re-create all the entities.
+We strongly recommand you create the workflow in ``migration\postcreate.py``
+and we will now show you how.
+The user interface would only be a reference for you to view the states
+and transitions but is not the appropriate interface to define your
+application workflow.
+
+Update the schema
+~~~~~~~~~~~~~~~~~
+To enable a BlogEntry to have a State, we have to define a relation
+``in_state`` in the schema of BlogEntry. Please do as follows, add
+the line ``in_state (...)``::
+
+ class BlogEntry(EntityType):
+ title = String(maxsize=100, required=True)
+ publish_date = Date(default='TODAY')
+ text_format = String(meta=True, internationalizable=True, maxsize=50,
+ default='text/rest', constraints=[format_constraint])
+ text = String(fulltextindexed=True)
+ category = String(vocabulary=('important','business'))
+ entry_of = SubjectRelation('Blog', cardinality='?*')
+ in_state = SubjectRelation('State', cardinality='1*')
+
+As you updated the schema, you will have re-execute ``./bin/laxctl db-init``
+to initialize the database and migrate your existing entities.
+[WRITE ABOUT MIGRATION]
+
+Create states, transitions and group permissions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+At the time the ``postcreate.py`` script is executed, several methods
+can be used. They are all defined in the ``class ServerMigrationHelper``.
+We will only discuss the method we use to create a wrokflow here.
+
+To define our workflow for BlogDemo, please add the following lines
+to ``migration/postcreate.py``::
+
+ _ = unicode
+
+ moderators = add_entity('EGroup', name=u"moderators")
+
+ submitted = add_state(_('submitted'), 'BlogEntry', initial=True)
+ published = add_state(_('published'), 'BlogEntry')
+
+ add_transition(_('approve_blogentry'), 'BlogEntry', (submitted,), published, ('moderators', 'managers'),)
+
+ checkpoint()
+
+``add_entity`` is used here to define the new group of users that we
+need to define the transitions, `moderators`.
+If this group required by the transition is not defined before the
+transition is created, it will not create the relation `transition
+require the group moderator`.
+
+``add_state`` expects as the first argument the name of the state you are
+willing to create, then the entity type on which the state can be applied,
+and an optionnal argument to set if the state is the initial state
+of the entity type or not.
+
+``add_transition`` expects as the first argument the name of the
+transition, then the entity type on which we can apply the transition,
+then the list of possible initial states from which the transition
+can be applied, the target state of the transition, and the permissions
+(e.g. list of the groups of users who can apply the transition).
+
+.. image:: images/lax-book.03-transitions-view.en.png
+
+You can now notice that in the actions box of a BlogEntry, the state
+is now listed as well as the possible transitions from this state
+defined by the workflow. This transition, as defined in the workflow,
+will only being displayed for the users belonging to the group
+moderators of managers.
+
+Change view permission
+~~~~~~~~~~~~~~~~~~~~~~
+
+
+
+Conclusion
+----------
+
+Exercise
+~~~~~~~~
+
+Create new blog entries in ``Tech-blog``.
+
+What we learned
+~~~~~~~~~~~~~~~
+
+Creating a simple schema was enough to set up a new application that
+can store blogs and blog entries.
+
+What is next ?
+~~~~~~~~~~~~~~
+
+Although the application is fully functionnal, its look is very
+basic. In the following section we will learn to create views to
+customize how data is displayed.
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/MERGE_ME-tut-create-gae-app.en.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,218 @@
+.. -*- coding: utf-8 -*-
+
+.. _tutorielGAE:
+
+Tutoriel : créer votre première application web pour Google AppEngine
+=====================================================================
+
+Ce tutoriel va vous guider pas à pas a construire une apllication web
+de gestion de Blog afin de vous faire découvrir les fonctionnalités de
+`CubicWeb`.
+
+Nous supposons que vous avec déjà suivi le guide :ref:`installationGAE`.
+
+
+Créez une nouvelle application
+------------------------------
+
+Nous choisissons dans ce tutoriel de développer un blog comme un exemple
+d'application web et nous allons expliciter toutes les étapes nécessaires
+à sa réalisation.
+
+::
+
+ cubicweb-ctl newgapp blogdemo
+
+`newgapp` est la commande permettant de créer une instance `CubicWeb` pour
+le datastore.
+
+Assurez-vous que votre variable d'environnement ``PYTHONPATH`` est correctement
+initialisée (:ref:`installationGAE`)
+
+Définissez un schéma
+--------------------
+
+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.
+
+Commençons par un schéma simple que nous améliorerons progressivemment.
+
+Une fois votre instance ``blogdemo`` crée, vous trouverez un fichier ``schema.py``
+contenant la définition des entités suivantes : ``Blog`` and ``BlogEntry``.
+
+::
+
+ class Blog(EntityType):
+ title = String(maxsize=50, required=True)
+ description = String()
+
+ class BlogEntry(EntityType):
+ title = String(maxsize=100, required=True)
+ publish_date = Date(default='TODAY')
+ text = String(fulltextindexed=True)
+ category = String(vocabulary=('important','business'))
+ 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 and 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`.
+
+Lancez l'application
+--------------------
+
+Définir ce simple schéma est suffisant pour commencer. Assurez-vous
+que vous avez suivi les étapes décrites dans la section installation
+(en particulier visitez http://localhost:8080/_load en tant qu'administrateur
+afin d'initialiser le datastore), puis lancez votre application avec la commande ::
+
+ python dev_appserver.py BlogDemo
+
+puis dirigez vous vers http://localhost:8080/ (ou si c'est plus facile
+vous pouvez utiliser la démo en ligne http://lax.appspot.com/).
+[FIXME] -- changer la demo en ligne en quelque chose qui marche (!)
+
+.. image:: images/lax-book.00-login.en.png
+ :alt: login screen
+
+Après vous être authentifié, vous arrivez sur la page d'accueil de votre
+application. Cette page liste les types d'entités accessibles dans votre
+application, en l'occurrence : Blog et Articles. Si vous lisez ``blog_plural``
+et ``blogentry_plural`` cela signifie que l'internationalisation (i18n)
+n'a pas encore fonctionné. Ignorez cela pour le moment.
+
+.. image:: images/lax-book.01-start.en.png
+ :alt: home page
+
+Créez des entités système
+-------------------------
+
+Vous ne pourrez créer de nouveaux utilisateurs que dans le cas où vous
+avez choisi de ne pas utiliser l'authentification Google.
+
+
+[WRITE ME : create users manages permissions etc]
+
+
+
+Créez des entités applicatives
+------------------------------
+
+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/lax-book.02-create-blog.en.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/lax-book.03-list-one-blog.en.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``
+
+
+.. image:: images/lax-book.04-detail-one-blog.en.png
+ :alt: displaying the detailed view of a blog
+
+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/lax-book.05-list-two-blog.en.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/lax-book.06-add-relation-entryof.en.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/lax-book.07-detail-one-blogentry.en.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, exécutez
+la commande ``laxctl genschema blogdemo`` et vous pourrez visualiser
+votre schéma a l'URL suivante : http://localhost:8080/schema
+
+.. image:: images/lax-book.08-schema.en.png
+ :alt: graphical view of the schema (aka data-model)
+
+
+Change view permission
+~~~~~~~~~~~~~~~~~~~~~~
+
+
+
+Conclusion
+----------
+
+Exercise
+~~~~~~~~
+
+Create new blog entries in ``Tech-blog``.
+
+What we learned
+~~~~~~~~~~~~~~~
+
+Creating a simple schema was enough to set up a new application that
+can store blogs and blog entries.
+
+What is next ?
+~~~~~~~~~~~~~~
+
+Although the application is fully functionnal, its look is very
+basic. In the following section we will learn to create views to
+customize how data is displayed.
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/conf.py Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,179 @@
+# -*- coding: utf-8 -*-
+#
+# Cubicweb documentation build configuration file, created by
+# sphinx-quickstart on Fri Oct 31 09:10:36 2008.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# The contents of this file are pickled, so don't put values in the namespace
+# that aren't pickleable (module imports are okay, they're removed automatically).
+#
+# All configuration values have a default value; values that are commented out
+# serve to show the default value.
+
+import sys, os
+
+# If your extensions are in another directory, add it here. If the directory
+# is relative to the documentation root, use os.path.abspath to make it
+# absolute, like shown here.
+#sys.path.append(os.path.abspath('some/directory'))
+
+# General configuration
+# ---------------------
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = ['sphinx.ext.autodoc']
+autoclass_content = 'both'
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['.templates']
+
+# The suffix of source filenames.
+source_suffix = '.txt'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General substitutions.
+project = 'Cubicweb'
+copyright = '2008, Logilab'
+
+# The default replacements for |version| and |release|, also used in various
+# other places throughout the built documents.
+#
+# The short X.Y version.
+version = '0.54'
+# The full version, including alpha/beta/rc tags.
+release = '3.0'
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+today_fmt = '%B %d, %Y'
+
+# List of documents that shouldn't be included in the build.
+#unused_docs = []
+
+# List of directories, relative to source directories, that shouldn't be searched
+# for source files.
+#exclude_dirs = []
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+
+# Options for HTML output
+# -----------------------
+
+# The style sheet to use for HTML and HTML Help pages. A file of that name
+# must exist either in Sphinx' static/ path, or in one of the custom paths
+# given in html_static_path.
+html_style = 'sphinx-default.css'
+
+# The name for this set of Sphinx documents. If None, it defaults to
+# "<project> v<release> documentation".
+html_title = '%s %s' % (project, release)
+
+# A shorter title for the navigation bar. Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (within the static path) to place at the top of
+# the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['.static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+html_use_modindex = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, the reST sources are included in the HTML build as _sources/<name>.
+#html_copy_source = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it. The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
+html_file_suffix = '.html'
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'Cubicwebdoc'
+
+
+# Options for LaTeX output
+# ------------------------
+
+# The paper size ('letter' or 'a4').
+#latex_paper_size = 'letter'
+
+# The font size ('10pt', '11pt' or '12pt').
+#latex_font_size = '10pt'
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, document class [howto/manual]).
+latex_documents = [
+ ('index', 'Cubicweb.tex', 'Cubicweb Documentation',
+ 'Logilab', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# Additional stuff for the LaTeX preamble.
+#latex_preamble = ''
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_use_modindex = True
--- a/doc/book/en/faq.en.txt Mon Nov 17 14:38:30 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Frequently Asked Questions
-==========================
-
-* Why does not LAX have a template language ?
-
- It does. Actually, you can use your preferred template language if you
- want. [explain how to use a template language]
-
- The reason template languages are not used in this book is that
- experience has proved us that using pure python was more efficient.
-
-* Why do you think using pure python is better than using a template language ?
-
- [copy answer from forum]
-
- code is easier to maintain, does not have to learn a new dialect
- each time, real function/classes etc -> real development
-
-* Why do you use the GPL license to prevent me from doing X ?
-
- [copy answer from forum]
-
-* LAX looks pretty recent. Is it stable ?
-
- [answer that framework has evolved over the past seven years and that
- data migrated from one schema to the other ever since]
-
-* Why is the RQL query language looking similar to X ?
-
- [copy answer from forum, explain why similar to sparql and why better
- than django and SQL]
-
-* which ajax library
-
- [we use mochikit and things on top of that]
-
-* `Error while publishing rest text ...`
-
- While modifying the description of an entity, you get an error message in
- the application `Error while publishing ...` for Rest text and plain text.
- The server returns a traceback like as follows ::
-
- 2008-10-06 15:05:08 - (erudi.rest) ERROR: error while publishing ReST text
- Traceback (most recent call last):
- File "/home/sandrine/src/blogdemo/ginco/common/rest.py", line 217, in rest_publish
- (...)
- File "/usr/lib/python2.5/codecs.py", line 817, in open
- file = __builtin__.open(filename, mode, buffering)
- TypeError: __init__() takes at most 3 arguments (4 given)
-
- This can be fixed by applying the patch described in :
- `Google group appengine <http://code.google.com/p/googleappengine/issues/detail?id=48>`_
-
-[ADD MORE FAQ]
Binary file doc/book/en/images/cbw-add-relation-entryof.en.png has changed
Binary file doc/book/en/images/cbw-create-blog.en.png has changed
Binary file doc/book/en/images/cbw-detail-one-blogentry.en.png has changed
Binary file doc/book/en/images/cbw-list-one-blog.en.png has changed
Binary file doc/book/en/images/cbw-list-two-blog.en.png has changed
Binary file doc/book/en/images/cbw-schema.en.png has changed
Binary file doc/book/en/images/cbw-update-primary-view.en.png has changed
--- a/doc/book/en/lax-book.en.txt Mon Nov 17 14:38:30 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-.. LAX documentation master file, created by sphinx-quickstart on Wed Sep 10 08:23:04 2008.
- You can adapt this file completely to your liking, but it should at least
- contain the root `toctree` directive.
-
-.. _contents:
-
-LAX book
-========
-
-
-.. toctree::
- :maxdepth: 2
-
-
- 01-intro.en.txt
- 02-install.en.txt
- 03-definition-schema.en.txt
- 04-develop-views.en.txt
- 05-components.en.txt
- 06-maintemplate.en.txt
- 07-rss-xml.en.txt
- 08-rql.en.txt
- 09-urlrewrite.en.txt
- 10-security.en.txt
- 11-definition-workflow.en.txt
- 12-internationalization.en.txt
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/makefile Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,91 @@
+MKHTML=mkdoc
+MKHTMLOPTS=--doctype article --target html --stylesheet standard
+SRC=.
+
+TXTFILES:= $(wildcard *.txt)
+TARGET := $(TXTFILES:.txt=.html)
+
+# You can set these sphinx variables from the command line.
+SPHINXOPTS =
+SPHINXBUILD = sphinx-build
+PAPER =
+
+# Internal variables for sphinx
+PAPEROPT_a4 = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS = -d build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+
+.PHONY: help clean html web pickle htmlhelp latex changes linkcheck
+
+help:
+ @echo "Please use \`make <target>' where <target> 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)"
+ @echo " htmlhelp to make HTML files and a HTML help project"
+ @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+ @echo " changes to make an overview over all changed/added/deprecated items"
+ @echo " linkcheck to check all external links for integrity"
+
+clean:
+ rm -rf apidoc/
+ rm -f *.html
+ -rm -rf build/*
+
+all: ${TARGET} apidoc 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:
+ mkdir -p build/html build/doctrees
+ $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) build/html
+ @echo
+ @echo "Build finished. The HTML pages are in build/html."
+
+pickle:
+ mkdir -p build/pickle build/doctrees
+ $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) build/pickle
+ @echo
+ @echo "Build finished; now you can process the pickle files or run"
+ @echo " sphinx-web build/pickle"
+ @echo "to start the sphinx-web server."
+
+web: pickle
+
+htmlhelp:
+ mkdir -p build/htmlhelp build/doctrees
+ $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) build/htmlhelp
+ @echo
+ @echo "Build finished; now you can run HTML Help Workshop with the" \
+ ".hhp project file in build/htmlhelp."
+
+latex:
+ mkdir -p build/latex build/doctrees
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) build/latex
+ @echo
+ @echo "Build finished; the LaTeX files are in build/latex."
+ @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
+ "run these through (pdf)latex."
+
+changes:
+ mkdir -p build/changes build/doctrees
+ $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) build/changes
+ @echo
+ @echo "The overview file is in build/changes."
+
+linkcheck:
+ mkdir -p build/linkcheck build/doctrees
+ $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) build/linkcheck
+ @echo
+ @echo "Link check complete; look for any errors in the above output " \
+ "or in build/linkcheck/output.txt."
--- a/doc/book/en/reference.en.txt Mon Nov 17 14:38:30 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-API Reference
-=============
-
-Schema API
-----------
-
-Base Types
-~~~~~~~~~~
-
-Base types are defined as a set in yams.BASE_TYPES that includes:
-`String`, `Int`, `Float`, `Boolean`, `Date`, `Time`, `Datetime`,
-`Interval`, `Password`, `Bytes`.
-
-See `yams' API <http://lax.logilab.org/apidoc>`_
-
-Constraints
-~~~~~~~~~~~
-
-Constraints are defined in yams.constraints and include:
-`UniqueConstraint`, `SizeConstraint`, `RegexpConstraint`,
-`BoundConstraint`, `IntervalBoundConstraint`,
-`StaticVocabularyConstraint`, `MultipleStaticVocabularyConstraint`.
-
-See `yams' API <http://lax.logilab.org/apidoc>`_
-
-Views API
----------
-
-See `yams' API <http://lax.logilab.org/apidoc>`_
-[WRITE ME]
-
--- a/doc/book/en/tut-create-app.en.txt Mon Nov 17 14:38:30 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,386 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-
-Tutoriel : créer votre première application web pour Google AppEngine
-=====================================================================
-
-[TRANSLATE ME TO FRENCH]
-
-This tutorial will guide you step by step to build a blog application
-and discover the unique features of `LAX`. It assumes that you followed
-the :ref:`installation` guidelines and that both the `AppEngine SDK` and the
-`LAX` framework are setup on your computer.
-
-Creating a new application
---------------------------
-
-We choosed in this tutorial to develop a blog as an example of web application
-and will go through each required steps/actions to have it running with `LAX`.
-When you installed `LAX`, you saw a directory named ``skel``. Make a copy of
-this directory and call it ``BlogDemo``.
-
-The location of this directory does not matter. But once decided, make sure your ``PYTHONPATH`` is properly set (:ref:`installation`).
-
-
-Defining a schema
------------------
-
-With `LAX`, the schema/datamodel is the core of the application. This is where
-you will define the type of content you have to hanlde in your application.
-
-Let us start with something simple and improve on it iteratively.
-
-In schema.py, we define two entities: ``Blog`` and ``BlogEntry``.
-
-::
-
- class Blog(EntityType):
- title = String(maxsize=50, required=True)
- description = String()
-
- class BlogEntry(EntityType):
- title = String(maxsize=100, required=True)
- publish_date = Date(default='TODAY')
- text = String(fulltextindexed=True)
- category = String(vocabulary=('important','business'))
- entry_of = SubjectRelation('Blog', cardinality='?*')
-
-A Blog has a title and a description. The title is a string that is
-required by the class EntityType and must be less than 50 characters.
-The description is a string that is not constrained.
-
-A BlogEntry has a title, a publish_date and a text. The title is a
-string that is required and must be less than 100 characters. The
-publish_date is a Date with a default value of TODAY, meaning that
-when a BlogEntry is created, its publish_date will be the current day
-unless it is modified. The text is a string that will be indexed in
-the full-text index and has no constraint.
-
-A BlogEntry also has a relationship ``entry_of`` that link it to a
-Blog. The cardinality ``?*`` means that a BlogEntry can be part of
-zero or one Blog (``?`` means `zero or one`) and that a Blog can
-have any number of BlogEntry (``*`` means `any number including
-zero`). For completeness, remember that ``+`` means `one or more`.
-
-Running the application
------------------------
-
-Defining this simple schema is enough to get us started. Make sure you
-followed the setup steps described in detail in the installation
-chapter (especially visiting http://localhost:8080/_load as an
-administrator), then launch the application with the command::
-
- python dev_appserver.py BlogDemo
-
-and point your browser at http://localhost:8080/ (if it is easier for
-you, use the on-line demo at http://lax.appspot.com/).
-
-.. image:: images/lax-book.00-login.en.png
- :alt: login screen
-
-After you log in, you will see the home page of your application. It
-lists the entity types: Blog and BlogEntry. If these links read
-``blog_plural`` and ``blogentry_plural`` it is because
-internationalization (i18n) is not working for you yet. Please ignore
-this for now.
-
-.. image:: images/lax-book.01-start.en.png
- :alt: home page
-
-Creating system entities
-------------------------
-You can only create new users if you decided not to use google authentication.
-
-
-[WRITE ME : create users manages permissions etc]
-
-
-
-Creating application entites
-----------------------------
-
-Create a Blog
-~~~~~~~~~~~~~
-
-Let us create a few of these entities. Click on the [+] at the right
-of the link Blog. Call this new Blog ``Tech-blog`` and type in
-``everything about technology`` as the description, then validate the
-form by clicking on ``Validate``.
-
-.. image:: images/lax-book.02-create-blog.en.png
- :alt: from to create blog
-
-Click on the logo at top left to get back to the home page, then
-follow the Blog link that will list for you all the existing Blog.
-You should be seeing a list with a single item ``Tech-blog`` you
-just created.
-
-.. image:: images/lax-book.03-list-one-blog.en.png
- :alt: displaying a list of a single blog
-
-Clicking on this item will get you to its detailed description except
-that in this case, there is not much to display besides the name and
-the phrase ``everything about technology``.
-
-.. image:: images/lax-book.04-detail-one-blog.en.png
- :alt: displaying the detailed view of a blog
-
-Now get back to the home page by clicking on the top-left logo, then
-create a new Blog called ``MyLife`` and get back to the home page
-again to follow the Blog link for the second time. The list now
-has two items.
-
-.. image:: images/lax-book.05-list-two-blog.en.png
- :alt: displaying a list of two blogs
-
-
-Create a BlogEntry
-~~~~~~~~~~~~~~~~~~
-
-Get back to the home page and click on [+] at the right of the link
-BlogEntry. Call this new entry ``Hello World`` and type in some text
-before clicking on ``Validate``. You added a new blog entry without
-saying to what blog it belongs. There is a box on the left entitled
-``actions``, click on the menu item ``modify``. You are back to the form
-to edit the blog entry you just created, except that the form now has
-another section with a combobox titled ``add relation``. Chose
-``entry_of`` in this menu and a second combobox appears where you pick
-``MyLife``.
-
-You could also have, at the time you started to fill the form for a
-new entity BlogEntry, hit ``Apply`` instead of ``Validate`` and the
-combobox titled ``add relation`` would have showed up.
-
-.. image:: images/lax-book.06-add-relation-entryof.en.png
- :alt: editing a blog entry to add a relation to a blog
-
-Validate the changes by clicking ``Validate``. The entity BlogEntry
-that is displayed now includes a link to the entity Blog named
-``MyLife``.
-
-.. image:: images/lax-book.07-detail-one-blogentry.en.png
- :alt: displaying the detailed view of a blogentry
-
-Remember that all of this was handled by the framework and that the
-only input that was provided so far is the schema. To get a graphical
-view of the schema, run the ``laxctl genschema BlogDemo`` command as
-explained in the installation section and point your browser to the
-URL http://localhost:8080/schema
-
-.. image:: images/lax-book.08-schema.en.png
- :alt: graphical view of the schema (aka data-model)
-
-Site configuration
-------------------
-
-.. image:: images/lax-book.03-site-config-panel.en.png
-
-This panel allows you to configure the appearance of your application site.
-Six menus are available and we will go through each of them to explain how
-to use them.
-
-Navigation
-~~~~~~~~~~
-This menu provides you a way to adjust some navigation options depending on
-your needs, such as the number of entities to display by page of results.
-Follows the detailled list of available options:
-
-* navigation.combobox-limit: maximum number of entities to display in related
- combo box (sample format: 23)
-* navigation.page-size: maximum number of objects displayed by page of results
- (sample format: 23)
-* navigation.related-limit: maximum number of related entities to display in
- the primary view (sample format: 23)
-* navigation.short-line-size: maximum number of characters in short description
- (sample format: 23)
-
-UI
-~~
-This menu provides you a way to customize the user interface settings such as
-date format or encoding in the produced html.
-Follows the detailled list of available options:
-
-* ui.date-format : how to format date in the ui ("man strftime" for format description)
-* ui.datetime-format : how to format date and time in the ui ("man strftime" for format
- description)
-* ui.default-text-format : default text format for rich text fields.
-* ui.encoding : user interface encoding
-* ui.fckeditor : should html fields being edited using fckeditor (a HTML WYSIWYG editor).
- You should also select text/html as default text format to actually get fckeditor.
-* ui.float-format : how to format float numbers in the ui
-* ui.language : language of the user interface
-* ui.main-template : id of main template used to render pages
-* ui.site-title : site title, which is displayed right next to the logo in the header
-* ui.time-format : how to format time in the ui ("man strftime" for format description)
-
-
-Actions
-~~~~~~~
-This menu provides a way to configure the context in which you expect the actions
-to be displayed to the user and if you want the action to be visible or not.
-You must have notice that when you view a list of entities, an action box is
-available on the left column which display some actions as well as a drop-down
-menu for more actions.
-
-The context available are:
-
-* mainactions : actions listed in the left box
-* moreactions : actions listed in the `more` menu of the left box
-* addrelated : add actions listed in the left box
-* useractions : actions listed in the first section of drop-down menu
- accessible from the right corner user login link
-* siteactions : actions listed in the second section of drop-down menu
- accessible from the right corner user login link
-* hidden : select this to hide the specific action
-
-Boxes
-~~~~~
-The application has already a pre-defined set of boxes you can use right away.
-This configuration section allows you to place those boxes where you want in the
-application interface to customize it.
-
-The available boxes are:
-
-* actions box : box listing the applicable actions on the displayed data
-
-* boxes_blog_archives_box : box listing the blog archives
-
-* possible views box : box listing the possible views for the displayed data
-
-* rss box : RSS icon to get displayed data as a RSS thread
-
-* search box : search box
-
-* startup views box : box listing the configuration options available for
- the application site, such as `Preferences` and `Site Configuration`
-
-Components
-~~~~~~~~~~
-[WRITE ME]
-
-Contextual components
-~~~~~~~~~~~~~~~~~~~~~
-[WRITE ME]
-
-Set-up a workflow
------------------
-
-Before starting, make sure you refresh your mind by reading [link to
-definition_workflow chapter].
-
-We want to create a workflow to control the quality of the BlogEntry
-submitted on your application. When a BlogEntry is created by a user
-its state should be `submitted`. To be visible to all, it needs to
-be in the state `published`. To move from `submitted` to `published`
-we need a transition that we can name `approve_blogentry`.
-
-We do not want every user to be allowed to change the state of a
-BlogEntry. We need to define a group of user, `moderators`, and
-this group will have appropriate permissions to approve BlogEntry
-to be published and visible to all.
-
-There are two ways to create a workflow, form the user interface,
-and also by defining it in ``migration/postcreate.py``. This script
-is executed each time a new ``./bin/laxctl db-init`` is done.
-If you create the states and transitions through the user interface
-this means that next time you will need to initialize the database
-you will have to re-create all the entities.
-We strongly recommand you create the workflow in ``migration\postcreate.py``
-and we will now show you how.
-The user interface would only be a reference for you to view the states
-and transitions but is not the appropriate interface to define your
-application workflow.
-
-Update the schema
-~~~~~~~~~~~~~~~~~
-To enable a BlogEntry to have a State, we have to define a relation
-``in_state`` in the schema of BlogEntry. Please do as follows, add
-the line ``in_state (...)``::
-
- class BlogEntry(EntityType):
- title = String(maxsize=100, required=True)
- publish_date = Date(default='TODAY')
- text_format = String(meta=True, internationalizable=True, maxsize=50,
- default='text/rest', constraints=[format_constraint])
- text = String(fulltextindexed=True)
- category = String(vocabulary=('important','business'))
- entry_of = SubjectRelation('Blog', cardinality='?*')
- in_state = SubjectRelation('State', cardinality='1*')
-
-As you updated the schema, you will have re-execute ``./bin/laxctl db-init``
-to initialize the database and migrate your existing entities.
-[WRITE ABOUT MIGRATION]
-
-Create states, transitions and group permissions
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-At the time the ``postcreate.py`` script is executed, several methods
-can be used. They are all defined in the ``class ServerMigrationHelper``.
-We will only discuss the method we use to create a wrokflow here.
-
-To define our workflow for BlogDemo, please add the following lines
-to ``migration/postcreate.py``::
-
- _ = unicode
-
- moderators = add_entity('EGroup', name=u"moderators")
-
- submitted = add_state(_('submitted'), 'BlogEntry', initial=True)
- published = add_state(_('published'), 'BlogEntry')
-
- add_transition(_('approve_blogentry'), 'BlogEntry', (submitted,), published, ('moderators', 'managers'),)
-
- checkpoint()
-
-``add_entity`` is used here to define the new group of users that we
-need to define the transitions, `moderators`.
-If this group required by the transition is not defined before the
-transition is created, it will not create the relation `transition
-require the group moderator`.
-
-``add_state`` expects as the first argument the name of the state you are
-willing to create, then the entity type on which the state can be applied,
-and an optionnal argument to set if the state is the initial state
-of the entity type or not.
-
-``add_transition`` expects as the first argument the name of the
-transition, then the entity type on which we can apply the transition,
-then the list of possible initial states from which the transition
-can be applied, the target state of the transition, and the permissions
-(e.g. list of the groups of users who can apply the transition).
-
-.. image:: images/lax-book.03-transitions-view.en.png
-
-You can now notice that in the actions box of a BlogEntry, the state
-is now listed as well as the possible transitions from this state
-defined by the workflow. This transition, as defined in the workflow,
-will only being displayed for the users belonging to the group
-moderators of managers.
-
-Change view permission
-~~~~~~~~~~~~~~~~~~~~~~
-
-
-
-Conclusion
-----------
-
-Exercise
-~~~~~~~~
-
-Create new blog entries in ``Tech-blog``.
-
-What we learned
-~~~~~~~~~~~~~~~
-
-Creating a simple schema was enough to set up a new application that
-can store blogs and blog entries.
-
-What is next ?
-~~~~~~~~~~~~~~
-
-Although the application is fully functionnal, its look is very
-basic. In the following section we will learn to create views to
-customize how data is displayed.
-
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/01-introduction.fr.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,343 @@
+.. -*- 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'<h1>%s</h1>' % html_escape(entity.dc_title()))
+
+ def content_format(self, entity):
+ return entity.view('reledit', rtype='content_format')
+
+ def cell_call(self, row, col):
+ entity = self.entity(row, col)
+
+ # display entity attributes with prefixes
+ self.w(u'<h1>%s</h1>' % entity.title)
+ self.w(u'<p>published on %s</p>' % entity.publish_date.strftime('%Y-%m-%d'))
+ self.w(u'<p>%s</p>' % entity.content)
+
+ # display relations
+ siderelations = []
+ if self.main_related_section:
+ self.render_entity_relations(entity, siderelations)
+
+.. note::
+ 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é.
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/02-foundation.fr.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,431 @@
+.. -*- 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 (`EProperty`)
+ * 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
--- a/doc/book/fr/02-install.fr.txt Mon Nov 17 14:38:30 2008 -0800
+++ /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
-
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/03-01-bis-installation.fr.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,79 @@
+.. -*- coding: utf-8 -*-
+
+.. _installationGAE:
+
+Installation de `CubicWeb` pour GoogleAppEngine
+===============================================
+
+Qu'est-ce que `LAX` ?
+=======================
+
+`LAX` (Logilab Appengine eXtension) est un framework d'application
+web basé sur `Google AppEngine`.
+
+`LAX` est un portage de la partie web de la plate-forme applicative
+développée par Logilab depuis 2001. Cette plate-forme publie des
+données tirées de bases SQL, d'annuaires LDAP et de systèmes de
+gestion de version. En avril 2008, elle a été portée pour fonctionner
+sur le "datastore" de `Google AppEngine`.
+
+XXX: faire un parallèle entre Django/GAE et LAX/GAE
+
+
+Téléchargement des sources
+==========================
+
+- Les sources de `Google AppEngine` peuvent être récupérées à l'adresse
+ suivante : http://code.google.com/appengine/downloads.html
+
+- Les sources de `LAX` se trouvent à l'adresse suivante :
+ http://lax.logilab.org/
+
+
+Installation
+============
+
+Une fois décompactée, l'archive `lax-0.1.0-alpha.tar.gz`, on obtient
+l'arborescence suivante::
+
+ .
+ |-- app.yaml
+ |-- custom.py
+ |-- data
+ |-- ginco/
+ |-- i18n/
+ |-- logilab/
+ |-- main.py
+ |-- mx/
+ |-- rql/
+ |-- schema.py
+ |-- simplejson/
+ |-- tools/
+ | |-- generate_schema_img.py
+ | `-- i18ncompile.py
+ |-- views.py
+ |-- yams/
+ `-- yapps/
+
+
+On retrouve le squelette d'une application web de `Google AppEngine`
+(fichiers ``app.yaml``, ``main.py`` en particulier) avec les dépendances
+supplémentaires nécessaires à l'utilisation du framework `LAX`
+
+
+Lancement de l'application de base
+==================================
+
+Plusieurs répertoires doivent être accessibles via la variable
+d'environnement ``PYTHONPATH`` ::
+
+ $ export PYTHONPATH=/path/to/google_appengine:/path/to/google_appengine/lib/yaml/lib:/path/to/myapp/
+
+Le répertoire yaml n'est nécessaire que pour le lancement des scripts
+qui se trouvent dans lax/tools et pour l'exécution des tests unitaires.
+
+Pour démarrer::
+
+ $ python /path/to/google_appengine/dev_appserver.py /path/to/lax
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/03-01-installation.fr.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,150 @@
+.. -*- 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
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/03-02-create-instance.fr.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,127 @@
+.. -*- 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
+ hg init moncube
+ cd moncube
+ 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).
+
+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
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/03-03-cubicweb-ctl.fr.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,121 @@
+.. -*- 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 <commande> [options commande] <arguments commandes>
+
+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 <commande> --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
+-------------------------------------------------
+* ``i18nlibupdate``, regénère les catalogues de messages de la librairie CubicWeb
+* ``i18nupdate``, regénère les catalogues de messages d'un composant
+* ``i18ncompile``, 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 <nom_cube> <nom_instance>
+
+Cette commande va creer les fichiers de configuration d'une instance dans
+``~/etc/cubicweb.d/<nom_instance>``.
+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 <nom_cube>
+
+Cette commande va creer un nouveau cube dans ``/path/to/forest/cubicweb/cubes/<nom_cube>``.
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/03-04-mercurial.fr.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,112 @@
+.. -*- 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/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/03-setup.fr.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,15 @@
+.. -*- 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
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/04-01-schema-stdlib.fr.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,70 @@
+.. -*- 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"
+``````````````````
+
+* `EUser`, utilisateurs du système
+* `EGroup`, groupes d'utilisateurs
+* `EEType`, types d'entité
+* `ERType`, 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
+
+* `EProperty`, utilisé pour configurer l'application
+* `EPermission`, 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.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/04-02-schema-definition.fr.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,348 @@
+.. -*- 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` (`EUser`) (quel utilisateur a créé l'entité)
+
+ - `owned_by` (`EUser`) (à qui appartient l'entité, par défaut le
+ créateur mais pas forcément et il peut exister plusieurs propriétaires)
+
+ - `is` (`EEType`)
+
+
+* 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 = 'EUser'
+
+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')
+
+* `symetric` : 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_<ACTION>_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 <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é `EPermission` 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 EPermission(MetaEntityType):
+ """entity type that may be used to construct some advanced security configuration
+ """
+ name = String(required=True, indexed=True, internationalizable=True, maxsize=100)
+ require_group = SubjectRelation('EGroup', cardinality='+*',
+ description=_('groups to which the permission is granted'))
+ require_state = SubjectRelation('State',
+ description=_("entity'state in which the permission is applyable"))
+ # can be used on any entity
+ require_permission = ObjectRelation('**', cardinality='*1', composite='subject',
+ description=_("link a permission to the entity. This "
+ "permission should be used in the security "
+ "definition of the entity's type to be useful."))
+
+
+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é `EPermission` 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é `EPermission`, 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_<ACTION>_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.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/04-define-schema.fr.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,21 @@
+.. -*- 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 "<type d'entité sujet>
+<type de relation> <type d'entité objet>". 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
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/05-01-views-stdlib.fr.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,65 @@
+.. -*- 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 (<ul>) 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 (<table>) 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/05-define-views.fr.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,247 @@
+.. -*- 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.entity(row, col)
+ 09. self.w(u'<h1>%s</h1>' % entity.title)
+ 10. self.w(u'<p>published on %s in category %s</p>' % \
+ 11. (entity.publish_date.strftime('%Y-%m-%d'), entity.category))
+ 12. self.w(u'<p>%s</p>' % entity.text)
+
+The above source code defines a new primary view (`line 03`) for
+``BlogEntry`` (`line 05`).
+
+Since views are applied to resultsets and resulsets can be tables of
+data, it is needed to recover the entity from its (row,col)
+coordinates (`line 08`). We will get to this in more detail later.
+
+The view has a ``self.w()`` method that is used to output data. Here `lines
+09-12` output HTML tags and values of the entity's attributes.
+
+When displaying same blog entry as before, you will notice that the
+page is now looking much nicer.
+
+.. image:: images/lax-book.09-new-view-blogentry.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.entity(row, col)
+ 07. self.w(u'<h1>%s</h1>' % entity.title)
+ 08. self.w(u'<p>%s</p>' % entity.description)
+ 09. rset = self.req.execute('Any E WHERE E entry_of B, B eid "%s"' % entity.eid)
+ 10. self.wview('primary', rset)
+
+In the above source code, `lines 01-08` are similar to the previous
+view we defined.
+
+At `line 09`, a simple request in made to build a resultset with all
+the entities linked to the current ``Blog`` entity by the relationship
+``entry_of``. The part of the framework handling the request knows
+about the schema and infer that such entities have to be of the
+``BlogEntry`` kind and retrieves them.
+
+The request returns a selection of data called a resultset. At
+`line 10` the view 'primary' is applied to this resultset to output
+HTML.
+
+**This is to be compared to interfaces and protocols in object-oriented
+languages. Applying a given view to all the entities of a resultset only
+requires the availability, for each entity of this resultset, of a
+view with that name that can accepts the entity.**
+
+Assuming we added entries to the blog titled `MyLife`, displaying it
+now allows to read its description and all its entries.
+
+.. image:: images/lax-book.10-blog-with-two-entries.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 `<div>` vides (par vide
+j'entend sans contenu dans la balise, il peut y avoir des attributs), faut
+toujours mettre `<div></div>` même s'il n'y a rien dedans, et non `<div/>`.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/06-define-workflows.fr.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,154 @@
+.. -*- coding: utf-8 -*-
+
+Définition de workflow
+======================
+On peut mettre une condition rql ou/et un groupe auquel doit appartenir l'utilisateur.
+
+Si on met à la fois un(ou plusieurs) groupe et une condition RQL, il faut que les deux soient respectés.
+
+Si on met plusieurs groupes, il faut que l'utilisateur soit dans un des groupes.
+
+Pour la condition RQL sur une transition, on peut y mettre les substitutions suivantes :
+
+* `%(eid)s`, eid de l'objet
+* `%(ueid)s`, eid de l'utilisateur qui fait la requête
+* `%(seid)s`, eid de l'état courant de l'objet
+
+Dans le script de création d'un workflow, penser à mettre `_()` autour des noms d'états et de transitions
+pour que ceux si soient pris en compte par les scripts de gestion des catalogues i18n.
+
+General
+-------
+
+A workflow can be defined in a `LAX` application thanks to the system
+entities ``State`` and ``Transition``. Those are defined within all
+LAX application and can be set-up through the main administrator interface.
+
+Once your schema is defined, you can start creating the set of states and
+the required transitions for your applications entities.
+
+You first need to define the states and then the transitions between those
+to complete your workflow.
+
+A ``State`` defines the status of an entity. While creating a new state,
+you will be first given the option to select the entity type the state
+can be applied to. By choosing ``Apply``, a new section will be displayed
+in the editing screen to enable you to add relation to the state you are
+creating.
+
+A ``Transition`` is also based on an entity type it can be applied to.
+By choosing ``Apply``, a new section will be displayed in the editing
+screen to enable you to add relation to the transition you are
+creating.
+
+At the transition level you will also define the group of user which can
+aplly this transition to an object.
+
+
+Example of a simple workflow
+----------------------------
+
+Please see the tutorial to view and example of a simple workflow.
+
+
+[Create a simple workflow for BlogDemo, to have a moderator approve new blog
+entry to be published. This implies, specify a dedicated group of blog
+moderator as well as hide the view of a blog entry to the user until
+it reaches the state published]
+
+Set-up a workflow
+-----------------
+
+Before starting, make sure you refresh your mind by reading [link to
+definition_workflow chapter].
+
+We want to create a workflow to control the quality of the BlogEntry
+submitted on your application. When a BlogEntry is created by a user
+its state should be `submitted`. To be visible to all, it needs to
+be in the state `published`. To move from `submitted` to `published`
+we need a transition that we can name `approve_blogentry`.
+
+We do not want every user to be allowed to change the state of a
+BlogEntry. We need to define a group of user, `moderators`, and
+this group will have appropriate permissions to approve BlogEntry
+to be published and visible to all.
+
+There are two ways to create a workflow, form the user interface,
+and also by defining it in ``migration/postcreate.py``. This script
+is executed each time a new ``./bin/laxctl db-init`` is done.
+If you create the states and transitions through the user interface
+this means that next time you will need to initialize the database
+you will have to re-create all the entities.
+We strongly recommand you create the workflow in ``migration\postcreate.py``
+and we will now show you how.
+The user interface would only be a reference for you to view the states
+and transitions but is not the appropriate interface to define your
+application workflow.
+
+Update the schema
+~~~~~~~~~~~~~~~~~
+To enable a BlogEntry to have a State, we have to define a relation
+``in_state`` in the schema of BlogEntry. Please do as follows, add
+the line ``in_state (...)``::
+
+ class BlogEntry(EntityType):
+ title = String(maxsize=100, required=True)
+ publish_date = Date(default='TODAY')
+ text_format = String(meta=True, internationalizable=True, maxsize=50,
+ default='text/rest', constraints=[format_constraint])
+ text = String(fulltextindexed=True)
+ category = String(vocabulary=('important','business'))
+ entry_of = SubjectRelation('Blog', cardinality='?*')
+ in_state = SubjectRelation('State', cardinality='1*')
+
+As you updated the schema, you will have re-execute ``./bin/laxctl db-init``
+to initialize the database and migrate your existing entities.
+[WRITE ABOUT MIGRATION]
+
+Create states, transitions and group permissions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+At the time the ``postcreate.py`` script is executed, several methods
+can be used. They are all defined in the ``class ServerMigrationHelper``.
+We will only discuss the method we use to create a wrokflow here.
+
+To define our workflow for BlogDemo, please add the following lines
+to ``migration/postcreate.py``::
+
+ _ = unicode
+
+ moderators = add_entity('EGroup', name=u"moderators")
+
+ submitted = add_state(_('submitted'), 'BlogEntry', initial=True)
+ published = add_state(_('published'), 'BlogEntry')
+
+ add_transition(_('approve_blogentry'), 'BlogEntry', (submitted,), published, ('moderators', 'managers'),)
+
+ checkpoint()
+
+``add_entity`` is used here to define the new group of users that we
+need to define the transitions, `moderators`.
+If this group required by the transition is not defined before the
+transition is created, it will not create the relation `transition
+require the group moderator`.
+
+``add_state`` expects as the first argument the name of the state you are
+willing to create, then the entity type on which the state can be applied,
+and an optionnal argument to set if the state is the initial state
+of the entity type or not.
+
+``add_transition`` expects as the first argument the name of the
+transition, then the entity type on which we can apply the transition,
+then the list of possible initial states from which the transition
+can be applied, the target state of the transition, and the permissions
+(e.g. list of the groups of users who can apply the transition).
+
+.. image:: images/lax-book.03-transitions-view.fr.png
+
+You can now notice that in the actions box of a BlogEntry, the state
+is now listed as well as the possible transitions from this state
+defined by the workflow. This transition, as defined in the workflow,
+will only being displayed for the users belonging to the group
+moderators of managers.
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/07-01-define-entities.fr.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,168 @@
+.. -*- coding: utf-8 -*-
+
+Paramétrages et extensions spécifiques
+--------------------------------------
+
+Valeurs par défaut dynamiques
+`````````````````````````````
+Il est possible de définir dans le schéma des valeurs par défaut *statiques*.
+Il est également possible de définir des valeurs par défaut *dynamiques* en
+définissant sur la classe d'entité une méthode `default_<nom attribut>` pour
+un attribut donnée.
+
+
+Contrôle des attributs chargés et du tri par défaut
+```````````````````````````````````````````````````
+* l'attribut de classe `fetch_attrs` permet de définir sur une classe d'entité
+ la liste des noms des attributs ou relations devant être chargés
+ automatiquement lors de la récupération d'entité(s) de ce type. Dans le cas
+ des relations, on est limité aux relations *sujets de cardinalité `?` ou `1`*.
+
+* la méthode de classe `fetch_order(attr, var)` prend en argument un nom
+ d'attribut (ou de relation) et un nom de variable et doit retourner une chaine
+ à utiliser dans la close "ORDERBY" d'une requête RQL pour trier
+ automatiquement les listes d'entités de ce type selon cet attribut, ou `None`
+ si l'on ne veut pas de tri sur l'attribut passé en argument. Par défaut les
+ entités sont triées selon leur date de création
+
+* la méthode de classe `fetch_unrelated_order(attr, var)` est similaire à la
+ méthode `fetch_order` mais est utilisée essentiellement pour contrôler le tri
+ des listes déroulantes permettant de créer des relations dans la vue d'édition
+ d'une entité
+
+La fonction `fetch_config(fetchattrs, mainattr=None)` permet de simplifier la
+définition des attributs à précharger et du tri en retournant une liste des
+attributs à précharger (en considérant ceux de la classe `AnyEntity`
+automatiquement) et une fonction de tri sur l'attribut "principal" (le 2eme
+argument si spécifié ou sinon le premier attribut de la liste `fetchattrs`).
+Cette fonction est définie dans le package `ginco.entities`.
+
+Par exemple : ::
+
+ class Transition(AnyEntity):
+ """..."""
+ id = 'Transition'
+ fetch_attrs, fetch_order = fetch_config(['name'])
+
+Indique que pour le type d'entité "Transition" il faut précharger l'attribut
+"name" et trier par défaut selon cet attribut.
+
+
+Contrôle des formulaires d'édition
+``````````````````````````````````
+Il est possible de contrôler les attributs/relations dans la vue d'édition
+simple ou multiple à l'aide des *rtags* suivants :
+
+* `primary`, indique qu'un attribut ou une relation doit être incorporé dans
+ les formulaires d'édition simple et multiple. Dans le cas d'une relation,
+ le formulaire d'édition de l'entité liée sera inclus dans le formulaire
+
+* `secondary`, indique qu'un attribut ou une relation doit être incorporé dans
+ le formulaire d'édition simple uniquement. Dans le cas d'une relation,
+ le formulaire d'édition de l'entité liée sera inclus dans le formulaire
+
+* `generic`, indique qu'une relation doit être incorporé dans le formulaire
+ d'édition simple dans la boite générique d'ajout de relation
+
+* `generated`, indique qu'un attribut est caculé dynamiquement ou autre, et
+ qu'il ne doit donc pas être présent dans les formulaires d'édition
+
+Au besoin il est possible de surcharger la méthode
+`relation_category(rtype, x='subject')` pour calculer dynamiquement la catégorie
+d'édition d'une relation.
+
+
+Contrôle de la boîte "add_related"
+``````````````````````````````````
+La boite `add related` est une boite automatique proposant de créer une entité
+qui sera automatiquement liée à l'entité de départ (le contexte dans lequel
+s'affiche la boite). Par défaut, les liens présents dans cette boite sont
+calculés en fonction des propriétés du schéma de l'entité visualisée, mais il
+est possible de les spécifier explicitement à l'aide des *rtags* suivants :
+
+* `link`, indique qu'une relation est généralement créée vers une entité
+ existante et qu'il ne faut donc pas faire apparaitre de lien pour cette
+ relation
+
+* `create`, indique qu'une relation est généralement créée vers de nouvelles
+ entités et qu'il faut donc faire apparaitre un lien pour créer une nouvelle
+ entité et la lier automatiquement
+
+Au besoin il est possible de surcharger la méthode
+`relation_mode(rtype, targettype, x='subject')` pour caculer dynamiquement la
+catégorie de création d'une relation.
+
+A noter également que si au moins une action dans la catégorie "addrelated" est
+trouvée pour le contexte courant, le fonctionnement automatique est désactivé
+en faveur du fonctionnement explicite (i.e. affichage des actions de la
+catégorie "addrelated" uniquement).
+
+Contrôle des formulaires de filtrage de table
+`````````````````````````````````````````````
+La vue "table" par défaut gère dynamiquement un formulaire de filtrage du
+contenu de celle-ci. L'algorithme est le suivant :
+
+1. on considère que la première colonne contient les entités à restreindre
+2. on recupère la première entité de la table (ligne 0) pour "représenter"
+ toutes les autres
+3. pour toutes les autres variables définies dans la requête originale :
+
+ 1. si la variable est liée à la variable principale par au moins une
+ n'importe quelle relation
+ 2. on appelle la méthode `filterform_vocabulary(rtype, x)` sur l'entité
+ et si rien est retourné (ou plus exactement un tuple de valeur `None`,
+ voir ci-dessous) on passe à la variable suivante, sinon un élément de
+ formulaire de filtrage sera créé avec les valeurs de vocabulaire
+ retournées
+
+4. il n'y a pas d'autres limitations sur le rql, il peut comporter des clauses
+ de tris, de groupes... Des fonctions javascripts sont utilisées pour
+ regénérer une requête à partir de la requête de départ et des valeurs
+ séléctionnées dans les filtres de formulaire.
+
+
+La méthode `filterform_vocabulary(rtype, x, var, rqlst, args, cachekey)` prend
+en argument le nom d'une relation et la "cible", qui indique si l'entité sur
+laquelle la méthode est appellée est sujet ou objet de la relation. Elle doit
+retourner :
+
+* un 2-uple de None si elle ne sait pas gérer cette relation
+
+* un type et une liste contenant le vocabulaire
+
+ * la liste doit contenir des couples (valeur, label)
+ * le type indique si la valeur désigne un nombre entier (`type == 'int'`), une
+ chaîne de caractères (`type == 'string'`) ou une entité non finale (`type
+ == 'eid'`)
+
+Par exemple dans notre application de gestion de tickets, on veut pouvoir
+filtrés ceux-ci par :
+
+* type
+* priorité
+* état (in_state)
+* étiquette (tags)
+* version (done_in)
+
+On définit donc la méthode suivante : ::
+
+
+ class Ticket(AnyEntity):
+
+ ...
+
+ def filterform_vocabulary(self, rtype, x, var, rqlst, args, cachekey):
+ _ = self.req._
+ if rtype == 'type':
+ return 'string', [(x, _(x)) for x in ('bug', 'story')]
+ if rtype == 'priority':
+ return 'string', [(x, _(x)) for x in ('minor', 'normal', 'important')]
+ if rtype == 'done_in':
+ rql = insert_attr_select_relation(rqlst, var, rtype, 'num')
+ return 'eid', self.req.execute(rql, args, cachekey)
+ return super(Ticket, self).filterform_vocabulary(rtype, x, var, rqlst,
+ args, cachekey)
+
+
+NOTE: Le support du filtrage sur les étiquettes et l'état est installé
+automatiquement, pas besoin de le gérer ici.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/07-data-as-objects.fr.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,142 @@
+.. -*- coding: utf-8 -*-
+
+
+Manipulation des données stockées
+=================================
+
+Les classes `Entity` et `AnyEntity`
+-----------------------------------
+Pour fournir un comportement spécifique à un type d'entité, il suffit de définir
+une classe héritant de la class `ginco.entities.AnyEntity`. En général il faut
+définir ces classes dans un module du package `entities` d'une application pour
+qu'elle soit disponible à la fois coté serveur et coté client.
+
+La classe `AnyEntity` est une classe chargée dynamiquement héritant de la classe
+de base `Entity` (`ginco.common.entity`). On définit une sous-classe pour
+ajouter des méthodes ou spécialiser les comportements d'un type d'entité donné.
+
+Des descripteurs sont ajoutés à l'enregistrement pour initialiser la classe en
+fonction du schéma :
+
+* on peut accéder aux attributs définis dans le schéma via les attributs de même
+ nom sur les instances (valeur typée)
+
+* on peut accéder aux relations définies dans le schéma via les attributs de même
+ nom sur les instances (liste d'instances d'entité)
+
+Les méthodes définies sur la classe `AnyEntity` ou `Entity` sont les suivantes :
+
+* `has_eid()`, retourne vrai si l'entité à un eid affecté (i.e. pas en cours de
+ création)
+
+* `check_perm(action)`, vérifie que l'utilisateur à le droit d'effectuer
+ l'action demandée sur l'entité
+
+:Formattage et génération de la sortie:
+
+ * `view(vid, **kwargs)`, applique la vue donnée à l'entité
+
+ * `absolute_url(**kwargs)`, retourne une URL absolue permettant d'accéder à la
+ vue primaire d'une entité
+
+ * `rest_path()`, renvoie une l'URL REST relative permettant d'obtenir l'entité
+
+ * `format(attr)`, retourne le format (type MIME) du champ passé en argument
+
+ * `printable_value(attr, value=_marker, attrtype=None, format='text/html')`,
+ retourne une chaine permettant l'affichage dans un format donné de la valeur
+ d'un attribut (la valeur est automatiquement récupérée au besoin)
+
+ * `display_name(form='')`, retourne une chaîne pour afficher le type de
+ l'entité, en spécifiant éventuellement la forme désirée ('plural' pour la
+ forme plurielle)
+
+:Gestion de données:
+
+ * `as_rset()`, transforme l'entité en un resultset équivalent simulant
+ le résultat de la requête `Any X WHERE X eid _eid_`
+
+ * `complete(skip_bytes=True)`, effectue une requête permettant de récupérer d'un
+ coup toutes les valeurs d'attributs manquant sur l'entité
+
+ * `get_value(name)`, récupere la valeur associée à l'attribut passé en argument
+
+ * `related(rtype, x='subject', limit=None, entities=False)`, retourne une liste
+ des entités liées à l'entité courant par la relation donnée en argument
+
+ * `unrelated(rtype, targettype, x='subject', limit=None)`, retourne un result set
+ des entités not liées à l'entité courante par la relation donnée en argument
+ et satisfaisants les contraintes de celle-ci
+
+ * `set_attributes(**kwargs)`, met à jour la liste des attributs avec
+ les valeurs correspondantes passées sous forme d'arguments nommés
+
+ * `copy_relations(ceid)`, copie les relations de l'entité ayant l'eid passé en
+ argument sur l'entité courante
+
+ * `last_modified(view)`, retourne la date à laquelle on doit considérer
+ l'objet comme modifié (utiliser par la gestion de cache HTTP)
+
+ * `delete()` permet de supprimer l'entité représentée
+
+:Meta-données standard (Dublin Core):
+
+ * `dc_title()`, retourne une chaine unicode correspondant à la méta-donnée
+ 'Title' (utilise par défaut le premier attribut non 'meta' du schéma de
+ l'entité)
+
+ * `dc_long_title()`, comme dc_title mais peut retourner un titre plus détaillé
+
+ * `dc_description(format='text/plain')`, retourne une chaine unicode
+ correspondant à la méta-donnée 'Description' (cherche un attribut
+ 'description' par défaut)
+
+ * `dc_authors()`, retourne une chaine unicode correspondant à la méta-donnée
+ 'Authors' (propriétaires par défaut)
+
+ * `dc_date(date_format=None)`, retourne une chaine unicode
+ correspondant à la méta-donnée 'Date' (date de modification par défaut)
+
+:Contrôle du vocabulaire pour les relations:
+
+ * `vocabulary(rtype, x='subject', limit=None)`, appelée notamment
+ par les vues d'édition d'erudi, elle renvoie une liste de couple
+ (label, eid) des entités qui pourraient être liées à l'entité
+ via la relation `rtype`
+ * `subject_relation_vocabulary(rtype, limit=None)`, appelée
+ en interne par `vocabulary` dans le cas d'une relation sujet
+ * `object_relation_vocabulary(rtype, limit=None)`, appelée
+ en interne par `vocabulary` dans le cas d'une relation objet
+ * `relation_vocabulary(rtype, targettype, x, limit=None)`, appelé
+ en interne par `subject_relation_vocabulary` et `object_relation_vocabulary`
+
+
+Les *rtags*
+-----------
+Les *rtags* permettent de spécifier certains comportements propres aux relations
+d'un type d'entité donné (voir plus loin). Ils sont définis sur la classe
+d'entité via l'attribut `rtags` qui est un dictionnaire dont les clés sont un
+triplet ::
+
+ <type de relation>, <type d'entité cible>, <position du contexte ("subject" ou "object"
+
+et les valeurs un `set` ou un tuple de marqueurs définissant des propriétés
+s'appliquant à cette relation.
+
+Il est possible de simplifier ce dictionnaire :
+
+* si l'on veut spécifier un seul marqueur, il n'est pas nécessaire d'utiliser
+ un tuple comme valeur, le marqueur seul (chaine de caractères) suffit
+* si l'on s'intéresse uniquement à un type de relation et non à la cible et à la
+ position du contexte (ou que celui-ci n'est pas ambigüe), on peut simplement
+ utiliser le nom du type de relation comme clé
+* si l'on veut qu'un marqueur s'applique quelque soit le type d'entité cible, il
+ faut utiliser la chaine `*` comme type d'entité cible
+
+A noter également que ce dictionnaire est *traité à la création de la classe*.
+Il est automatiquement fusionné avec celui de la ou des classe(s) parentes (pas
+besoin de copier celui de la classe parent pour le modifier). De même modifier
+celui-ci après création de la classe n'aura aucun effet...
+
+
+.. include:: 07-01-define-entities.fr.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/08-site-config.fr.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,94 @@
+.. -*- coding: utf-8 -*-
+
+Interface de configuration du site
+==================================
+
+.. image:: images/lax-book.03-site-config-panel.fr.png
+
+This panel allows you to configure the appearance of your application site.
+Six menus are available and we will go through each of them to explain how
+to use them.
+
+Navigation
+~~~~~~~~~~
+This menu provides you a way to adjust some navigation options depending on
+your needs, such as the number of entities to display by page of results.
+Follows the detailled list of available options :
+
+* navigation.combobox-limit : maximum number of entities to display in related
+ combo box (sample format: 23)
+* navigation.page-size : maximum number of objects displayed by page of results
+ (sample format: 23)
+* navigation.related-limit : maximum number of related entities to display in
+ the primary view (sample format: 23)
+* navigation.short-line-size : maximum number of characters in short description
+ (sample format: 23)
+
+UI
+~~
+This menu provides you a way to customize the user interface settings such as
+date format or encoding in the produced html.
+Follows the detailled list of available options :
+
+* ui.date-format : how to format date in the ui ("man strftime" for format description)
+* ui.datetime-format : how to format date and time in the ui ("man strftime" for format
+ description)
+* ui.default-text-format : default text format for rich text fields.
+* ui.encoding : user interface encoding
+* ui.fckeditor :should html fields being edited using fckeditor (a HTML WYSIWYG editor).
+ You should also select text/html as default text format to actually get fckeditor.
+* ui.float-format : how to format float numbers in the ui
+* ui.language : language of the user interface
+* ui.main-template : id of main template used to render pages
+* ui.site-title : site title, which is displayed right next to the logo in the header
+* ui.time-format : how to format time in the ui ("man strftime" for format description)
+
+
+Actions
+~~~~~~~
+This menu provides a way to configure the context in which you expect the actions
+to be displayed to the user and if you want the action to be visible or not.
+You must have notice that when you view a list of entities, an action box is
+available on the left column which display some actions as well as a drop-down
+menu for more actions.
+
+The context available are :
+
+* mainactions : actions listed in the left box
+* moreactions : actions listed in the `more` menu of the left box
+* addrelated : add actions listed in the left box
+* useractions : actions listed in the first section of drop-down menu
+ accessible from the right corner user login link
+* siteactions : actions listed in the second section of drop-down menu
+ accessible from the right corner user login link
+* hidden : select this to hide the specific action
+
+Boxes
+~~~~~
+The application has already a pre-defined set of boxes you can use right away.
+This configuration section allows you to place those boxes where you want in the
+application interface to customize it.
+
+The available boxes are :
+
+* actions box : box listing the applicable actions on the displayed data
+
+* boxes_blog_archives_box : box listing the blog archives
+
+* possible views box : box listing the possible views for the displayed data
+
+* rss box : RSS icon to get displayed data as a RSS thread
+
+* search box : search box
+
+* startup views box : box listing the configuration options available for
+ the application site, such as `Preferences` and `Site Configuration`
+
+Components
+~~~~~~~~~~
+[WRITE ME]
+
+Contextual components
+~~~~~~~~~~~~~~~~~~~~~
+[WRITE ME]
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/09-instance-config.fr.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,162 @@
+.. -*- coding: utf-8 -*-
+
+Configuration d'une instance
+============================
+
+À la création d'une instance, un fichier de configuration est généré dans ::
+
+ $(CW_REGISTRY)/<instance>/<nom configuration>.conf
+
+par exemple ::
+
+ /etc/cubicweb.d/jpl/all-in-one.conf
+
+C'est un simple fichier texte au format INI. Dans la description suivante,
+chaque nom d'option est préfixé de sa section et suivi de sa valeur par défaut
+le cas échéant, e.g. "`<section>.<option>` [valeur]".
+
+
+Configuration du serveur web
+----------------------------
+:`web.auth-mode` [cookie]:
+ mode d'authentification, cookie ou http
+:`web.realm`:
+ realm de l'application en mode d'authentification http
+:`web.http-session-time` [0]:
+ délai d'inactivité d'une session HTTP avant sa fermeture automatique. Durée
+ en secondes, 0 signifiant pas d'expiration (ou plus exactement lors de la
+ fermeture du navigateur du client)
+
+:`main.anonymous-user`, `main.anonymous-password`:
+ login et mot de passe à utiliser pour se connecter au serveur RQL lors des
+ connexions HTTP anonymes. Il faut que le compte EUser associé existe.
+
+:`main.base-url`:
+ url de base du site, à utiliser pour générer les urls des pages web
+
+Configuration https
+```````````````````
+Il est possible de rendre un site accessible en http pour les connections
+anonymes et en https pour les utilisateurs authentifié. Il faut pour cela
+utiliser apache (par ex.) pour la redirection et la variable `main.https-url` du
+fichier de configuration.
+
+:Exemple:
+
+ pour une redirection apache d'un site accessible via `http://localhost/demo`
+ et `https://localhost/demo` et qui tourne en réalité sur le port 8080, il
+ faut avoir pour la version http : ::
+
+ RewriteCond %{REQUEST_URI} ^/demo
+ RewriteRule ^/demo$ /demo/
+ RewriteRule ^/demo/(.*) http://127.0.0.1:8080/$1 [L,P]
+
+ et pour la version https : ::
+
+ RewriteCond %{REQUEST_URI} ^/demo
+ RewriteRule ^/demo$ /demo/
+ RewriteRule ^/demo/(.*) http://127.0.0.1:8080/https/$1 [L,P]
+
+
+ et on aura dans le fichier all-in-one.conf de l'instance : ::
+
+ base-url = http://localhost/demo
+ https-url = `https://localhost/demo`
+
+Configuration de l'interface web
+--------------------------------
+:`web.embed-allowed`:
+ expression régulière correspondant aux sites pouvant être "incorporé" dans
+ le site (controleur 'embed')
+:`web.submit-url`:
+ url à laquelle les bugs rencontrés dans l'application peuvent être posté
+
+
+Configuration du serveur RQL
+----------------------------
+:`main.host`:
+ nom de l'hôte s'il ne peut être détecter correctement
+:`main.pid-file`:
+ fichier où sera écrit le pid du serveur
+:`main.uid`:
+ compte utilisateur à utiliser pour le lancement du serveur quand il est
+ lancé en root par init
+:`main.session-time [30*60]`:
+ temps d'expiration d'une session RQL
+:`main.query-log-file`:
+ fichier dans lequel écrire toutes les requêtes RQL éxécutées par le serveur
+
+
+Configuration Pyro pour l'instance
+-----------------------------------
+Coté serveur web :
+
+:`pyro-client.pyro-application-id`:
+ identifiant pyro du serveur RQL (e.g. le nom de l'instance)
+
+Coté serveur RQL :
+
+:`pyro-server.pyro-port`:
+ numéro de port pyro. Si aucune valeur n'est spécifiée, un port est attribué
+ automatiquement.
+
+Coté serveur RQL et serveur web :
+
+:`pyro-name-server.pyro-ns-host`:
+ nom de l'hôte hébergeant le serveur de nom pyro. Si aucune valeur n'est
+ spécifié, il est localisé par une requête de broadcast
+:`pyro-name-server.pyro-ns-group` [cubicweb]:
+ groupe pyro sous lequel enregistrer l'application
+
+
+Configuration courriel
+----------------------
+Coté serveur RQL et serveur web :
+
+:`email.mangle-emails [no]`:
+ indique si les adresses email doivent être affichées telle quelle ou
+ transformée
+
+Coté serveur RQL :
+
+:`email.smtp-host [mail]`:
+ nom de l'hôte hébergeant le serveur SMTP à utiliser pour le courriel sortant
+:`email.smtp-port [25]`:
+ port du serveur SMTP à utiliser pour le courriel sortant
+:`email.sender-name`:
+ nom à utiliser pour les courriels sortant de l'application
+:`email.sender-addr`:
+ adresse à utiliser pour les courriels sortant de l'application
+:`email.default-dest-addrs`:
+ adresses de destination par défaut, si utilisé par la configuration de la
+ diffusion du modèle (séparées par des virgules)
+:`email.supervising-addrs`:
+ addresses de destination des courriels de supervision (séparées par des
+ virgules)
+
+
+Configuration journalisation
+----------------------------
+:`main.log-threshold`:
+ niveau de filtrage des messages (DEBUG, INFO, WARNING, ERROR)
+:`main.log-file`:
+ fichier dans lequel écrire les messages
+
+
+Configuration Eproperties
+-------------------------
+D'autres paramètres de configuration sont sous la forme d'entités `EProperty`
+dans la base de données. Il faut donc les éditer via l'interface web ou par des
+requêtes rql.
+
+:`ui.encoding`:
+ encodage de caractères à utiliser pour l'interface web
+:`navigation.short-line-size`: # XXX should be in ui
+ nombre de caractères maximum pour les affichages "courts"
+:`navigation.page-size`:
+ nombre d'entités maximum à afficher par page de résultat
+:`navigation.related-limit`:
+ nombre d'entités liées maximum à afficher sur la vue primaire d'une entité
+:`navigation.combobox-limit`:
+ nombre d'entités non liées maximum à afficher sur les listes déroulantes de
+ la vue d'édition d'une entité
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/10-form-management.fr.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,133 @@
+.. -*- coding: utf-8 -*-
+
+Gestion de formulaires
+======================
+
+Contrôle de la génération automatique de formulaire pour les entités manipulée
+------------------------------------------------------------------------------
+XXX FILLME
+
+* les formulaires 'edition' et 'creation'
+
+Le formulaire généré par défaut ne vous convient pas ? Vous êtes peut-être pas
+obligé de le refaire à la main ! :)
+
+* rtags primary, secondary, generated, generic,
+ `Entity.relation_category(rtype, x='subject')`
+* inline_view (now a rtag?)
+* spécification widget
+
+
+Fonctionnement du contrôleur d'édition par défaut (id: 'edit')
+--------------------------------------------------------------
+
+Contrôle de l'édition
+`````````````````````
+Prérequis: les paramètres liés aux entités à éditer sont spécifiés de la forme ::
+
+ <nom de champ>:<eid de l'entité>
+
+où l'eid de l'entité pourra être une lettre dans le cas d'une entité à créer. On
+dénommera ces paramètres comme *qualifié*.
+
+1. récupération des entités à éditer en cherchant les paramètres de formulaire
+ commençant par 'eid:' ayant également un paramètre '__type' associé
+ (également *qualifié* par l'eid évidemment)
+
+2. pour tous les attributs et relations de chaque entité à éditer
+
+ 1. recherche d'un paramètre 'edits-<nom relation>' ou 'edito-<nom relation>'
+ qualifié dans le cas d'une relation dont l'entité est objet
+ 2. si trouvé, la valeur récupérée est considérée comme la valeur originale
+ pour cette relation, et on cherche la (ou les) nouvelle(s) valeur(s) dans
+ le paramètre <nom relation> (qualifié)
+ 3. si la valeur est différente de l'originale, une requête de modification en
+ base est effectuée
+
+3. pour chaque entité à éditer
+
+ 1. si un paramètre `__linkto` qualifié est spécifié, sa valeur doit être une
+ chaine (ou une liste de chaine) de la forme : ::
+
+ <relation type>:<eids>:<target>
+
+ où <target> vaut 'subject' ou 'object' et chaque eid peut-être séparé d'un
+ autre par un '_'. Target spécifie *l'entité éditée* est sujet ou objet de la
+ relation et chaque relation ainsi spécifiée sera insérée.
+
+ 2. si un paramètre `__cloned_eid` qualifié est spécifié pour une entité, les
+ relations de l'entité spécifiée en valeur de cette argument sont copiées sur
+ l'entité éditée
+
+
+ 3. si un paramètre `__delete` qualifié est spécifié, sa valeur doit être une
+ chaine (ou une liste de chaine) de la forme : ::
+
+ <subject eids>:<relation type>:<object eids>
+
+ où chaque eid sujet ou objet peut-être séparé d'un autre par un '_'. Chaque
+ relation ainsi spécifiée sera supprimée.
+
+ 4. si un paramètre `__insert` qualifié est spécifié, sa valeur doit être de
+ même format que pour `__delete`, mais chaque relation ainsi spécifiée sera
+ insérée.
+
+4. si les paramètres `__insert` et/ou `__delete` sont trouvés non qualifiés,
+ ils sont interprétés comme décrit ci-dessus (quelque soit le nombre d'entité
+ édité)
+
+5. si aucune entité n'est éditée mais que le formulaire contient les paramètres
+ `__linkto` et `eid`, celui-ci est interprété en prenant la valeur spécifié
+ par le paramètre `eid` pour désigner l'entité sur laquelle ajouter les
+ relations
+
+
+A noter que :
+
+* si le paramètre `__action_delete` est trouvé, toutes les entités comme
+ spécifiées à éditer seront supprimées
+
+* si le paramètre `__action_cancel` est trouvé, aucune action n'est effectuée
+
+* si le paramètre `__action_apply` est trouvé, l'édition est effectuée
+ normalement mais la redirection sera effectuée sur le formulaire (cf `Contrôle
+ de la redirection`_)
+
+* le paramètre `__method` est également supporté comme sur le template principal
+ (XXX not very consistent, maybe __method should be dealed in the view controller)
+
+* si aucune entité à éditer n'est trouvée et qu'il n'y a pas de paramètre
+ `__action_delete`, `__action_cancel`, `__linkto`, `__delete` ou `__insert`,
+ une erreur est levée
+
+* placer dans le formulaire le paramètre `__message` permettra d'utiliser la
+ valeur de ce paramètre comme message d'information à l'utilisateur une fois
+ l'édition effectuée.
+
+
+Contrôle de la redirection
+``````````````````````````
+Une fois que l'édition s'est bien passé, reste un problème : c'est bien beau
+tout ça, mais où qu'on va maintenant ?? Si rien n'est spécifié, le controlleur
+se débrouille, mais comme il fait pas toujours ce qu'on voudrait, on peut
+controller ça en utilisant les paramètres suivant :
+
+* `__redirectpath`: chemin de l'url (relatif à la racine du site, sans paramètre
+ de formulaire
+
+* `__redirectparams`: paramètres de formulaires à ajouter au chemin
+
+* `__redirectrql`: requête RQL de redirection
+
+* `__redirectvid`: identifiant de vue de redirection
+
+* `__errorurl`: url du formulaire original, utilisé pour la redirection en cas
+ d'erreur de validation pendant l'édition. Si celui-ci n'est pas spécifié, une
+ page d'erreur sera présentée plutot qu'un retour sur le formulaire (qui est le
+ cas échéant responsable d'afficher les erreurs)
+
+* `__form_id`: identifiant de vue du formulaire original, utilisée si
+ `__action_apply` est trouvé
+
+En général on utilise soit `__redirectpath et `__redirectparams` soit
+`__redirectrql` et `__redirectvid`.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/11-ajax-json.fr.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,16 @@
+.. -*- coding: utf-8 -*-
+
+AJAX
+====
+JSON bla bla
+XXX FILLME
+
+
+Le contrôleur 'json'
+--------------------
+XXX FILLME
+
+
+API Javascript
+--------------
+XXX FILLME
--- a/doc/book/fr/11-faq.fr.txt Mon Nov 17 14:38:30 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-LAX Foire Aux Questions
-=======================
-
-[TRADUISEZ-MOI]
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/12-ui-components.fr.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,14 @@
+Autres composants de l'interface web
+====================================
+
+Actions
+-------
+XXXFILLME
+
+Component, VComponent
+---------------------
+XXXFILLME
+
+EProperty
+---------
+XXXFILLME
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/13-security.fr.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,45 @@
+.. -*- coding: utf-8 -*-
+
+Utilisateurs de l'application : Le contrôle d'accès
+===================================================
+
+
+Vocabulaire
+-----------
+* Personne, Societe définissent deux *types* d'entité
+* "Personne travaille_pour Societé" déclare qu'une relation
+ travaille_pour peut exister entre une entité de type Personne et une
+ entité de type Societe. L'ensemble des règles de ce type appliqué
+ à la relation "travaille_pour" définit le schéma de la relation
+ "travaille_pour"
+
+
+Description du modèle de sécurité
+---------------------------------
+
+Le modèle de sécurité de CubicWeb est un modèle fondé sur des `Access
+Control List`. Les notions sont les suivantes :
+
+* utilisateurs et groupes d'utilisateurs
+* un utilisateur appartient à au moins un groupe
+* droits (lire, modifier, créer, supprimer)
+* les droits sont attribués aux groupes (et non aux utilisateurs)
+
+Pour CubicWeb plus spécifiquement :
+
+* on associe les droits au niveau des schemas d'entites / relations
+* pour chaque type d'entité, on distingue les droits de lecture,
+ ajout, modification et suppression
+* pour chaque type de relation, on distingue les droits de lecture,
+ ajout et suppression (on ne peut pas modifer une relation)
+* les groupes de base sont : Administrateurs, Utilisateurs, Invités
+* les utilisateurs font par défaut parti du groupe Utilisateurs
+* on a un groupe virtuel "Utilisateurs Propriétaires", auquel on peut
+ associer uniquement les droits de suppression et de modification
+* on ne peut pas mettre d'utilisateurs dans ce groupe, ils y sont
+ ajoutés implicitement dans le contexte des objets dont ils sont
+ propriétaires
+* les droits de ce groupe ne sont vérifiés que sur
+ modification / suppression si tous les autres groupes auxquels
+ l'utilisateur appartient se sont vu interdir l'accès
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/14-hooks.fr.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,31 @@
+.. -*- coding: utf-8 -*-
+
+Les crochets (*hooks*)
+======================
+
+XXX FILLME
+
+Les crochets sont appelés avant ou après la mise à jour d'une entité ou d'une
+relations dans le dépot
+
+Leur prototypes sont les suivants
+
+
+ * after_add_entity (session, entity)
+ * after_update_entity (session, entity)
+ * after_delete_entity (session, eid)
+ * before_add_entity (session, entity)
+ * before_update_entity (session, entity)
+ * before_delete_entity (session, eid)
+
+ * after_add_relation (session, fromeid, rtype, toeid)
+ * after_delete_relation (session, fromeid, rtype, toeid)
+ * before_add_relation (session, fromeid, rtype, toeid)
+ * before_delete_relation (session, fromeid, rtype, toeid)
+
+ * server_startup
+ * server_shutdown
+
+ * session_open
+ * session_close
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/15-notifications.fr.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,6 @@
+.. -*- coding: utf-8 -*-
+
+Gestion de notifications
+========================
+
+XXX FILLME
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/16-rql.fr.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,11 @@
+.. -*- coding: utf-8 -*-
+
+Le langage RQL (Relation Query Language)
+========================================
+
+Voir la `documentation de RQL <file:///home/sandrine/src/fcubicweb/rql/doc/build/html/index.html>`_ .
+
+
+[TODO]
+Specific link to RQL complete documentation to remove duplicated content.
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/17-migration.fr.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,218 @@
+.. -*- coding: utf-8 -*-
+
+
+Migration
+=========
+
+Une des idées de base d'Erudi est la création incrémentale d'application, et
+pour cela de nombreuses actions sont fournies afin de facilement faire évoluer
+une application et tout particulièrement le modèle de données manipulé sans
+perdre les données des instances existantes.
+
+La version courante d'un modèle d'application est données dans le fichier
+`__pkginfo__.py` sous forme d'un tuple de 3 entiers.
+
+
+Gestion des scripts de migrations
+---------------------------------
+Les scripts des migrations doivent être placés dans le répertoire `migration` de
+l'application, et nommé de la manière suivante :
+
+::
+
+ <n° de version X.Y.Z>[_<description>]_<mode>.py
+
+dans lequel :
+
+* X.Y.Z correspond au n° de version du modèle vers lequel le script permet de
+ migrer,
+
+* le *mode* (entre le dernier "_" et l'extension ".py") indique à quelle partie
+ de l'application (serveur RQL, serveur web) le script s'applique en cas
+ d'installation distribuée. Il peut valoir :
+
+ * `common`, s'applique aussi bien sur le serveur RQL que sur le serveur web,
+ et met à jour des fichiers sur le disque (migration de fichier de
+ configuration par exemple).
+
+ * `web`, s'applique uniquement sur le serveur web, et met à jour des fichiers
+ sur le disque
+
+ * `repository`, s'applique uniquement sur le serveur RQL, et met à jour des
+ fichiers sur le disque
+
+ * `Any`, s'applique uniquement sur le serveur RQL, et met à jour des
+ données en base (migrations de schéma et de données par ex.)
+
+
+Toujours dans le répertoire `migration`, le fichier spécial `depends.map` permet
+d'indiquer que pour migrer vers une version spécifique du modèle, il faut tout
+d'abord avoir migrer vers une version données de erudi. Ce fichier peut contenir
+des commentaires (lignes commençant par un "#"), et une dépendance est notée sur
+une ligne de la manière suivante : ::
+
+ <n° de version du modèle X.Y.Z> : <n° de version erudi X.Y.Z>
+
+Par exemple ::
+
+ 0.12.0: 2.26.0
+ 0.13.0: 2.27.0
+ # 0.14 works with 2.27 <= erudi <= 2.28 at least
+ 0.15.0: 2.28.0
+
+
+Contexte de base
+----------------
+Les identifiants suivants sont préféfinis dans les scripts de migration :
+
+* `config`, configuration de l'instance
+
+* `interactive_mode`, booléen indiquant si le script est éxécuté en mode
+ interactif ou non
+
+* `appltemplversion`, version du modèle d'application de l'instance
+
+* `applerudiversion`, version erudi de l'instance
+
+* `templversion`, version du modéle d'application installée
+
+* `erudiversion`, version erudi installée
+
+* `confirm(question)`, fonction posant une question et retournant vrai si
+ l'utilisateur a répondu oui, faux sinon (retourne toujours vrai en mode non
+ interactif)
+
+* `_`, fonction équivalente à `unicode` permettant de marquer des chaines à
+ internationaliser dans les scripts de migration
+
+Dans les scripts "repository", les identifiants suivant sont également définis :
+
+* `checkpoint`, demande confirmant et effectue un "commit" au point d'appel
+
+* `repo_schema`, schéma persistent de l'instance (i.e. schéma de l'instance en
+ cours de migration)
+
+* `newschema`, schéma installé sur le système de fichier (i.e. schéma de la
+ version à jour du modèle et de erudi)
+
+* `sqlcursor`, un curseur SQL pour les très rares cas où il est réellement
+ nécessaire ou avantageux de passer par du sql
+
+* `repo`, l'objet repository
+
+
+Migration de schéma
+-------------------
+Les fonctions de migration de schéma suivantes sont disponibles dans les scripts
+"repository" :
+
+* `add_attribute(etype, attrname, attrtype=None, commit=True)`, ajoute un
+ nouvel attribut à un type d'entité existante. Si le type de celui-ci n'est pas
+ spécifié il est extrait du schéma à jour.
+
+* `drop_attribute(etype, attrname, commit=True)`, supprime un
+ attribut à un type d'entité existante.
+
+* `rename_attribute(etype, oldname, newname, commit=True)`, renomme un attribut
+
+* `add_entity_type(etype, auto=True, commit=True)`, ajoute un nouveau type
+ d'entité. Si `auto` est vrai, toutes les relations utilisant ce type d'entité
+ et ayant un type d'entité connu à l'autre extrémité vont également être
+ ajoutées.
+
+* `drop_entity_type(etype, commit=True)`, supprime un type d'entité et toutes
+ les relations l'utilisant.
+
+* `rename_entity_type(oldname, newname, commit=True)`, renomme un type d'entité
+
+* `add_relation_type(rtype, addrdef=True, commit=True)`, ajoute un nouveau type
+ de relation. Si `addrdef` est vrai, toutes les définitions de relation de ce
+ type seront également ajoutées.
+
+* `drop_relation_type(rtype, commit=True)`, supprime un type de relation et
+ toutes les définitions de ce type.
+
+* `rename_relation(oldname, newname, commit=True)`, renomme une relation.
+
+* `add_relation_definition(subjtype, rtype, objtype, commit=True)`, ajoute une
+ définition de relation.
+
+* `drop_relation_definition(subjtype, rtype, objtype, commit=True)`, supprime
+ une définition de relation.
+
+* `synchronize_permissions(ertype, commit=True)`, synchronise les permissions
+ d'un type d'entité ou de relation
+
+* `synchronize_rschema(rtype, commit=True)`, synchronise les propriétés et
+ permissions d'un type de relation.
+
+* `synchronize_eschema(etype, commit=True)`, synchronise les propriétés et
+ permissions d'un type d'entité.
+
+* `synchronize_schema(commit=True)`, synchronise le schéma persistent avec le
+ schéma à jour (mais sans ajouter ni supprimer de nouveaux types d'entités ou
+ de relations ni de définitions de relation).
+
+* `change_relation_props(subjtype, rtype, objtype, commit=True, **kwargs)`, change
+ les propriétés d'une definition de relation en utilisant les arguments nommés
+ pour les propriétés à changer.
+
+* `set_widget(etype, rtype, widget, commit=True)`, change le widget à utiliser
+ pour la relation <rtype> du type d'entité <etype>
+
+* `set_size_constraint(etype, rtype, size, commit=True)`, change la contrainte
+ de taille pour la relation <rtype> du type d'entité <etype>
+
+
+Migration de données
+--------------------
+Les fonctions de migration de données suivantes sont disponibles dans les scripts
+"repository" :
+
+* `rql(rql, kwargs=None, cachekey=None, ask_confirm=True)`, éxécute une
+ requête rql arbitraire, d'interrogation ou de modification. Un objet result
+ set est retourné.
+
+* `add_entity(etype, *args, **kwargs)`, ajoute une nouvelle entité du type
+ données. La valeur des attributs et relations est spécifiée en utilisant les
+ arguments nommés et positionnels.
+
+
+Création de workflow
+--------------------
+Les fonctions de création de workflow suivantes sont disponibles dans les scripts
+"repository" :
+
+* `add_state(name, stateof, initial=False, commit=False, **kwargs)`, ajoute un
+ nouvel état de workflow
+
+* `add_transition(name, transitionof, fromstates, tostate, requiredgroups=(), commit=False, **kwargs)`,
+ ajoute une nouvelle transtion de workflow
+
+Migration de configuration
+--------------------------
+Les fonctions de migration de configuration suivantes sont disponibles dans tout
+les scripts :
+
+* `option_renamed(oldname, newname)`, indique qu'une option a été renommée
+
+* `option_group_change(option, oldgroup, newgroup)`, indique qu'une option a
+ changé de groupe
+
+* `option_added(oldname, newname)`, indique qu'une option a été ajoutée
+
+* `option_removed(oldname, newname)`, indique qu'une option a été supprimée
+
+
+Autres fonctions de migration
+-----------------------------
+Ces fonctions ne sont utilisés que pour des opérations de bas niveau
+irréalisables autrement ou pour réparer des bases cassées lors de session
+interactive. Elles sont disponibles dans les scripts "repository".
+
+* `sqlexec(sql, args=None, ask_confirm=True)`, éxécute une requête sql
+ arbitraire, à n'utiliser
+
+* `add_entity_type_table(etype, commit=True)`
+* `add_relation_type_table(rtype, commit=True)`
+* `uninline_relation(rtype, commit=True)`
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/18-tests.fr.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,38 @@
+.. -*- coding: utf-8 -*-
+
+Tests
+=====
+
+Écriture de tests unitaires
+---------------------------
+Le framework de test fournit principalement deux classes de tests dans le module
+`ginco.devtools.apptest`:
+
+* `EnvBasedTC`, pour simuler un environnement complet (web + repository)
+* `RepositoryBasedTC`, pour simuler un environnement de repository uniquement
+
+Ces deux classes ont quasiment la même interface et proposent un certain nombre de méthodes
+rendant l'écriture de test puissante et rapide.
+
+XXXFILLME describe API
+
+Dans la plupart des cas, vous allez vouloir hériter de `EnvBasedTC` pour écrire des tests
+unitaires ou fonctionnels pour vos entités, vues, crochets...
+
+
+Test des courriels de notifications
+```````````````````````````````````
+Lors de l'éxécution de tests les courriels potentiellement générés ne sont pas réellement
+envoyé mais se retrouve dans la liste `MAILBOX` du module `ginco.devtools.apptest`. Cette
+liste est remise à zéro au *setUp* de chaque test (par le setUp des classes `EnvBasedTC`
+et `RepositoryBasedTC`).
+
+Vous pouvez donc tester vos notifications en analysant le contenu de cette liste, qui
+contient des objets ayant deux attributs :
+* `recipients`, la liste des destinataires
+* `msg`, l'objet email.Message
+
+
+Tests automatiques
+------------------
+XXXFILLME
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/19-i18n.fr.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,71 @@
+.. -*- coding: utf-8 -*-
+
+.. _Internationalisation:
+
+
+Internationalisation
+====================
+
+Le système d'internationalisation de l'interface web de CubicWeb est basé sur le
+système `GNU gettext`_.
+
+.. _`GNU gettext`: http://www.gnu.org/software/gettext/
+
+Messages à internationaliser
+----------------------------
+
+Marquage des messages à internaliser
+````````````````````````````````````
+Les chaines de caractères à internationaliser sont marqués par l'appel à la
+fonction `_` *OU* par la méthode équivalent de la requête dans le code python ou
+dans les expressions python de template TAL.
+
+Dans les templates cubicweb-tal, il est également possible d'insérer une chaine à
+traduire via les balises `i18n:content` et `i18n:replace`.
+
+De plus des messages correspondant aux entités/relations utilisés par le schéma
+de l'application seront automatiquement ajoutés.
+
+Renvoi d'un message internationalisé lors de la construction d'une page
+```````````````````````````````````````````````````````````````````````
+La fonction *built-in* `_` ne doit servir qu'**à marquer les messages à
+traduire**, non pas à récupérer une traduction. Il faut pour cela utiliser la
+méthode `_` de l'objet requête, sans quoi vous récupérerez l'identifiant de
+message au lieu de sa traduction dans la langue propre à la requête.1
+
+
+Gestion des catalogues de traduction
+------------------------------------
+Une fois l'application rendu internationalisable coté code, reste à gérer les
+catalogues de traductions. cubicweb-ctl intègre pour cela les commandes suivantes :
+
+* `i18nlibupdate`, met à jour les catalogues de messages *de la librairie
+ cubicweb*. Sauf si vous développez sur le framework (et non votre propre
+ application), vous ne devriez pas avoir à utiliser cette commande
+
+* `i18nupdate`, met à jour les catalogues de messages *du composant* (ou de tous
+ les composants). A la suite de cette commande, vous devez mettre à jour les
+ fichiers de traduction *.po* dans le sous-répertoire "i18n" de votre
+ template. Évidemment les traductions précédentes toujours utilisées ont été
+ conservées.
+
+* `i18ncompile`, recompile les catalogues de messages *d'une instance* (ou de
+ toutes les instances) après mise à jour des catalogues de son composant. Cela
+ est effectué automatiquement lors d'une création ou d'une mise à jour. Les
+ catalogues de messages compilés se trouvent dans le répertoire
+ "i18n/<lang>/LC_MESSAGES/cubicweb.mo" de l'application où `lang` est
+ l'identifiant de la langue sur 2 lettres ('en' ou 'fr' par exemple)
+
+
+Le cas classique
+````````````````
+Vous avez ajouté et/ou modifié des messages d'un composant utilisé par votre
+application (en ajoutant une nouvelle vue ou en ayant modifié le schéma par
+exemple) :
+
+1. `cubicweb-ctl i18nupdate <composant>`
+2. éditer les fichiers <composant>/xxx.po dans pour y rajouter les traductions
+ manquantes (`msgstr` vide)
+3. `hg ci -m "updated i18n catalogs"`
+4. `cubicweb-ctl i18n compile <monapplication>`
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/20-gae.fr.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,19 @@
+.. -*- coding: utf-8 -*-
+
+.. _contents:
+
+==========================
+Google AppEngine Datastore
+==========================
+
+
+.. include:: 01-intro.fr.txt
+.. include:: 02-install.fr.txt
+.. include:: 03-create-app.fr.txt
+.. include:: 04-develop-views.fr.txt
+.. include:: 05-components.fr.txt
+.. include:: 06-maintemplate.fr.txt
+.. include:: 07-rss-xml.fr.txt
+.. include:: 08-rql.fr.txt
+.. include:: 09-urlrewrite.fr.txt
+.. include:: 10-security.fr.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/21-01-architecture.fr.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,14 @@
+.. -*- coding: utf-8 -*-
+
+
+Architecture du serveur
+-----------------------
+
+.. image:: images/server-class-diagram.png
+
+`Diagramme ArgoUML`_
+
+[FIXME]
+Make a downloadable source of zargo file.
+
+.. _`Diagramme ArgoUML`: cubicweb.zargo
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/21-02-querier.fr.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,62 @@
+.. -*- coding: utf-8 -*-
+
+Déroulement de l'éxecution d'une requête en multi-source avec insertion de sécurité
+```````````````````````````````````````````````````````````````````````````````````
+
+* 3 sources (system, ldap (Euser) et rql (Card)
+* permission en lecture Card is elle appartient à l'utilisateur
+
+Soit la requête de départ: ::
+
+ Any X,T WHERE X owned_by U, U login "syt", X title T
+
+1. récupération arbre de syntaxe et solution (+cache) ::
+
+ -> {X: Card, U: Euser}, {X: Blog, U: Euser}, {X: Bookmark, U: Euser}
+
+2. insertion sécurité ::
+
+ -> Any X,T WHERE X owned_by U, U login "syt", X title T, EXISTS(X owned_by UEID) / {X: Card, U: Euser}
+ Any X,T WHERE X owned_by U, U login "syt", X title T / {X: Blog, U: Euser}, {X: Bookmark, U: Euser}
+
+3. construction plan
+ 0. preprocessing (annotation des arbres de syntaxe)
+
+ 1. Any U WHERE U login "syt" / {U: Euser}
+ [system+ldap] => table1/varmap1{U:U2}
+
+ 2. Any X,T WHERE X owned_by U2, X title T / {X: Blog, U: Euser}, {X: Bookmark, U: Euser}
+ [varmap1|system] => TABLE2
+
+ 3 Deux alernatives:
+
+ 1. Any X,T WHERE X is Card, X title T {X: Card} ::
+
+ [system+rql] => table3/varmap3{X:X3, T:T3}
+
+ Any X3,T3 WHERE X3 owned_by U2, X3 title T3, EXISTS(X owned_by UEID) / {X3: Card, U2: Euser} ::
+
+ [(varmap1, varmap3)|system] => TABLE2
+
+ 2 Any X WHERE X is Card X owned_by U2, EXISTS(X owned_by UEID) / {X: Card, U2: Euser} ::
+
+ [varmap1|system] => EIDS
+
+ Any X,T WHERE X title T, X eid IN(EIDS) {X: Card} ::
+
+ [system+rql] => TABLE2
+
+ 4. renvoie contenu TABLE2.
+ Note : si aggrégat / tri / distinct TABLE2 est nécessairement une table temporaire et besoin d'une
+ étape AggrStep supplémentaire
+
+4. éxécution du plan
+
+5. [construction description]
+
+6. renvoie ResultSet
+
+Notes sur UNION
+```````````````
+
+* en multi-sources, les résultats des unions peuvent être mélangés
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/21-03-modules.fr.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,253 @@
+.. -*- coding: utf-8 -*-
+
+
+:mod:`cubes.addressbook`
+========================
+
+.. automodule:: cubes.addressbook
+ :members:
+
+:mod:`cubes.basket`
+========================
+
+.. automodule:: cubes.basket
+ :members:
+
+:mod:`cubes.blog`
+========================
+
+.. automodule:: cubes.blog
+ :members:
+
+:mod:`cubes.book`
+========================
+
+.. automodule:: cubes.book
+ :members:
+
+:mod:`cubes.comment`
+========================
+
+.. automodule:: cubes.comment
+ :members:
+
+:mod:`cubes.company`
+========================
+
+.. automodule:: cubes.company
+ :members:
+
+
+:mod:`cubes.conference`
+========================
+
+.. automodule:: cubes.conference
+ :members:
+
+:mod:`cubes.email`
+========================
+
+.. automodule:: cubes.email
+ :members:
+
+:mod:`cubes.event`
+========================
+
+.. automodule:: cubes.event
+ :members:
+
+:mod:`cubes.expense`
+========================
+
+.. automodule:: cubes.expense
+ :members:
+
+
+:mod:`cubes.file`
+========================
+
+.. automodule:: cubes.file
+ :members:
+
+:mod:`cubes.folder`
+========================
+
+.. automodule:: cubes.folder
+ :members:
+
+:mod:`cubes.i18ncontent`
+========================
+
+.. automodule:: cubes.i18ncontent
+ :members:
+
+:mod:`cubes.invoice`
+========================
+
+.. automodule:: cubes.invoice
+ :members:
+
+:mod:`cubes.keyword`
+========================
+
+.. automodule:: cubes.keyword
+ :members:
+
+:mod:`cubes.link`
+========================
+
+.. automodule:: cubes.link
+ :members:
+
+:mod:`cubes.mailinglist`
+========================
+
+.. automodule:: cubes.mailinglist
+ :members:
+
+:mod:`cubes.person`
+========================
+
+.. automodule:: cubes.person
+ :members:
+
+:mod:`cubes.shopcart`
+========================
+
+.. automodule:: cubes.shopcart
+ :members:
+
+:mod:`cubes.skillmat`
+========================
+
+.. automodule:: cubes.skillmat
+ :members:
+
+:mod:`cubes.tag`
+========================
+
+.. automodule:: cubes.tag
+ :members:
+
+:mod:`cubes.task`
+========================
+
+.. automodule:: cubes.task
+ :members:
+
+:mod:`cubes.workcase`
+========================
+
+.. automodule:: cubes.workcase
+ :members:
+
+:mod:`cubes.workorder`
+========================
+
+.. automodule:: cubes.workorder
+ :members:
+
+:mod:`cubes.zone`
+========================
+
+.. automodule:: cubes.zone
+ :members:
+
+:mod:`cubicweb`
+===============
+
+.. automodule:: cubicweb
+ :members:
+
+:mod:`cubicweb.common`
+======================
+
+.. automodule:: cubicweb.common
+ :members:
+
+:mod:`cubicweb.devtools`
+========================
+
+.. automodule:: cubicweb.devtools
+ :members:
+
+:mod:`cubicweb.entities`
+========================
+
+.. automodule:: cubicweb.entities
+ :members:
+
+:mod:`cubicweb.etwist`
+======================
+
+.. automodule:: cubicweb.etwist
+ :members:
+
+:mod:`cubicweb.goa`
+===================
+
+.. automodule:: cubicweb.goa
+ :members:
+
+:mod:`cubicweb.schemas`
+=======================
+
+.. automodule:: cubicweb.schemas
+ :members:
+
+:mod:`cubicweb.server`
+======================
+
+.. automodule:: cubicweb.server
+ :members:
+
+:mod:`cubicweb.sobjects`
+========================
+
+.. automodule:: cubicweb.sobjects
+ :members:
+
+:mod:`cubicweb.web`
+===================
+
+.. automodule:: cubicweb.web
+ :members:
+
+:mod:`cubicweb.web.views`
+=========================
+
+.. automodule:: cubicweb.web.views
+ :members:
+
+
+:mod:`cubicweb.wsgi`
+====================
+
+.. automodule:: cubicweb.wsgi
+ :members:
+
+:mod:`indexer`
+==============
+
+.. automodule:: indexer
+ :members:
+
+:mod:`logilab`
+==============
+
+.. automodule:: logilab
+ :members:
+
+
+
+:mod:`rql`
+==========
+
+.. automodule:: rql
+ :members:
+
+:mod:`yams`
+===========
+
+.. automodule:: yams
+ :members:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/21-references.fr.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,13 @@
+.. -*- coding: utf-8 -*-
+
+.. _contents:
+
+Références
+==========
+
+.. toctree::
+ :maxdepth: 1
+
+ 21-01-architecture.fr.txt
+ 21-02-querier.fr.txt
+ 21-03-modules.fr.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/22-faq.fr.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,55 @@
+.. -*- coding: utf-8 -*-
+
+Foire Aux Questions
+===================
+
+[FILL ME]
+
+* A quoi servent les crochets?
+
+ Les crochets sont appeles lorsqu'une requete RQL est executee. Cela
+ permet d'executer des actions specifiques lors d'un acces a la base
+ de donnees, ce qui donne un controle de la base de donnees afin de
+ prevenir l'insertion de `mauvaises` entites dans la base.
+
+* Quand utiliser un template HTML plutot qu'un composant graphique?
+
+ Un template HTML ne peut contenir de logique, il ne permettra donc
+ que de definir une vue statique. Un composant permet lui de gerer
+ plus de logique et d'operations sur le contexte dans lequel il
+ s'applique. Il faut donc bien reflechir avant de decider de l'un ou
+ de l'autre, mais vous avez la possibilite de choisir.
+
+* Comment mettre à jour une base de données après avoir modifié le schéma?
+
+ Cela dépend de ce qui a été modifié dans le schéma.
+
+ * Modification d'une relation non finale
+
+ * Modification d'une relation finale
+
+[TO COMPLETE]
+
+* Comment créer un utilisateur anonyme?
+
+ Cela vous permet d'acceder a votre site sans avoir besoin de vous authentifier.
+ Dans le fichier ``all-in-one.conf`` de votre instance, définir l'utilisateur
+ anonyme en initilisant les valeurs des variables suivantes ::
+
+ # login of the Erudi user account to use for anonymous user (if you want to
+ # allow anonymous)
+ anonymous-user=anon
+
+ # password of the Erudi user account matching login
+ anonymous-password=anon
+
+ Vous devez aussi vous assurer que cet utilisateur `anon` existe dans la base
+ de données, le plus simple étant de s'identifier sur votre application en
+ administrateur et de rajouter l'utilisateur `anon` via l'interface d'administration.
+
+* Quelle est la différence entre `AppRsetObject` et `AppObject` ?
+
+ La différence entre la classe `AppRsetObject` et la classe `AppObject` est que
+ les instances de la premières sont séléctionnées pour une requête et un "result
+ set" et alors que les secondes ne sont séléctionnées qu'en fonction de leur
+ identifiant.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/MERGE_ME-tut-create-app.fr.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,394 @@
+.. -*- coding: utf-8 -*-
+
+
+Tutoriel : créer votre première application web pour Postgres
+=============================================================
+
+
+[TRANSLATE ME TO FRENCH]
+
+Ce tutoriel va vous guider pas à pas a construire une apllication web
+de gestion de Blog afin de vous faire découvrir les fonctionnalités de
+`CubicWeb`.
+
+Nous supposons que vous avec déjà suivi le guide :ref:`MiseEnPlaceEnv`
+
+
+This tutorial will guide you step by step to build a blog application
+and discover the unique features of `LAX`. It assumes that you followed
+the :ref:`installation` guidelines and that both the `AppEngine SDK` and the
+`LAX` framework are setup on your computer.
+
+Creating a new application
+--------------------------
+
+We choosed in this tutorial to develop a blog as an example of web application
+and will go through each required steps/actions to have it running with `LAX`.
+When you installed `LAX`, you saw a directory named ``skel``. Make a copy of
+this directory and call it ``BlogDemo``.
+
+The location of this directory does not matter. But once decided, make sure your ``PYTHONPATH`` is properly set (:ref:`installation`).
+
+
+Defining a schema
+-----------------
+
+With `LAX`, the schema/datamodel is the core of the application. This is where
+you will define the type of content you have to hanlde in your application.
+
+Let us start with something simple and improve on it iteratively.
+
+In schema.py, we define two entities : ``Blog`` and ``BlogEntry``.
+
+::
+
+ class Blog(EntityType):
+ title = String(maxsize=50, required=True)
+ description = String()
+
+ class BlogEntry(EntityType):
+ title = String(maxsize=100, required=True)
+ publish_date = Date(default='TODAY')
+ text = String(fulltextindexed=True)
+ category = String(vocabulary=('important','business'))
+ entry_of = SubjectRelation('Blog', cardinality='?*')
+
+A Blog has a title and a description. The title is a string that is
+required by the class EntityType and must be less than 50 characters.
+The description is a string that is not constrained.
+
+A BlogEntry has a title, a publish_date and a text. The title is a
+string that is required and must be less than 100 characters. The
+publish_date is a Date with a default value of TODAY, meaning that
+when a BlogEntry is created, its publish_date will be the current day
+unless it is modified. The text is a string that will be indexed in
+the full-text index and has no constraint.
+
+A BlogEntry also has a relationship ``entry_of`` that link it to a
+Blog. The cardinality ``?*`` means that a BlogEntry can be part of
+zero or one Blog (``?`` means `zero or one`) and that a Blog can
+have any number of BlogEntry (``*`` means `any number including
+zero`). For completeness, remember that ``+`` means `one or more`.
+
+Running the application
+-----------------------
+
+Defining this simple schema is enough to get us started. Make sure you
+followed the setup steps described in detail in the installation
+chapter (especially visiting http://localhost:8080/_load as an
+administrator), then launch the application with the command::
+
+ python dev_appserver.py BlogDemo
+
+and point your browser at http://localhost:8080/ (if it is easier for
+you, use the on-line demo at http://lax.appspot.com/).
+
+.. image:: images/lax-book.00-login.fr.png
+ :alt: login screen
+
+After you log in, you will see the home page of your application. It
+lists the entity types: Blog and BlogEntry. If these links read
+``blog_plural`` and ``blogentry_plural`` it is because
+internationalization (i18n) is not working for you yet. Please ignore
+this for now.
+
+.. image:: images/lax-book.01-start.fr.png
+ :alt: home page
+
+Creating system entities
+------------------------
+You can only create new users if you decided not to use google authentication.
+
+
+[WRITE ME : create users manages permissions etc]
+
+
+
+Creating application entites
+----------------------------
+
+Create a Blog
+~~~~~~~~~~~~~
+
+Let us create a few of these entities. Click on the [+] at the right
+of the link Blog. Call this new Blog ``Tech-blog`` and type in
+``everything about technology`` as the description, then validate the
+form by clicking on ``Validate``.
+
+.. image:: images/lax-book.02-create-blog.fr.png
+ :alt: from to create blog
+
+Click on the logo at top left to get back to the home page, then
+follow the Blog link that will list for you all the existing Blog.
+You should be seeing a list with a single item ``Tech-blog`` you
+just created.
+
+.. image:: images/lax-book.03-list-one-blog.fr.png
+ :alt: displaying a list of a single blog
+
+Clicking on this item will get you to its detailed description except
+that in this case, there is not much to display besides the name and
+the phrase ``everything about technology``.
+
+.. image:: images/lax-book.04-detail-one-blog.fr.png
+ :alt: displaying the detailed view of a blog
+
+Now get back to the home page by clicking on the top-left logo, then
+create a new Blog called ``MyLife`` and get back to the home page
+again to follow the Blog link for the second time. The list now
+has two items.
+
+.. image:: images/lax-book.05-list-two-blog.fr.png
+ :alt: displaying a list of two blogs
+
+
+Create a BlogEntry
+~~~~~~~~~~~~~~~~~~
+
+Get back to the home page and click on [+] at the right of the link
+BlogEntry. Call this new entry ``Hello World`` and type in some text
+before clicking on ``Validate``. You added a new blog entry without
+saying to what blog it belongs. There is a box on the left entitled
+``actions``, click on the menu item ``modify``. You are back to the form
+to edit the blog entry you just created, except that the form now has
+another section with a combobox titled ``add relation``. Chose
+``entry_of`` in this menu and a second combobox appears where you pick
+``MyLife``.
+
+You could also have, at the time you started to fill the form for a
+new entity BlogEntry, hit ``Apply`` instead of ``Validate`` and the
+combobox titled ``add relation`` would have showed up.
+
+.. image:: images/lax-book.06-add-relation-entryof.fr.png
+ :alt: editing a blog entry to add a relation to a blog
+
+Validate the changes by clicking ``Validate``. The entity BlogEntry
+that is displayed now includes a link to the entity Blog named
+``MyLife``.
+
+.. image:: images/lax-book.07-detail-one-blogentry.fr.png
+ :alt: displaying the detailed view of a blogentry
+
+Remember that all of this was handled by the framework and that the
+only input that was provided so far is the schema. To get a graphical
+view of the schema, run the ``laxctl genschema BlogDemo`` command as
+explained in the installation section and point your browser to the
+URL http://localhost:8080/schema
+
+.. image:: images/lax-book.08-schema.fr.png
+ :alt: graphical view of the schema (aka data-model)
+
+Site configuration
+------------------
+
+.. image:: images/lax-book.03-site-config-panel.fr.png
+
+This panel allows you to configure the appearance of your application site.
+Six menus are available and we will go through each of them to explain how
+to use them.
+
+Navigation
+~~~~~~~~~~
+This menu provides you a way to adjust some navigation options depending on
+your needs, such as the number of entities to display by page of results.
+Follows the detailled list of available options :
+
+* navigation.combobox-limit : maximum number of entities to display in related
+ combo box (sample format: 23)
+* navigation.page-size : maximum number of objects displayed by page of results
+ (sample format: 23)
+* navigation.related-limit : maximum number of related entities to display in
+ the primary view (sample format: 23)
+* navigation.short-line-size : maximum number of characters in short description
+ (sample format: 23)
+
+UI
+~~
+This menu provides you a way to customize the user interface settings such as
+date format or encoding in the produced html.
+Follows the detailled list of available options :
+
+* ui.date-format : how to format date in the ui ("man strftime" for format description)
+* ui.datetime-format : how to format date and time in the ui ("man strftime" for format
+ description)
+* ui.default-text-format : default text format for rich text fields.
+* ui.encoding : user interface encoding
+* ui.fckeditor :should html fields being edited using fckeditor (a HTML WYSIWYG editor).
+ You should also select text/html as default text format to actually get fckeditor.
+* ui.float-format : how to format float numbers in the ui
+* ui.language : language of the user interface
+* ui.main-template : id of main template used to render pages
+* ui.site-title : site title, which is displayed right next to the logo in the header
+* ui.time-format : how to format time in the ui ("man strftime" for format description)
+
+
+Actions
+~~~~~~~
+This menu provides a way to configure the context in which you expect the actions
+to be displayed to the user and if you want the action to be visible or not.
+You must have notice that when you view a list of entities, an action box is
+available on the left column which display some actions as well as a drop-down
+menu for more actions.
+
+The context available are :
+
+* mainactions : actions listed in the left box
+* moreactions : actions listed in the `more` menu of the left box
+* addrelated : add actions listed in the left box
+* useractions : actions listed in the first section of drop-down menu
+ accessible from the right corner user login link
+* siteactions : actions listed in the second section of drop-down menu
+ accessible from the right corner user login link
+* hidden : select this to hide the specific action
+
+Boxes
+~~~~~
+The application has already a pre-defined set of boxes you can use right away.
+This configuration section allows you to place those boxes where you want in the
+application interface to customize it.
+
+The available boxes are :
+
+* actions box : box listing the applicable actions on the displayed data
+
+* boxes_blog_archives_box : box listing the blog archives
+
+* possible views box : box listing the possible views for the displayed data
+
+* rss box : RSS icon to get displayed data as a RSS thread
+
+* search box : search box
+
+* startup views box : box listing the configuration options available for
+ the application site, such as `Preferences` and `Site Configuration`
+
+Components
+~~~~~~~~~~
+[WRITE ME]
+
+Contextual components
+~~~~~~~~~~~~~~~~~~~~~
+[WRITE ME]
+
+Set-up a workflow
+-----------------
+
+Before starting, make sure you refresh your mind by reading [link to
+definition_workflow chapter].
+
+We want to create a workflow to control the quality of the BlogEntry
+submitted on your application. When a BlogEntry is created by a user
+its state should be `submitted`. To be visible to all, it needs to
+be in the state `published`. To move from `submitted` to `published`
+we need a transition that we can name `approve_blogentry`.
+
+We do not want every user to be allowed to change the state of a
+BlogEntry. We need to define a group of user, `moderators`, and
+this group will have appropriate permissions to approve BlogEntry
+to be published and visible to all.
+
+There are two ways to create a workflow, form the user interface,
+and also by defining it in ``migration/postcreate.py``. This script
+is executed each time a new ``./bin/laxctl db-init`` is done.
+If you create the states and transitions through the user interface
+this means that next time you will need to initialize the database
+you will have to re-create all the entities.
+We strongly recommand you create the workflow in ``migration\postcreate.py``
+and we will now show you how.
+The user interface would only be a reference for you to view the states
+and transitions but is not the appropriate interface to define your
+application workflow.
+
+Update the schema
+~~~~~~~~~~~~~~~~~
+To enable a BlogEntry to have a State, we have to define a relation
+``in_state`` in the schema of BlogEntry. Please do as follows, add
+the line ``in_state (...)``::
+
+ class BlogEntry(EntityType):
+ title = String(maxsize=100, required=True)
+ publish_date = Date(default='TODAY')
+ text_format = String(meta=True, internationalizable=True, maxsize=50,
+ default='text/rest', constraints=[format_constraint])
+ text = String(fulltextindexed=True)
+ category = String(vocabulary=('important','business'))
+ entry_of = SubjectRelation('Blog', cardinality='?*')
+ in_state = SubjectRelation('State', cardinality='1*')
+
+As you updated the schema, you will have re-execute ``./bin/laxctl db-init``
+to initialize the database and migrate your existing entities.
+[WRITE ABOUT MIGRATION]
+
+Create states, transitions and group permissions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+At the time the ``postcreate.py`` script is executed, several methods
+can be used. They are all defined in the ``class ServerMigrationHelper``.
+We will only discuss the method we use to create a wrokflow here.
+
+To define our workflow for BlogDemo, please add the following lines
+to ``migration/postcreate.py``::
+
+ _ = unicode
+
+ moderators = add_entity('EGroup', name=u"moderators")
+
+ submitted = add_state(_('submitted'), 'BlogEntry', initial=True)
+ published = add_state(_('published'), 'BlogEntry')
+
+ add_transition(_('approve_blogentry'), 'BlogEntry', (submitted,), published, ('moderators', 'managers'),)
+
+ checkpoint()
+
+``add_entity`` is used here to define the new group of users that we
+need to define the transitions, `moderators`.
+If this group required by the transition is not defined before the
+transition is created, it will not create the relation `transition
+require the group moderator`.
+
+``add_state`` expects as the first argument the name of the state you are
+willing to create, then the entity type on which the state can be applied,
+and an optionnal argument to set if the state is the initial state
+of the entity type or not.
+
+``add_transition`` expects as the first argument the name of the
+transition, then the entity type on which we can apply the transition,
+then the list of possible initial states from which the transition
+can be applied, the target state of the transition, and the permissions
+(e.g. list of the groups of users who can apply the transition).
+
+.. image:: images/lax-book.03-transitions-view.fr.png
+
+You can now notice that in the actions box of a BlogEntry, the state
+is now listed as well as the possible transitions from this state
+defined by the workflow. This transition, as defined in the workflow,
+will only being displayed for the users belonging to the group
+moderators of managers.
+
+Change view permission
+~~~~~~~~~~~~~~~~~~~~~~
+
+
+
+Conclusion
+----------
+
+Exercise
+~~~~~~~~
+
+Create new blog entries in ``Tech-blog``.
+
+What we learned
+~~~~~~~~~~~~~~~
+
+Creating a simple schema was enough to set up a new application that
+can store blogs and blog entries.
+
+What is next ?
+~~~~~~~~~~~~~~
+
+Although the application is fully functionnal, its look is very
+basic. In the following section we will learn to create views to
+customize how data is displayed.
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/fr/MERGE_ME-tut-create-gae-app.fr.txt Tue Nov 18 01:16:30 2008 +0100
@@ -0,0 +1,218 @@
+.. -*- coding: utf-8 -*-
+
+.. _tutorielGAE:
+
+Tutoriel : créer votre première application web pour Google AppEngine
+=====================================================================
+
+Ce tutoriel va vous guider pas à pas a construire une apllication web
+de gestion de Blog afin de vous faire découvrir les fonctionnalités de
+`CubicWeb`.
+
+Nous supposons que vous avec déjà suivi le guide :ref:`installationGAE`.
+
+
+Créez une nouvelle application
+------------------------------
+
+Nous choisissons dans ce tutoriel de développer un blog comme un exemple
+d'application web et nous allons expliciter toutes les étapes nécessaires
+à sa réalisation.
+
+::
+
+ cubicweb-ctl newgapp blogdemo
+
+`newgapp` est la commande permettant de créer une instance `CubicWeb` pour
+le datastore.
+
+Assurez-vous que votre variable d'environnement ``PYTHONPATH`` est correctement
+initialisée (:ref:`installationGAE`)
+
+Définissez un schéma
+--------------------
+
+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.
+
+Commençons par un schéma simple que nous améliorerons progressivemment.
+
+Une fois votre instance ``blogdemo`` crée, vous trouverez un fichier ``schema.py``
+contenant la définition des entités suivantes : ``Blog`` and ``BlogEntry``.
+
+::
+
+ class Blog(EntityType):
+ title = String(maxsize=50, required=True)
+ description = String()
+
+ class BlogEntry(EntityType):
+ title = String(maxsize=100, required=True)
+ publish_date = Date(default='TODAY')
+ text = String(fulltextindexed=True)
+ category = String(vocabulary=('important','business'))
+ 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 and 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`.
+
+Lancez l'application
+--------------------
+
+Définir ce simple schéma est suffisant pour commencer. Assurez-vous
+que vous avez suivi les étapes décrites dans la section installation
+(en particulier visitez http://localhost:8080/_load en tant qu'administrateur
+afin d'initialiser le datastore), puis lancez votre application avec la commande ::
+
+ python dev_appserver.py BlogDemo
+
+puis dirigez vous vers http://localhost:8080/ (ou si c'est plus facile
+vous pouvez utiliser la démo en ligne http://lax.appspot.com/).
+[FIXME] -- changer la demo en ligne en quelque chose qui marche (!)
+
+.. image:: images/lax-book.00-login.fr.png
+ :alt: login screen
+
+Après vous être authentifié, vous arrivez sur la page d'accueil de votre
+application. Cette page liste les types d'entités accessibles dans votre
+application, en l'occurrence : Blog et Articles. Si vous lisez ``blog_plural``
+et ``blogentry_plural`` cela signifie que l'internationalisation (i18n)
+n'a pas encore fonctionné. Ignorez cela pour le moment.
+
+.. image:: images/lax-book.01-start.fr.png
+ :alt: home page
+
+Créez des entités système
+-------------------------
+
+Vous ne pourrez créer de nouveaux utilisateurs que dans le cas où vous
+avez choisi de ne pas utiliser l'authentification Google.
+
+
+[WRITE ME : create users manages permissions etc]
+
+
+
+Créez des entités applicatives
+------------------------------
+
+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/lax-book.02-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/lax-book.03-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``
+
+
+.. image:: images/lax-book.04-detail-one-blog.fr.png
+ :alt: displaying the detailed view of a blog
+
+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/lax-book.05-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/lax-book.06-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/lax-book.07-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, exécutez
+la commande ``laxctl genschema blogdemo`` et vous pourrez visualiser
+votre schéma a l'URL suivante : http://localhost:8080/schema
+
+.. image:: images/lax-book.08-schema.fr.png
+ :alt: graphical view of the schema (aka data-model)
+
+
+Change view permission
+~~~~~~~~~~~~~~~~~~~~~~
+
+
+
+Conclusion
+----------
+
+Exercise
+~~~~~~~~
+
+Create new blog entries in ``Tech-blog``.
+
+What we learned
+~~~~~~~~~~~~~~~
+
+Creating a simple schema was enough to set up a new application that
+can store blogs and blog entries.
+
+What is next ?
+~~~~~~~~~~~~~~
+
+Although the application is fully functionnal, its look is very
+basic. In the following section we will learn to create views to
+customize how data is displayed.
+
+
--- a/doc/book/fr/advanced_notes.fr.txt Mon Nov 17 14:38:30 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-La différence entre la classe `AppRsetObject` et la classe `AppObject` est que
-les instances de la premières sont séléctionnées pour une requête et un "result
-set" et alors que les secondes ne sont séléctionnées qu'en fonction de leur
-identifiant.
--- a/doc/book/fr/chap_addons.txt Mon Nov 17 14:38:30 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _contents:
-
-==========
-References
-==========
-
-.. toctree::
- :maxdepth: 1
-
- chap_rql.txt
- chap_migration.txt
- chap_tests.txt
- chap_i18n.txt
-
-
--- a/doc/book/fr/chap_autres_composants_ui.txt Mon Nov 17 14:38:30 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-Autres composants de l'interface web
-====================================
-
-Actions
--------
-XXXFILLME
-
-Component, VComponent
----------------------
-XXXFILLME
-
-EProperty
----------
-XXXFILLME
--- a/doc/book/fr/chap_configuration_instance.txt Mon Nov 17 14:38:30 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,162 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Configuration d'une instance
-============================
-
-À la création d'une instance, un fichier de configuration est généré dans ::
-
- $(CW_REGISTRY)/<instance>/<nom configuration>.conf
-
-par exemple ::
-
- /etc/cubicweb.d/jpl/all-in-one.conf
-
-C'est un simple fichier texte au format INI. Dans la description suivante,
-chaque nom d'option est préfixé de sa section et suivi de sa valeur par défaut
-le cas échéant, e.g. "`<section>.<option>` [valeur]".
-
-
-Configuration du serveur web
-----------------------------
-:`web.auth-mode` [cookie]:
- mode d'authentification, cookie ou http
-:`web.realm`:
- realm de l'application en mode d'authentification http
-:`web.http-session-time` [0]:
- délai d'inactivité d'une session HTTP avant sa fermeture automatique. Durée
- en secondes, 0 signifiant pas d'expiration (ou plus exactement lors de la
- fermeture du navigateur du client)
-
-:`main.anonymous-user`, `main.anonymous-password`:
- login et mot de passe à utiliser pour se connecter au serveur RQL lors des
- connexions HTTP anonymes. Il faut que le compte EUser associé existe.
-
-:`main.base-url`:
- url de base du site, à utiliser pour générer les urls des pages web
-
-Configuration https
-```````````````````
-Il est possible de rendre un site accessible en http pour les connections
-anonymes et en https pour les utilisateurs authentifié. Il faut pour cela
-utiliser apache (par ex.) pour la redirection et la variable `main.https-url` du
-fichier de configuration.
-
-:Exemple:
-
- pour une redirection apache d'un site accessible via `http://localhost/demo`
- et `https://localhost/demo` et qui tourne en réalité sur le port 8080, il
- faut avoir pour la version http : ::
-
- RewriteCond %{REQUEST_URI} ^/demo
- RewriteRule ^/demo$ /demo/
- RewriteRule ^/demo/(.*) http://127.0.0.1:8080/$1 [L,P]
-
- et pour la version https : ::
-
- RewriteCond %{REQUEST_URI} ^/demo
- RewriteRule ^/demo$ /demo/
- RewriteRule ^/demo/(.*) http://127.0.0.1:8080/https/$1 [L,P]
-
-
- et on aura dans le fichier all-in-one.conf de l'instance : ::
-
- base-url = http://localhost/demo
- https-url = `https://localhost/demo`
-
-Configuration de l'interface web
---------------------------------
-:`web.embed-allowed`:
- expression régulière correspondant aux sites pouvant être "incorporé" dans
- le site (controleur 'embed')
-:`web.submit-url`:
- url à laquelle les bugs rencontrés dans l'application peuvent être posté
-
-
-Configuration du serveur RQL
-----------------------------
-:`main.host`:
- nom de l'hôte s'il ne peut être détecter correctement
-:`main.pid-file`:
- fichier où sera écrit le pid du serveur
-:`main.uid`:
- compte utilisateur à utiliser pour le lancement du serveur quand il est
- lancé en root par init
-:`main.session-time [30*60]`:
- temps d'expiration d'une session RQL
-:`main.query-log-file`:
- fichier dans lequel écrire toutes les requêtes RQL éxécutées par le serveur
-
-
-Configuration Pyro pour l'instance
------------------------------------
-Coté serveur web :
-
-:`pyro-client.pyro-application-id`:
- identifiant pyro du serveur RQL (e.g. le nom de l'instance)
-
-Coté serveur RQL :
-
-:`pyro-server.pyro-port`:
- numéro de port pyro. Si aucune valeur n'est spécifiée, un port est attribué
- automatiquement.
-
-Coté serveur RQL et serveur web :
-
-:`pyro-name-server.pyro-ns-host`:
- nom de l'hôte hébergeant le serveur de nom pyro. Si aucune valeur n'est
- spécifié, il est localisé par une requête de broadcast
-:`pyro-name-server.pyro-ns-group` [cubicweb]:
- groupe pyro sous lequel enregistrer l'application
-
-
-Configuration courriel
-----------------------
-Coté serveur RQL et serveur web :
-
-:`email.mangle-emails [no]`:
- indique si les adresses email doivent être affichées telle quelle ou
- transformée
-
-Coté serveur RQL :
-
-:`email.smtp-host [mail]`:
- nom de l'hôte hébergeant le serveur SMTP à utiliser pour le courriel sortant
-:`email.smtp-port [25]`:
- port du serveur SMTP à utiliser pour le courriel sortant
-:`email.sender-name`:
- nom à utiliser pour les courriels sortant de l'application
-:`email.sender-addr`:
- adresse à utiliser pour les courriels sortant de l'application
-:`email.default-dest-addrs`:
- adresses de destination par défaut, si utilisé par la configuration de la
- diffusion du modèle (séparées par des virgules)
-:`email.supervising-addrs`:
- addresses de destination des courriels de supervision (séparées par des
- virgules)
-
-
-Configuration journalisation
-----------------------------
-:`main.log-threshold`:
- niveau de filtrage des messages (DEBUG, INFO, WARNING, ERROR)
-:`main.log-file`:
- fichier dans lequel écrire les messages
-
-
-Configuration Eproperties
--------------------------
-D'autres paramètres de configuration sont sous la forme d'entités `EProperty`
-dans la base de données. Il faut donc les éditer via l'interface web ou par des
-requêtes rql.
-
-:`ui.encoding`:
- encodage de caractères à utiliser pour l'interface web
-:`navigation.short-line-size`: # XXX should be in ui
- nombre de caractères maximum pour les affichages "courts"
-:`navigation.page-size`:
- nombre d'entités maximum à afficher par page de résultat
-:`navigation.related-limit`:
- nombre d'entités liées maximum à afficher sur la vue primaire d'une entité
-:`navigation.combobox-limit`:
- nombre d'entités non liées maximum à afficher sur les listes déroulantes de
- la vue d'édition d'une entité
--- a/doc/book/fr/chap_creation_instance.txt Mon Nov 17 14:38:30 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-
-=======================
-Création d'une instance
-=======================
-
-.. toctree::
- :maxdepth: 1
-
- sect_installation.txt
- sect_cubicweb-ctl.txt
-
--- a/doc/book/fr/chap_definition_schema.txt Mon Nov 17 14:38:30 2008 -0800
+++ /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 "<type d'entité sujet>
-<type de relation> <type d'entité objet>". Eventuellement un type de relation
-sera créé implicitement si aucun n'est associé à une définition de relation du
-schema.
-
-.. include:: sect_stdlib_schemas.txt
-.. include:: sect_definition_schema.txt
-
--- a/doc/book/fr/chap_definition_workflows.txt Mon Nov 17 14:38:30 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,154 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Définition de workflow
-======================
-On peut mettre une condition rql ou/et un groupe auquel doit appartenir l'utilisateur.
-
-Si on met à la fois un(ou plusieurs) groupe et une condition RQL, il faut que les deux soient respectés.
-
-Si on met plusieurs groupes, il faut que l'utilisateur soit dans un des groupes.
-
-Pour la condition RQL sur une transition, on peut y mettre les substitutions suivantes :
-
-* `%(eid)s`, eid de l'objet
-* `%(ueid)s`, eid de l'utilisateur qui fait la requête
-* `%(seid)s`, eid de l'état courant de l'objet
-
-Dans le script de création d'un workflow, penser à mettre `_()` autour des noms d'états et de transitions
-pour que ceux si soient pris en compte par les scripts de gestion des catalogues i18n.
-
-General
--------
-
-A workflow can be defined in a `LAX` application thanks to the system
-entities ``State`` and ``Transition``. Those are defined within all
-LAX application and can be set-up through the main administrator interface.
-
-Once your schema is defined, you can start creating the set of states and
-the required transitions for your applications entities.
-
-You first need to define the states and then the transitions between those
-to complete your workflow.
-
-A ``State`` defines the status of an entity. While creating a new state,
-you will be first given the option to select the entity type the state
-can be applied to. By choosing ``Apply``, a new section will be displayed
-in the editing screen to enable you to add relation to the state you are
-creating.
-
-A ``Transition`` is also based on an entity type it can be applied to.
-By choosing ``Apply``, a new section will be displayed in the editing
-screen to enable you to add relation to the transition you are
-creating.
-
-At the transition level you will also define the group of user which can
-aplly this transition to an object.
-
-
-Example of a simple workflow
-----------------------------
-
-Please see the tutorial to view and example of a simple workflow.
-
-
-[Create a simple workflow for BlogDemo, to have a moderator approve new blog
-entry to be published. This implies, specify a dedicated group of blog
-moderator as well as hide the view of a blog entry to the user until
-it reaches the state published]
-
-Set-up a workflow
------------------
-
-Before starting, make sure you refresh your mind by reading [link to
-definition_workflow chapter].
-
-We want to create a workflow to control the quality of the BlogEntry
-submitted on your application. When a BlogEntry is created by a user
-its state should be `submitted`. To be visible to all, it needs to
-be in the state `published`. To move from `submitted` to `published`
-we need a transition that we can name `approve_blogentry`.
-
-We do not want every user to be allowed to change the state of a
-BlogEntry. We need to define a group of user, `moderators`, and
-this group will have appropriate permissions to approve BlogEntry
-to be published and visible to all.
-
-There are two ways to create a workflow, form the user interface,
-and also by defining it in ``migration/postcreate.py``. This script
-is executed each time a new ``./bin/laxctl db-init`` is done.
-If you create the states and transitions through the user interface
-this means that next time you will need to initialize the database
-you will have to re-create all the entities.
-We strongly recommand you create the workflow in ``migration\postcreate.py``
-and we will now show you how.
-The user interface would only be a reference for you to view the states
-and transitions but is not the appropriate interface to define your
-application workflow.
-
-Update the schema
-~~~~~~~~~~~~~~~~~
-To enable a BlogEntry to have a State, we have to define a relation
-``in_state`` in the schema of BlogEntry. Please do as follows, add
-the line ``in_state (...)``::
-
- class BlogEntry(EntityType):
- title = String(maxsize=100, required=True)
- publish_date = Date(default='TODAY')
- text_format = String(meta=True, internationalizable=True, maxsize=50,
- default='text/rest', constraints=[format_constraint])
- text = String(fulltextindexed=True)
- category = String(vocabulary=('important','business'))
- entry_of = SubjectRelation('Blog', cardinality='?*')
- in_state = SubjectRelation('State', cardinality='1*')
-
-As you updated the schema, you will have re-execute ``./bin/laxctl db-init``
-to initialize the database and migrate your existing entities.
-[WRITE ABOUT MIGRATION]
-
-Create states, transitions and group permissions
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-At the time the ``postcreate.py`` script is executed, several methods
-can be used. They are all defined in the ``class ServerMigrationHelper``.
-We will only discuss the method we use to create a wrokflow here.
-
-To define our workflow for BlogDemo, please add the following lines
-to ``migration/postcreate.py``::
-
- _ = unicode
-
- moderators = add_entity('EGroup', name=u"moderators")
-
- submitted = add_state(_('submitted'), 'BlogEntry', initial=True)
- published = add_state(_('published'), 'BlogEntry')
-
- add_transition(_('approve_blogentry'), 'BlogEntry', (submitted,), published, ('moderators', 'managers'),)
-
- checkpoint()
-
-``add_entity`` is used here to define the new group of users that we
-need to define the transitions, `moderators`.
-If this group required by the transition is not defined before the
-transition is created, it will not create the relation `transition
-require the group moderator`.
-
-``add_state`` expects as the first argument the name of the state you are
-willing to create, then the entity type on which the state can be applied,
-and an optionnal argument to set if the state is the initial state
-of the entity type or not.
-
-``add_transition`` expects as the first argument the name of the
-transition, then the entity type on which we can apply the transition,
-then the list of possible initial states from which the transition
-can be applied, the target state of the transition, and the permissions
-(e.g. list of the groups of users who can apply the transition).
-
-.. image:: images/lax-book.03-transitions-view.fr.png
-
-You can now notice that in the actions box of a BlogEntry, the state
-is now listed as well as the possible transitions from this state
-defined by the workflow. This transition, as defined in the workflow,
-will only being displayed for the users belonging to the group
-moderators of managers.
-
-
--- a/doc/book/fr/chap_developper_application.txt Mon Nov 17 14:38:30 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _contents:
-
-==================
-Les indispensables
-==================
-
-.. toctree::
- :maxdepth: 1
-
- chap_fondements_cubicweb.txt
- chap_mise_en_place_environnement.txt
- chap_configuration_instance.txt
- chap_definition_schema.txt
- chap_definition_workflows.txt
- chap_visualisation_donnees.txt
- chap_manipulation_donnees.txt
- chap_ui_gestion_formulaire.txt
- chap_ui_js_json.txt
- chap_autres_composants_ui.txt
- chap_securite.txt
- chap_serveur_crochets.txt
- chap_serveur_notification.txt
-
--- a/doc/book/fr/chap_fondements_cubicweb.txt Mon Nov 17 14:38:30 2008 -0800
+++ /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 (`EProperty`)
- * 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
--- a/doc/book/fr/chap_i18n.txt Mon Nov 17 14:38:30 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _Internationalisation:
-
-
-Internationalisation
-====================
-
-Le système d'internationalisation de l'interface web de CubicWeb est basé sur le
-système `GNU gettext`_.
-
-.. _`GNU gettext`: http://www.gnu.org/software/gettext/
-
-Messages à internationaliser
-----------------------------
-
-Marquage des messages à internaliser
-````````````````````````````````````
-Les chaines de caractères à internationaliser sont marqués par l'appel à la
-fonction `_` *OU* par la méthode équivalent de la requête dans le code python ou
-dans les expressions python de template TAL.
-
-Dans les templates cubicweb-tal, il est également possible d'insérer une chaine à
-traduire via les balises `i18n:content` et `i18n:replace`.
-
-De plus des messages correspondant aux entités/relations utilisés par le schéma
-de l'application seront automatiquement ajoutés.
-
-Renvoi d'un message internationalisé lors de la construction d'une page
-```````````````````````````````````````````````````````````````````````
-La fonction *built-in* `_` ne doit servir qu'**à marquer les messages à
-traduire**, non pas à récupérer une traduction. Il faut pour cela utiliser la
-méthode `_` de l'objet requête, sans quoi vous récupérerez l'identifiant de
-message au lieu de sa traduction dans la langue propre à la requête.1
-
-
-Gestion des catalogues de traduction
-------------------------------------
-Une fois l'application rendu internationalisable coté code, reste à gérer les
-catalogues de traductions. cubicweb-ctl intègre pour cela les commandes suivantes :
-
-* `i18nlibupdate`, met à jour les catalogues de messages *de la librairie
- cubicweb*. Sauf si vous développez sur le framework (et non votre propre
- application), vous ne devriez pas avoir à utiliser cette commande
-
-* `i18nupdate`, met à jour les catalogues de messages *du composant* (ou de tous
- les composants). A la suite de cette commande, vous devez mettre à jour les
- fichiers de traduction *.po* dans le sous-répertoire "i18n" de votre
- template. Évidemment les traductions précédentes toujours utilisées ont été
- conservées.
-
-* `i18ncompile`, recompile les catalogues de messages *d'une instance* (ou de
- toutes les instances) après mise à jour des catalogues de son composant. Cela
- est effectué automatiquement lors d'une création ou d'une mise à jour. Les
- catalogues de messages compilés se trouvent dans le répertoire
- "i18n/<lang>/LC_MESSAGES/cubicweb.mo" de l'application où `lang` est
- l'identifiant de la langue sur 2 lettres ('en' ou 'fr' par exemple)
-
-
-Le cas classique
-````````````````
-Vous avez ajouté et/ou modifié des messages d'un composant utilisé par votre
-application (en ajoutant une nouvelle vue ou en ayant modifié le schéma par
-exemple) :
-
-1. `cubicweb-ctl i18nupdate <composant>`
-2. éditer les fichiers <composant>/xxx.po dans pour y rajouter les traductions
- manquantes (`msgstr` vide)
-3. `hg ci -m "updated i18n catalogs"`
-4. `cubicweb-ctl i18n compile <monapplication>`
-
--- a/doc/book/fr/chap_manipulation_donnees.txt Mon Nov 17 14:38:30 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,142 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-
-Manipulation des données stockées
-=================================
-
-Les classes `Entity` et `AnyEntity`
------------------------------------
-Pour fournir un comportement spécifique à un type d'entité, il suffit de définir
-une classe héritant de la class `ginco.entities.AnyEntity`. En général il faut
-définir ces classes dans un module du package `entities` d'une application pour
-qu'elle soit disponible à la fois coté serveur et coté client.
-
-La classe `AnyEntity` est une classe chargée dynamiquement héritant de la classe
-de base `Entity` (`ginco.common.entity`). On définit une sous-classe pour
-ajouter des méthodes ou spécialiser les comportements d'un type d'entité donné.
-
-Des descripteurs sont ajoutés à l'enregistrement pour initialiser la classe en
-fonction du schéma :
-
-* on peut accéder aux attributs définis dans le schéma via les attributs de même
- nom sur les instances (valeur typée)
-
-* on peut accéder aux relations définies dans le schéma via les attributs de même
- nom sur les instances (liste d'instances d'entité)
-
-Les méthodes définies sur la classe `AnyEntity` ou `Entity` sont les suivantes :
-
-* `has_eid()`, retourne vrai si l'entité à un eid affecté (i.e. pas en cours de
- création)
-
-* `check_perm(action)`, vérifie que l'utilisateur à le droit d'effectuer
- l'action demandée sur l'entité
-
-:Formattage et génération de la sortie:
-
- * `view(vid, **kwargs)`, applique la vue donnée à l'entité
-
- * `absolute_url(**kwargs)`, retourne une URL absolue permettant d'accéder à la
- vue primaire d'une entité
-
- * `rest_path()`, renvoie une l'URL REST relative permettant d'obtenir l'entité
-
- * `format(attr)`, retourne le format (type MIME) du champ passé en argument
-
- * `printable_value(attr, value=_marker, attrtype=None, format='text/html')`,
- retourne une chaine permettant l'affichage dans un format donné de la valeur
- d'un attribut (la valeur est automatiquement récupérée au besoin)
-
- * `display_name(form='')`, retourne une chaîne pour afficher le type de
- l'entité, en spécifiant éventuellement la forme désirée ('plural' pour la
- forme plurielle)
-
-:Gestion de données:
-
- * `as_rset()`, transforme l'entité en un resultset équivalent simulant
- le résultat de la requête `Any X WHERE X eid _eid_`
-
- * `complete(skip_bytes=True)`, effectue une requête permettant de récupérer d'un
- coup toutes les valeurs d'attributs manquant sur l'entité
-
- * `get_value(name)`, récupere la valeur associée à l'attribut passé en argument
-
- * `related(rtype, x='subject', limit=None, entities=False)`, retourne une liste
- des entités liées à l'entité courant par la relation donnée en argument
-
- * `unrelated(rtype, targettype, x='subject', limit=None)`, retourne un result set
- des entités not liées à l'entité courante par la relation donnée en argument
- et satisfaisants les contraintes de celle-ci
-
- * `set_attributes(**kwargs)`, met à jour la liste des attributs avec
- les valeurs correspondantes passées sous forme d'arguments nommés
-
- * `copy_relations(ceid)`, copie les relations de l'entité ayant l'eid passé en
- argument sur l'entité courante
-
- * `last_modified(view)`, retourne la date à laquelle on doit considérer
- l'objet comme modifié (utiliser par la gestion de cache HTTP)
-
- * `delete()` permet de supprimer l'entité représentée
-
-:Meta-données standard (Dublin Core):
-
- * `dc_title()`, retourne une chaine unicode correspondant à la méta-donnée
- 'Title' (utilise par défaut le premier attribut non 'meta' du schéma de
- l'entité)
-
- * `dc_long_title()`, comme dc_title mais peut retourner un titre plus détaillé
-
- * `dc_description(format='text/plain')`, retourne une chaine unicode
- correspondant à la méta-donnée 'Description' (cherche un attribut
- 'description' par défaut)
-
- * `dc_authors()`, retourne une chaine unicode correspondant à la méta-donnée
- 'Authors' (propriétaires par défaut)
-
- * `dc_date(date_format=None)`, retourne une chaine unicode
- correspondant à la méta-donnée 'Date' (date de modification par défaut)
-
-:Contrôle du vocabulaire pour les relations:
-
- * `vocabulary(rtype, x='subject', limit=None)`, appelée notamment
- par les vues d'édition d'erudi, elle renvoie une liste de couple
- (label, eid) des entités qui pourraient être liées à l'entité
- via la relation `rtype`
- * `subject_relation_vocabulary(rtype, limit=None)`, appelée
- en interne par `vocabulary` dans le cas d'une relation sujet
- * `object_relation_vocabulary(rtype, limit=None)`, appelée
- en interne par `vocabulary` dans le cas d'une relation objet
- * `relation_vocabulary(rtype, targettype, x, limit=None)`, appelé
- en interne par `subject_relation_vocabulary` et `object_relation_vocabulary`
-
-
-Les *rtags*
------------
-Les *rtags* permettent de spécifier certains comportements propres aux relations
-d'un type d'entité donné (voir plus loin). Ils sont définis sur la classe
-d'entité via l'attribut `rtags` qui est un dictionnaire dont les clés sont un
-triplet ::
-
- <type de relation>, <type d'entité cible>, <position du contexte ("subject" ou "object"
-
-et les valeurs un `set` ou un tuple de marqueurs définissant des propriétés
-s'appliquant à cette relation.
-
-Il est possible de simplifier ce dictionnaire :
-
-* si l'on veut spécifier un seul marqueur, il n'est pas nécessaire d'utiliser
- un tuple comme valeur, le marqueur seul (chaine de caractères) suffit
-* si l'on s'intéresse uniquement à un type de relation et non à la cible et à la
- position du contexte (ou que celui-ci n'est pas ambigüe), on peut simplement
- utiliser le nom du type de relation comme clé
-* si l'on veut qu'un marqueur s'applique quelque soit le type d'entité cible, il
- faut utiliser la chaine `*` comme type d'entité cible
-
-A noter également que ce dictionnaire est *traité à la création de la classe*.
-Il est automatiquement fusionné avec celui de la ou des classe(s) parentes (pas
-besoin de copier celui de la classe parent pour le modifier). De même modifier
-celui-ci après création de la classe n'aura aucun effet...
-
-
-.. include:: sect_definition_entites.txt
--- a/doc/book/fr/chap_migration.txt Mon Nov 17 14:38:30 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,218 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-
-Migration
-=========
-
-Une des idées de base d'Erudi est la création incrémentale d'application, et
-pour cela de nombreuses actions sont fournies afin de facilement faire évoluer
-une application et tout particulièrement le modèle de données manipulé sans
-perdre les données des instances existantes.
-
-La version courante d'un modèle d'application est données dans le fichier
-`__pkginfo__.py` sous forme d'un tuple de 3 entiers.
-
-
-Gestion des scripts de migrations
----------------------------------
-Les scripts des migrations doivent être placés dans le répertoire `migration` de
-l'application, et nommé de la manière suivante :
-
-::
-
- <n° de version X.Y.Z>[_<description>]_<mode>.py
-
-dans lequel :
-
-* X.Y.Z correspond au n° de version du modèle vers lequel le script permet de
- migrer,
-
-* le *mode* (entre le dernier "_" et l'extension ".py") indique à quelle partie
- de l'application (serveur RQL, serveur web) le script s'applique en cas
- d'installation distribuée. Il peut valoir :
-
- * `common`, s'applique aussi bien sur le serveur RQL que sur le serveur web,
- et met à jour des fichiers sur le disque (migration de fichier de
- configuration par exemple).
-
- * `web`, s'applique uniquement sur le serveur web, et met à jour des fichiers
- sur le disque
-
- * `repository`, s'applique uniquement sur le serveur RQL, et met à jour des
- fichiers sur le disque
-
- * `Any`, s'applique uniquement sur le serveur RQL, et met à jour des
- données en base (migrations de schéma et de données par ex.)
-
-
-Toujours dans le répertoire `migration`, le fichier spécial `depends.map` permet
-d'indiquer que pour migrer vers une version spécifique du modèle, il faut tout
-d'abord avoir migrer vers une version données de erudi. Ce fichier peut contenir
-des commentaires (lignes commençant par un "#"), et une dépendance est notée sur
-une ligne de la manière suivante : ::
-
- <n° de version du modèle X.Y.Z> : <n° de version erudi X.Y.Z>
-
-Par exemple ::
-
- 0.12.0: 2.26.0
- 0.13.0: 2.27.0
- # 0.14 works with 2.27 <= erudi <= 2.28 at least
- 0.15.0: 2.28.0
-
-
-Contexte de base
-----------------
-Les identifiants suivants sont préféfinis dans les scripts de migration :
-
-* `config`, configuration de l'instance
-
-* `interactive_mode`, booléen indiquant si le script est éxécuté en mode
- interactif ou non
-
-* `appltemplversion`, version du modèle d'application de l'instance
-
-* `applerudiversion`, version erudi de l'instance
-
-* `templversion`, version du modéle d'application installée
-
-* `erudiversion`, version erudi installée
-
-* `confirm(question)`, fonction posant une question et retournant vrai si
- l'utilisateur a répondu oui, faux sinon (retourne toujours vrai en mode non
- interactif)
-
-* `_`, fonction équivalente à `unicode` permettant de marquer des chaines à
- internationaliser dans les scripts de migration
-
-Dans les scripts "repository", les identifiants suivant sont également définis :
-
-* `checkpoint`, demande confirmant et effectue un "commit" au point d'appel
-
-* `repo_schema`, schéma persistent de l'instance (i.e. schéma de l'instance en
- cours de migration)
-
-* `newschema`, schéma installé sur le système de fichier (i.e. schéma de la
- version à jour du modèle et de erudi)
-
-* `sqlcursor`, un curseur SQL pour les très rares cas où il est réellement
- nécessaire ou avantageux de passer par du sql
-
-* `repo`, l'objet repository
-
-
-Migration de schéma
--------------------
-Les fonctions de migration de schéma suivantes sont disponibles dans les scripts
-"repository" :
-
-* `add_attribute(etype, attrname, attrtype=None, commit=True)`, ajoute un
- nouvel attribut à un type d'entité existante. Si le type de celui-ci n'est pas
- spécifié il est extrait du schéma à jour.
-
-* `drop_attribute(etype, attrname, commit=True)`, supprime un
- attribut à un type d'entité existante.
-
-* `rename_attribute(etype, oldname, newname, commit=True)`, renomme un attribut
-
-* `add_entity_type(etype, auto=True, commit=True)`, ajoute un nouveau type
- d'entité. Si `auto` est vrai, toutes les relations utilisant ce type d'entité
- et ayant un type d'entité connu à l'autre extrémité vont également être
- ajoutées.
-
-* `drop_entity_type(etype, commit=True)`, supprime un type d'entité et toutes
- les relations l'utilisant.
-
-* `rename_entity_type(oldname, newname, commit=True)`, renomme un type d'entité
-
-* `add_relation_type(rtype, addrdef=True, commit=True)`, ajoute un nouveau type
- de relation. Si `addrdef` est vrai, toutes les définitions de relation de ce
- type seront également ajoutées.
-
-* `drop_relation_type(rtype, commit=True)`, supprime un type de relation et
- toutes les définitions de ce type.
-
-* `rename_relation(oldname, newname, commit=True)`, renomme une relation.
-
-* `add_relation_definition(subjtype, rtype, objtype, commit=True)`, ajoute une
- définition de relation.
-
-* `drop_relation_definition(subjtype, rtype, objtype, commit=True)`, supprime
- une définition de relation.
-
-* `synchronize_permissions(ertype, commit=True)`, synchronise les permissions
- d'un type d'entité ou de relation
-
-* `synchronize_rschema(rtype, commit=True)`, synchronise les propriétés et
- permissions d'un type de relation.
-
-* `synchronize_eschema(etype, commit=True)`, synchronise les propriétés et
- permissions d'un type d'entité.
-
-* `synchronize_schema(commit=True)`, synchronise le schéma persistent avec le
- schéma à jour (mais sans ajouter ni supprimer de nouveaux types d'entités ou
- de relations ni de définitions de relation).
-
-* `change_relation_props(subjtype, rtype, objtype, commit=True, **kwargs)`, change
- les propriétés d'une definition de relation en utilisant les arguments nommés
- pour les propriétés à changer.
-
-* `set_widget(etype, rtype, widget, commit=True)`, change le widget à utiliser
- pour la relation <rtype> du type d'entité <etype>
-
-* `set_size_constraint(etype, rtype, size, commit=True)`, change la contrainte
- de taille pour la relation <rtype> du type d'entité <etype>
-
-
-Migration de données
---------------------
-Les fonctions de migration de données suivantes sont disponibles dans les scripts
-"repository" :
-
-* `rql(rql, kwargs=None, cachekey=None, ask_confirm=True)`, éxécute une
- requête rql arbitraire, d'interrogation ou de modification. Un objet result
- set est retourné.
-
-* `add_entity(etype, *args, **kwargs)`, ajoute une nouvelle entité du type
- données. La valeur des attributs et relations est spécifiée en utilisant les
- arguments nommés et positionnels.
-
-
-Création de workflow
---------------------
-Les fonctions de création de workflow suivantes sont disponibles dans les scripts
-"repository" :
-
-* `add_state(name, stateof, initial=False, commit=False, **kwargs)`, ajoute un
- nouvel état de workflow
-
-* `add_transition(name, transitionof, fromstates, tostate, requiredgroups=(), commit=False, **kwargs)`,
- ajoute une nouvelle transtion de workflow
-
-Migration de configuration
---------------------------
-Les fonctions de migration de configuration suivantes sont disponibles dans tout
-les scripts :
-
-* `option_renamed(oldname, newname)`, indique qu'une option a été renommée
-
-* `option_group_change(option, oldgroup, newgroup)`, indique qu'une option a
- changé de groupe
-
-* `option_added(oldname, newname)`, indique qu'une option a été ajoutée
-
-* `option_removed(oldname, newname)`, indique qu'une option a été supprimée
-
-
-Autres fonctions de migration
------------------------------
-Ces fonctions ne sont utilisés que pour des opérations de bas niveau
-irréalisables autrement ou pour réparer des bases cassées lors de session
-interactive. Elles sont disponibles dans les scripts "repository".
-
-* `sqlexec(sql, args=None, ask_confirm=True)`, éxécute une requête sql
- arbitraire, à n'utiliser
-
-* `add_entity_type_table(etype, commit=True)`
-* `add_relation_type_table(rtype, commit=True)`
-* `uninline_relation(rtype, commit=True)`
--- a/doc/book/fr/chap_mise_en_place_environnement.txt Mon Nov 17 14:38:30 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _MiseEnPlaceEnv:
-
-Installation et mise en place d'un environnement `CubicWeb`
-===========================================================
-
-
-
-.. toctree::
- :maxdepth: 1
-
- sect_installation.txt
- sect_creation_instance.txt
- sect_cubicweb-ctl.txt
- sect_mercurial.txt
-
--- a/doc/book/fr/chap_rql.txt Mon Nov 17 14:38:30 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Le langage RQL (Relation Query Language)
-========================================
-
-Voir la `documentation de RQL <file:///home/sandrine/src/fcubicweb/rql/doc/build/html/index.html>`_ .
-
-
-[TODO]
-Specific link to RQL complete documentation to remove duplicated content.
-
--- a/doc/book/fr/chap_securite.txt Mon Nov 17 14:38:30 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Utilisateurs de l'application : Le contrôle d'accès
-===================================================
-
-
-Vocabulaire
------------
-* Personne, Societe définissent deux *types* d'entité
-* "Personne travaille_pour Societé" déclare qu'une relation
- travaille_pour peut exister entre une entité de type Personne et une
- entité de type Societe. L'ensemble des règles de ce type appliqué
- à la relation "travaille_pour" définit le schéma de la relation
- "travaille_pour"
-
-
-Description du modèle de sécurité
----------------------------------
-
-Le modèle de sécurité de CubicWeb est un modèle fondé sur des `Access
-Control List`. Les notions sont les suivantes :
-
-* utilisateurs et groupes d'utilisateurs
-* un utilisateur appartient à au moins un groupe
-* droits (lire, modifier, créer, supprimer)
-* les droits sont attribués aux groupes (et non aux utilisateurs)
-
-Pour CubicWeb plus spécifiquement :
-
-* on associe les droits au niveau des schemas d'entites / relations
-* pour chaque type d'entité, on distingue les droits de lecture,
- ajout, modification et suppression
-* pour chaque type de relation, on distingue les droits de lecture,
- ajout et suppression (on ne peut pas modifer une relation)
-* les groupes de base sont : Administrateurs, Utilisateurs, Invités
-* les utilisateurs font par défaut parti du groupe Utilisateurs
-* on a un groupe virtuel "Utilisateurs Propriétaires", auquel on peut
- associer uniquement les droits de suppression et de modification
-* on ne peut pas mettre d'utilisateurs dans ce groupe, ils y sont
- ajoutés implicitement dans le contexte des objets dont ils sont
- propriétaires
-* les droits de ce groupe ne sont vérifiés que sur
- modification / suppression si tous les autres groupes auxquels
- l'utilisateur appartient se sont vu interdir l'accès
-
--- a/doc/book/fr/chap_serveur_crochets.txt Mon Nov 17 14:38:30 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Les crochets (*hooks*)
-======================
-
-XXX FILLME
-
-Les crochets sont appelés avant ou après la mise à jour d'une entité ou d'une
-relations dans le dépot
-
-Leur prototypes sont les suivants
-
-
- * after_add_entity (session, entity)
- * after_update_entity (session, entity)
- * after_delete_entity (session, eid)
- * before_add_entity (session, entity)
- * before_update_entity (session, entity)
- * before_delete_entity (session, eid)
-
- * after_add_relation (session, fromeid, rtype, toeid)
- * after_delete_relation (session, fromeid, rtype, toeid)
- * before_add_relation (session, fromeid, rtype, toeid)
- * before_delete_relation (session, fromeid, rtype, toeid)
-
- * server_startup
- * server_shutdown
-
- * session_open
- * session_close
-
--- a/doc/book/fr/chap_serveur_notification.txt Mon Nov 17 14:38:30 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Gestion de notifications
-========================
-
-XXX FILLME
--- a/doc/book/fr/chap_site_configuration.txt Mon Nov 17 14:38:30 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Interface de configuration du site
-==================================
-
-.. image:: images/lax-book.03-site-config-panel.fr.png
-
-This panel allows you to configure the appearance of your application site.
-Six menus are available and we will go through each of them to explain how
-to use them.
-
-Navigation
-~~~~~~~~~~
-This menu provides you a way to adjust some navigation options depending on
-your needs, such as the number of entities to display by page of results.
-Follows the detailled list of available options :
-
-* navigation.combobox-limit : maximum number of entities to display in related
- combo box (sample format: 23)
-* navigation.page-size : maximum number of objects displayed by page of results
- (sample format: 23)
-* navigation.related-limit : maximum number of related entities to display in
- the primary view (sample format: 23)
-* navigation.short-line-size : maximum number of characters in short description
- (sample format: 23)
-
-UI
-~~
-This menu provides you a way to customize the user interface settings such as
-date format or encoding in the produced html.
-Follows the detailled list of available options :
-
-* ui.date-format : how to format date in the ui ("man strftime" for format description)
-* ui.datetime-format : how to format date and time in the ui ("man strftime" for format
- description)
-* ui.default-text-format : default text format for rich text fields.
-* ui.encoding : user interface encoding
-* ui.fckeditor :should html fields being edited using fckeditor (a HTML WYSIWYG editor).
- You should also select text/html as default text format to actually get fckeditor.
-* ui.float-format : how to format float numbers in the ui
-* ui.language : language of the user interface
-* ui.main-template : id of main template used to render pages
-* ui.site-title : site title, which is displayed right next to the logo in the header
-* ui.time-format : how to format time in the ui ("man strftime" for format description)
-
-
-Actions
-~~~~~~~
-This menu provides a way to configure the context in which you expect the actions
-to be displayed to the user and if you want the action to be visible or not.
-You must have notice that when you view a list of entities, an action box is
-available on the left column which display some actions as well as a drop-down
-menu for more actions.
-
-The context available are :
-
-* mainactions : actions listed in the left box
-* moreactions : actions listed in the `more` menu of the left box
-* addrelated : add actions listed in the left box
-* useractions : actions listed in the first section of drop-down menu
- accessible from the right corner user login link
-* siteactions : actions listed in the second section of drop-down menu
- accessible from the right corner user login link
-* hidden : select this to hide the specific action
-
-Boxes
-~~~~~
-The application has already a pre-defined set of boxes you can use right away.
-This configuration section allows you to place those boxes where you want in the
-application interface to customize it.
-
-The available boxes are :
-
-* actions box : box listing the applicable actions on the displayed data
-
-* boxes_blog_archives_box : box listing the blog archives
-
-* possible views box : box listing the possible views for the displayed data
-
-* rss box : RSS icon to get displayed data as a RSS thread
-
-* search box : search box
-
-* startup views box : box listing the configuration options available for
- the application site, such as `Preferences` and `Site Configuration`
-
-Components
-~~~~~~~~~~
-[WRITE ME]
-
-Contextual components
-~~~~~~~~~~~~~~~~~~~~~
-[WRITE ME]
-
--- a/doc/book/fr/chap_tests.txt Mon Nov 17 14:38:30 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Tests
-=====
-
-Écriture de tests unitaires
----------------------------
-Le framework de test fournit principalement deux classes de tests dans le module
-`ginco.devtools.apptest`:
-
-* `EnvBasedTC`, pour simuler un environnement complet (web + repository)
-* `RepositoryBasedTC`, pour simuler un environnement de repository uniquement
-
-Ces deux classes ont quasiment la même interface et proposent un certain nombre de méthodes
-rendant l'écriture de test puissante et rapide.
-
-XXXFILLME describe API
-
-Dans la plupart des cas, vous allez vouloir hériter de `EnvBasedTC` pour écrire des tests
-unitaires ou fonctionnels pour vos entités, vues, crochets...
-
-
-Test des courriels de notifications
-```````````````````````````````````
-Lors de l'éxécution de tests les courriels potentiellement générés ne sont pas réellement
-envoyé mais se retrouve dans la liste `MAILBOX` du module `ginco.devtools.apptest`. Cette
-liste est remise à zéro au *setUp* de chaque test (par le setUp des classes `EnvBasedTC`
-et `RepositoryBasedTC`).
-
-Vous pouvez donc tester vos notifications en analysant le contenu de cette liste, qui
-contient des objets ayant deux attributs :
-* `recipients`, la liste des destinataires
-* `msg`, l'objet email.Message
-
-
-Tests automatiques
-------------------
-XXXFILLME
--- a/doc/book/fr/chap_ui_gestion_formulaire.txt Mon Nov 17 14:38:30 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,133 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Gestion de formulaires
-======================
-
-Contrôle de la génération automatique de formulaire pour les entités manipulée
-------------------------------------------------------------------------------
-XXX FILLME
-
-* les formulaires 'edition' et 'creation'
-
-Le formulaire généré par défaut ne vous convient pas ? Vous êtes peut-être pas
-obligé de le refaire à la main ! :)
-
-* rtags primary, secondary, generated, generic,
- `Entity.relation_category(rtype, x='subject')`
-* inline_view (now a rtag?)
-* spécification widget
-
-
-Fonctionnement du contrôleur d'édition par défaut (id: 'edit')
---------------------------------------------------------------
-
-Contrôle de l'édition
-`````````````````````
-Prérequis: les paramètres liés aux entités à éditer sont spécifiés de la forme ::
-
- <nom de champ>:<eid de l'entité>
-
-où l'eid de l'entité pourra être une lettre dans le cas d'une entité à créer. On
-dénommera ces paramètres comme *qualifié*.
-
-1. récupération des entités à éditer en cherchant les paramètres de formulaire
- commençant par 'eid:' ayant également un paramètre '__type' associé
- (également *qualifié* par l'eid évidemment)
-
-2. pour tous les attributs et relations de chaque entité à éditer
-
- 1. recherche d'un paramètre 'edits-<nom relation>' ou 'edito-<nom relation>'
- qualifié dans le cas d'une relation dont l'entité est objet
- 2. si trouvé, la valeur récupérée est considérée comme la valeur originale
- pour cette relation, et on cherche la (ou les) nouvelle(s) valeur(s) dans
- le paramètre <nom relation> (qualifié)
- 3. si la valeur est différente de l'originale, une requête de modification en
- base est effectuée
-
-3. pour chaque entité à éditer
-
- 1. si un paramètre `__linkto` qualifié est spécifié, sa valeur doit être une
- chaine (ou une liste de chaine) de la forme : ::
-
- <relation type>:<eids>:<target>
-
- où <target> vaut 'subject' ou 'object' et chaque eid peut-être séparé d'un
- autre par un '_'. Target spécifie *l'entité éditée* est sujet ou objet de la
- relation et chaque relation ainsi spécifiée sera insérée.
-
- 2. si un paramètre `__cloned_eid` qualifié est spécifié pour une entité, les
- relations de l'entité spécifiée en valeur de cette argument sont copiées sur
- l'entité éditée
-
-
- 3. si un paramètre `__delete` qualifié est spécifié, sa valeur doit être une
- chaine (ou une liste de chaine) de la forme : ::
-
- <subject eids>:<relation type>:<object eids>
-
- où chaque eid sujet ou objet peut-être séparé d'un autre par un '_'. Chaque
- relation ainsi spécifiée sera supprimée.
-
- 4. si un paramètre `__insert` qualifié est spécifié, sa valeur doit être de
- même format que pour `__delete`, mais chaque relation ainsi spécifiée sera
- insérée.
-
-4. si les paramètres `__insert` et/ou `__delete` sont trouvés non qualifiés,
- ils sont interprétés comme décrit ci-dessus (quelque soit le nombre d'entité
- édité)
-
-5. si aucune entité n'est éditée mais que le formulaire contient les paramètres
- `__linkto` et `eid`, celui-ci est interprété en prenant la valeur spécifié
- par le paramètre `eid` pour désigner l'entité sur laquelle ajouter les
- relations
-
-
-A noter que :
-
-* si le paramètre `__action_delete` est trouvé, toutes les entités comme
- spécifiées à éditer seront supprimées
-
-* si le paramètre `__action_cancel` est trouvé, aucune action n'est effectuée
-
-* si le paramètre `__action_apply` est trouvé, l'édition est effectuée
- normalement mais la redirection sera effectuée sur le formulaire (cf `Contrôle
- de la redirection`_)
-
-* le paramètre `__method` est également supporté comme sur le template principal
- (XXX not very consistent, maybe __method should be dealed in the view controller)
-
-* si aucune entité à éditer n'est trouvée et qu'il n'y a pas de paramètre
- `__action_delete`, `__action_cancel`, `__linkto`, `__delete` ou `__insert`,
- une erreur est levée
-
-* placer dans le formulaire le paramètre `__message` permettra d'utiliser la
- valeur de ce paramètre comme message d'information à l'utilisateur une fois
- l'édition effectuée.
-
-
-Contrôle de la redirection
-``````````````````````````
-Une fois que l'édition s'est bien passé, reste un problème : c'est bien beau
-tout ça, mais où qu'on va maintenant ?? Si rien n'est spécifié, le controlleur
-se débrouille, mais comme il fait pas toujours ce qu'on voudrait, on peut
-controller ça en utilisant les paramètres suivant :
-
-* `__redirectpath`: chemin de l'url (relatif à la racine du site, sans paramètre
- de formulaire
-
-* `__redirectparams`: paramètres de formulaires à ajouter au chemin
-
-* `__redirectrql`: requête RQL de redirection
-
-* `__redirectvid`: identifiant de vue de redirection
-
-* `__errorurl`: url du formulaire original, utilisé pour la redirection en cas
- d'erreur de validation pendant l'édition. Si celui-ci n'est pas spécifié, une
- page d'erreur sera présentée plutot qu'un retour sur le formulaire (qui est le
- cas échéant responsable d'afficher les erreurs)
-
-* `__form_id`: identifiant de vue du formulaire original, utilisée si
- `__action_apply` est trouvé
-
-En général on utilise soit `__redirectpath et `__redirectparams` soit
-`__redirectrql` et `__redirectvid`.
--- a/doc/book/fr/chap_ui_js_json.txt Mon Nov 17 14:38:30 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-AJAX
-====
-JSON bla bla
-XXX FILLME
-
-
-Le contrôleur 'json'
---------------------
-XXX FILLME
-
-
-API Javascript
---------------
-XXX FILLME
--- a/doc/book/fr/chap_visualisation_donnees.txt Mon Nov 17 14:38:30 2008 -0800
+++ /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.entity(row, col)
- 09. self.w(u'<h1>%s</h1>' % entity.title)
- 10. self.w(u'<p>published on %s in category %s</p>' % \
- 11. (entity.publish_date.strftime('%Y-%m-%d'), entity.category))
- 12. self.w(u'<p>%s</p>' % entity.text)
-
-The above source code defines a new primary view (`line 03`) for
-``BlogEntry`` (`line 05`).
-
-Since views are applied to resultsets and resulsets can be tables of
-data, it is needed to recover the entity from its (row,col)
-coordinates (`line 08`). We will get to this in more detail later.
-
-The view has a ``self.w()`` method that is used to output data. Here `lines
-09-12` output HTML tags and values of the entity's attributes.
-
-When displaying same blog entry as before, you will notice that the
-page is now looking much nicer.
-
-.. image:: images/lax-book.09-new-view-blogentry.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.entity(row, col)
- 07. self.w(u'<h1>%s</h1>' % entity.title)
- 08. self.w(u'<p>%s</p>' % entity.description)
- 09. rset = self.req.execute('Any E WHERE E entry_of B, B eid "%s"' % entity.eid)
- 10. self.wview('primary', rset)
-
-In the above source code, `lines 01-08` are similar to the previous
-view we defined.
-
-At `line 09`, a simple request in made to build a resultset with all
-the entities linked to the current ``Blog`` entity by the relationship
-``entry_of``. The part of the framework handling the request knows
-about the schema and infer that such entities have to be of the
-``BlogEntry`` kind and retrieves them.
-
-The request returns a selection of data called a resultset. At
-`line 10` the view 'primary' is applied to this resultset to output
-HTML.
-
-**This is to be compared to interfaces and protocols in object-oriented
-languages. Applying a given view to all the entities of a resultset only
-requires the availability, for each entity of this resultset, of a
-view with that name that can accepts the entity.**
-
-Assuming we added entries to the blog titled `MyLife`, displaying it
-now allows to read its description and all its entries.
-
-.. image:: images/lax-book.10-blog-with-two-entries.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:: sect_stdlib_vues.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 `<div>` vides (par vide
-j'entend sans contenu dans la balise, il peut y avoir des attributs), faut
-toujours mettre `<div></div>` même s'il n'y a rien dedans, et non `<div/>`.
--- a/doc/book/fr/cubicweb-uml.fr.txt Mon Nov 17 14:38:30 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-
-Architecture du serveur
------------------------
-
-.. image:: images/server-class-diagram.png
-
-`Diagramme ArgoUML`_
-
-[FIXME]
-Make a downloadable source of zargo file.
-
-.. _`Diagramme ArgoUML`: cubicweb.zargo
--- a/doc/book/fr/faq.fr.txt Mon Nov 17 14:38:30 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Frequently Asked Questions
-==========================
-
-[FILL ME]
-
-* A quoi servent les crochets?
-
- Les crochets sont appeles lorsqu'une requete RQL est executee. Cela
- permet d'executer des actions specifiques lors d'un acces a la base
- de donnees, ce qui donne un controle de la base de donnees afin de
- prevenir l'insertion de `mauvaises` entites dans la base.
-
-* Quand utiliser un template HTML plutot qu'un composant graphique?
-
- Un template HTML ne peut contenir de logique, il ne permettra donc
- que de definir une vue statique. Un composant permet lui de gerer
- plus de logique et d'operations sur le contexte dans lequel il
- s'applique. Il faut donc bien reflechir avant de decider de l'un ou
- de l'autre, mais vous avez la possibilite de choisir.
-
-* Comment mettre à jour une base de données après avoir modifié le schéma?
-
- Cela dépend de ce qui a été modifié dans le schéma.
-
- * Modification d'une relation non finale
-
- * Modification d'une relation finale
-
-[TO COMPLETE]
-
-* Comment créer un utilisateur anonyme?
-
- Cela vous permet d'acceder a votre site sans avoir besoin de vous authentifier.
- Dans le fichier ``all-in-one.conf`` de votre instance, définir l'utilisateur
- anonyme en initilisant les valeurs des variables suivantes ::
-
- # login of the Erudi user account to use for anonymous user (if you want to
- # allow anonymous)
- anonymous-user=anon
-
- # password of the Erudi user account matching login
- anonymous-password=anon
-
- Vous devez aussi vous assurer que cet utilisateur `anon` existe dans la base
- de données, le plus simple étant de s'identifier sur votre application en
- administrateur et de rajouter l'utilisateur `anon` via l'interface d'administration.
-
-*
-
-
--- a/doc/book/fr/gae.fr.txt Mon Nov 17 14:38:30 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _contents:
-
-==========================
-Google AppEngine Datastore
-==========================
-
-
-.. include:: 01-intro.fr.txt
-.. include:: 02-install.fr.txt
-.. include:: 03-create-app.fr.txt
-.. include:: 04-develop-views.fr.txt
-.. include:: 05-components.fr.txt
-.. include:: 06-maintemplate.fr.txt
-.. include:: 07-rss-xml.fr.txt
-.. include:: 08-rql.fr.txt
-.. include:: 09-urlrewrite.fr.txt
-.. include:: 10-security.fr.txt
-.. include:: 11-faq.fr.txt
--- a/doc/book/fr/howto.fr.txt Mon Nov 17 14:38:30 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-HOW TO
-======
-
-* Comment mettre à jour une base de données après avoir modifié le schéma?
-
- Cela dépend de ce qui a été modifié dans le schéma.
-
- * Modification d'une relation non finale
-
- * Modification d'une relation finale
-
-[TO COMPLETE]
-
-* Comment créer un utilisateur anonyme?
-
- Cela vous permet d'acceder a votre site sans avoir besoin de vous authentifier.
- Dans le fichier ``all-in-one.conf`` de votre instance, définir l'utilisateur
- anonyme en initilisant les valeurs des variables suivantes ::
-
- # login of the Erudi user account to use for anonymous user (if you want to
- # allow anonymous)
- anonymous-user=anon
-
- # password of the Erudi user account matching login
- anonymous-password=anon
-
- Vous devez aussi vous assurer que cet utilisateur `anon` existe dans la base
- de données, le plus simple étant de s'identifier sur votre application en
- administrateur et de rajouter l'utilisateur `anon` via l'interface d'administration.
-
-*
-
--- a/doc/book/fr/index-content.fr.txt Mon Nov 17 14:38:30 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _contents:
-
-
-.. toctree::
- :maxdepth: 1
-
- introduction.fr.txt
- chap_fondements_cubicweb.txt
- chap_mise_en_place_environnement.txt
- chap_definition_schema.txt
- chap_visualisation_donnees.txt
- chap_definition_workflows.txt
- chap_manipulation_donnees.txt
- chap_site_configuration.txt
- chap_configuration_instance.txt
- chap_ui_gestion_formulaire.txt
- chap_ui_js_json.txt
- chap_autres_composants_ui.txt
- chap_securite.txt
- chap_serveur_crochets.txt
- chap_serveur_notification.txt
- chap_rql.txt
- chap_migration.txt
- chap_tests.txt
- chap_i18n.txt
- gae.fr.txt
- references.fr.txt
- faq.fr.txt
-
-
-
--- a/doc/book/fr/index-devmanual.fr.txt Mon Nov 17 14:38:30 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _contents:
-
-==========================================
-Développement d'applications avec CubicWeb
-==========================================
-
-
-:Author: Sylvain Thénault
-:Organization: Logilab
-
-.. toctree::
- :maxdepth: 1
-
- chap_fondements_cubicweb.txt
- chap_mise_en_place_environnement.txt
- chap_configuration_instance.txt
- chap_definition_schema.txt
- chap_definition_workflows.txt
- chap_visualisation_donnees.txt
- chap_manipulation_donnees.txt
- chap_ui_gestion_formulaire.txt
- chap_ui_js_json.txt
- chap_autres_composants_ui.txt
- chap_securite.txt
- chap_serveur_crochets.txt
- chap_serveur_notification.txt
-
- chap_rql.txt
- chap_migration.txt
- chap_tests.txt
- chap_i18n.txt
- gae.txt
-
-
-
-XXX: XXX FILLME, CSS, API sécurité
--- a/doc/book/fr/index.txt Mon Nov 17 14:38:30 2008 -0800
+++ b/doc/book/fr/index.txt Tue Nov 18 01:16:30 2008 +0100
@@ -34,7 +34,29 @@
.. toctree::
:maxdepth: 1
- index-content.fr.txt
+ 01-introduction.fr.txt
+ 02-foundation.fr.txt
+ 03-setup.fr.txt
+ 04-define-schema.fr.txt
+ 05-define-views.fr.txt
+ 06-define-workflows.fr.txt
+ 07-data-as-objects.fr.txt
+ 08-site-config.fr.txt
+ 09-instance-config.fr.txt
+ 10-form-management.fr.txt
+ 11-ajax-json.fr.txt
+ 12-ui-components.fr.txt
+ 13-security.fr.txt
+ 14-hooks.fr.txt
+ 15-notifications.fr.txt
+ 16-rql.fr.txt
+ 17-migration.fr.txt
+ 18-tests.fr.txt
+ 19-i18n.fr.txt
+ 20-gae.fr.txt
+ 21-references.fr.txt
+ 22-faq.fr.txt
+
Indices and tables
==================
--- a/doc/book/fr/introduction.fr.txt Mon Nov 17 14:38:30 2008 -0800
+++ /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'<h1>%s</h1>' % html_escape(entity.dc_title()))
-
- def content_format(self, entity):
- return entity.view('reledit', rtype='content_format')
-
- def cell_call(self, row, col):
- entity = self.entity(row, col)
-
- # display entity attributes with prefixes
- self.w(u'<h1>%s</h1>' % entity.title)
- self.w(u'<p>published on %s</p>' % entity.publish_date.strftime('%Y-%m-%d'))
- self.w(u'<p>%s</p>' % entity.content)
-
- # display relations
- siderelations = []
- if self.main_related_section:
- self.render_entity_relations(entity, siderelations)
-
-.. note::
- 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é.
-
-
--- a/doc/book/fr/lax-book.fr.txt Mon Nov 17 14:38:30 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-=====================================================
-Tout ce que vous avez toujours voulu savoir sur `LAX`
-=====================================================
-
-:authors: - Nicolas Chauvat
- - Sylvain Thénault
- - Adrien Di Mascio
-:date: 2008-06-14
-:version: 0.1
-:organisation: Logilab
-:copyright: © 2008 Logilab
-:contact: contact@logilab.fr
-
-.. sectnum::
-.. contents::
-
-.. include:: 01-intro.fr.txt
-.. include:: 02-install.fr.txt
-.. include:: 03-create-app.fr.txt
-.. include:: 04-develop-views.fr.txt
-.. include:: 05-components.fr.txt
-.. include:: 06-maintemplate.fr.txt
-.. include:: 07-rss-xml.fr.txt
-.. include:: 08-rql.fr.txt
-.. include:: 09-urlrewrite.fr.txt
-.. include:: 10-security.fr.txt
-.. include:: 11-faq.fr.txt
-
--- a/doc/book/fr/modules.fr.txt Mon Nov 17 14:38:30 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,253 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-
-:mod:`cubes.addressbook`
-========================
-
-.. automodule:: cubes.addressbook
- :members:
-
-:mod:`cubes.basket`
-========================
-
-.. automodule:: cubes.basket
- :members:
-
-:mod:`cubes.blog`
-========================
-
-.. automodule:: cubes.blog
- :members:
-
-:mod:`cubes.book`
-========================
-
-.. automodule:: cubes.book
- :members:
-
-:mod:`cubes.comment`
-========================
-
-.. automodule:: cubes.comment
- :members:
-
-:mod:`cubes.company`
-========================
-
-.. automodule:: cubes.company
- :members:
-
-
-:mod:`cubes.conference`
-========================
-
-.. automodule:: cubes.conference
- :members:
-
-:mod:`cubes.email`
-========================
-
-.. automodule:: cubes.email
- :members:
-
-:mod:`cubes.event`
-========================
-
-.. automodule:: cubes.event
- :members:
-
-:mod:`cubes.expense`
-========================
-
-.. automodule:: cubes.expense
- :members:
-
-
-:mod:`cubes.file`
-========================
-
-.. automodule:: cubes.file
- :members:
-
-:mod:`cubes.folder`
-========================
-
-.. automodule:: cubes.folder
- :members:
-
-:mod:`cubes.i18ncontent`
-========================
-
-.. automodule:: cubes.i18ncontent
- :members:
-
-:mod:`cubes.invoice`
-========================
-
-.. automodule:: cubes.invoice
- :members:
-
-:mod:`cubes.keyword`
-========================
-
-.. automodule:: cubes.keyword
- :members:
-
-:mod:`cubes.link`
-========================
-
-.. automodule:: cubes.link
- :members:
-
-:mod:`cubes.mailinglist`
-========================
-
-.. automodule:: cubes.mailinglist
- :members:
-
-:mod:`cubes.person`
-========================
-
-.. automodule:: cubes.person
- :members:
-
-:mod:`cubes.shopcart`
-========================
-
-.. automodule:: cubes.shopcart
- :members:
-
-:mod:`cubes.skillmat`
-========================
-
-.. automodule:: cubes.skillmat
- :members:
-
-:mod:`cubes.tag`
-========================
-
-.. automodule:: cubes.tag
- :members:
-
-:mod:`cubes.task`
-========================
-
-.. automodule:: cubes.task
- :members:
-
-:mod:`cubes.workcase`
-========================
-
-.. automodule:: cubes.workcase
- :members:
-
-:mod:`cubes.workorder`
-========================
-
-.. automodule:: cubes.workorder
- :members:
-
-:mod:`cubes.zone`
-========================
-
-.. automodule:: cubes.zone
- :members:
-
-:mod:`cubicweb`
-===============
-
-.. automodule:: cubicweb
- :members:
-
-:mod:`cubicweb.common`
-======================
-
-.. automodule:: cubicweb.common
- :members:
-
-:mod:`cubicweb.devtools`
-========================
-
-.. automodule:: cubicweb.devtools
- :members:
-
-:mod:`cubicweb.entities`
-========================
-
-.. automodule:: cubicweb.entities
- :members:
-
-:mod:`cubicweb.etwist`
-======================
-
-.. automodule:: cubicweb.etwist
- :members:
-
-:mod:`cubicweb.goa`
-===================
-
-.. automodule:: cubicweb.goa
- :members:
-
-:mod:`cubicweb.schemas`
-=======================
-
-.. automodule:: cubicweb.schemas
- :members:
-
-:mod:`cubicweb.server`
-======================
-
-.. automodule:: cubicweb.server
- :members:
-
-:mod:`cubicweb.sobjects`
-========================
-
-.. automodule:: cubicweb.sobjects
- :members:
-
-:mod:`cubicweb.web`
-===================
-
-.. automodule:: cubicweb.web
- :members:
-
-:mod:`cubicweb.web.views`
-=========================
-
-.. automodule:: cubicweb.web.views
- :members:
-
-
-:mod:`cubicweb.wsgi`
-====================
-
-.. automodule:: cubicweb.wsgi
- :members:
-
-:mod:`indexer`
-==============
-
-.. automodule:: indexer
- :members:
-
-:mod:`logilab`
-==============
-
-.. automodule:: logilab
- :members:
-
-
-
-:mod:`rql`
-==========
-
-.. automodule:: rql
- :members:
-
-:mod:`yams`
-===========
-
-.. automodule:: yams
- :members:
--- a/doc/book/fr/querier.fr.txt Mon Nov 17 14:38:30 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Déroulement de l'éxecution d'une requête en multi-source avec insertion de sécurité
-```````````````````````````````````````````````````````````````````````````````````
-
-* 3 sources (system, ldap (Euser) et rql (Card)
-* permission en lecture Card is elle appartient à l'utilisateur
-
-Soit la requête de départ: ::
-
- Any X,T WHERE X owned_by U, U login "syt", X title T
-
-1. récupération arbre de syntaxe et solution (+cache) ::
-
- -> {X: Card, U: Euser}, {X: Blog, U: Euser}, {X: Bookmark, U: Euser}
-
-2. insertion sécurité ::
-
- -> Any X,T WHERE X owned_by U, U login "syt", X title T, EXISTS(X owned_by UEID) / {X: Card, U: Euser}
- Any X,T WHERE X owned_by U, U login "syt", X title T / {X: Blog, U: Euser}, {X: Bookmark, U: Euser}
-
-3. construction plan
- 0. preprocessing (annotation des arbres de syntaxe)
-
- 1. Any U WHERE U login "syt" / {U: Euser}
- [system+ldap] => table1/varmap1{U:U2}
-
- 2. Any X,T WHERE X owned_by U2, X title T / {X: Blog, U: Euser}, {X: Bookmark, U: Euser}
- [varmap1|system] => TABLE2
-
- 3 Deux alernatives:
-
- 1. Any X,T WHERE X is Card, X title T {X: Card} ::
-
- [system+rql] => table3/varmap3{X:X3, T:T3}
-
- Any X3,T3 WHERE X3 owned_by U2, X3 title T3, EXISTS(X owned_by UEID) / {X3: Card, U2: Euser} ::
-
- [(varmap1, varmap3)|system] => TABLE2
-
- 2 Any X WHERE X is Card X owned_by U2, EXISTS(X owned_by UEID) / {X: Card, U2: Euser} ::
-
- [varmap1|system] => EIDS
-
- Any X,T WHERE X title T, X eid IN(EIDS) {X: Card} ::
-
- [system+rql] => TABLE2
-
- 4. renvoie contenu TABLE2.
- Note : si aggrégat / tri / distinct TABLE2 est nécessairement une table temporaire et besoin d'une
- étape AggrStep supplémentaire
-
-4. éxécution du plan
-
-5. [construction description]
-
-6. renvoie ResultSet
-
-Notes sur UNION
-```````````````
-
-* en multi-sources, les résultats des unions peuvent être mélangés
--- a/doc/book/fr/references.fr.txt Mon Nov 17 14:38:30 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _contents:
-
-Références
-==========
-
-Détails d'implémentations
--------------------------
-.. toctree::
- :maxdepth: 1
-
- ../cubicweb-uml.txt
-
-Détail sur l'éxécution d'une requête complexe en multi-sources
---------------------------------------------------------------
-
-.. toctree::
- :maxdepth: 1
-
- ../querier.txt
-
--- a/doc/book/fr/sect_creation_instance.txt Mon Nov 17 14:38:30 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,127 +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
- hg init moncube
- cd moncube
- 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).
-
-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
-
--- a/doc/book/fr/sect_cubicweb-ctl.txt Mon Nov 17 14:38:30 2008 -0800
+++ /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 <commande> [options commande] <arguments commandes>
-
-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 <commande> --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
--------------------------------------------------
-* ``i18nlibupdate``, regénère les catalogues de messages de la librairie CubicWeb
-* ``i18nupdate``, regénère les catalogues de messages d'un composant
-* ``i18ncompile``, 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 <nom_cube> <nom_instance>
-
-Cette commande va creer les fichiers de configuration d'une instance dans
-``~/etc/cubicweb.d/<nom_instance>``.
-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 <nom_cube>
-
-Cette commande va creer un nouveau cube dans ``/path/to/forest/cubicweb/cubes/<nom_cube>``.
-
-
--- a/doc/book/fr/sect_definition_entites.txt Mon Nov 17 14:38:30 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,168 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-Paramétrages et extensions spécifiques
---------------------------------------
-
-Valeurs par défaut dynamiques
-`````````````````````````````
-Il est possible de définir dans le schéma des valeurs par défaut *statiques*.
-Il est également possible de définir des valeurs par défaut *dynamiques* en
-définissant sur la classe d'entité une méthode `default_<nom attribut>` pour
-un attribut donnée.
-
-
-Contrôle des attributs chargés et du tri par défaut
-```````````````````````````````````````````````````
-* l'attribut de classe `fetch_attrs` permet de définir sur une classe d'entité
- la liste des noms des attributs ou relations devant être chargés
- automatiquement lors de la récupération d'entité(s) de ce type. Dans le cas
- des relations, on est limité aux relations *sujets de cardinalité `?` ou `1`*.
-
-* la méthode de classe `fetch_order(attr, var)` prend en argument un nom
- d'attribut (ou de relation) et un nom de variable et doit retourner une chaine
- à utiliser dans la close "ORDERBY" d'une requête RQL pour trier
- automatiquement les listes d'entités de ce type selon cet attribut, ou `None`
- si l'on ne veut pas de tri sur l'attribut passé en argument. Par défaut les
- entités sont triées selon leur date de création
-
-* la méthode de classe `fetch_unrelated_order(attr, var)` est similaire à la
- méthode `fetch_order` mais est utilisée essentiellement pour contrôler le tri
- des listes déroulantes permettant de créer des relations dans la vue d'édition
- d'une entité
-
-La fonction `fetch_config(fetchattrs, mainattr=None)` permet de simplifier la
-définition des attributs à précharger et du tri en retournant une liste des
-attributs à précharger (en considérant ceux de la classe `AnyEntity`
-automatiquement) et une fonction de tri sur l'attribut "principal" (le 2eme
-argument si spécifié ou sinon le premier attribut de la liste `fetchattrs`).
-Cette fonction est définie dans le package `ginco.entities`.
-
-Par exemple : ::
-
- class Transition(AnyEntity):
- """..."""
- id = 'Transition'
- fetch_attrs, fetch_order = fetch_config(['name'])
-
-Indique que pour le type d'entité "Transition" il faut précharger l'attribut
-"name" et trier par défaut selon cet attribut.
-
-
-Contrôle des formulaires d'édition
-``````````````````````````````````
-Il est possible de contrôler les attributs/relations dans la vue d'édition
-simple ou multiple à l'aide des *rtags* suivants :
-
-* `primary`, indique qu'un attribut ou une relation doit être incorporé dans
- les formulaires d'édition simple et multiple. Dans le cas d'une relation,
- le formulaire d'édition de l'entité liée sera inclus dans le formulaire
-
-* `secondary`, indique qu'un attribut ou une relation doit être incorporé dans
- le formulaire d'édition simple uniquement. Dans le cas d'une relation,
- le formulaire d'édition de l'entité liée sera inclus dans le formulaire
-
-* `generic`, indique qu'une relation doit être incorporé dans le formulaire
- d'édition simple dans la boite générique d'ajout de relation
-
-* `generated`, indique qu'un attribut est caculé dynamiquement ou autre, et
- qu'il ne doit donc pas être présent dans les formulaires d'édition
-
-Au besoin il est possible de surcharger la méthode
-`relation_category(rtype, x='subject')` pour calculer dynamiquement la catégorie
-d'édition d'une relation.
-
-
-Contrôle de la boîte "add_related"
-``````````````````````````````````
-La boite `add related` est une boite automatique proposant de créer une entité
-qui sera automatiquement liée à l'entité de départ (le contexte dans lequel
-s'affiche la boite). Par défaut, les liens présents dans cette boite sont
-calculés en fonction des propriétés du schéma de l'entité visualisée, mais il
-est possible de les spécifier explicitement à l'aide des *rtags* suivants :
-
-* `link`, indique qu'une relation est généralement créée vers une entité
- existante et qu'il ne faut donc pas faire apparaitre de lien pour cette
- relation
-
-* `create`, indique qu'une relation est généralement créée vers de nouvelles
- entités et qu'il faut donc faire apparaitre un lien pour créer une nouvelle
- entité et la lier automatiquement
-
-Au besoin il est possible de surcharger la méthode
-`relation_mode(rtype, targettype, x='subject')` pour caculer dynamiquement la
-catégorie de création d'une relation.
-
-A noter également que si au moins une action dans la catégorie "addrelated" est
-trouvée pour le contexte courant, le fonctionnement automatique est désactivé
-en faveur du fonctionnement explicite (i.e. affichage des actions de la
-catégorie "addrelated" uniquement).
-
-Contrôle des formulaires de filtrage de table
-`````````````````````````````````````````````
-La vue "table" par défaut gère dynamiquement un formulaire de filtrage du
-contenu de celle-ci. L'algorithme est le suivant :
-
-1. on considère que la première colonne contient les entités à restreindre
-2. on recupère la première entité de la table (ligne 0) pour "représenter"
- toutes les autres
-3. pour toutes les autres variables définies dans la requête originale :
-
- 1. si la variable est liée à la variable principale par au moins une
- n'importe quelle relation
- 2. on appelle la méthode `filterform_vocabulary(rtype, x)` sur l'entité
- et si rien est retourné (ou plus exactement un tuple de valeur `None`,
- voir ci-dessous) on passe à la variable suivante, sinon un élément de
- formulaire de filtrage sera créé avec les valeurs de vocabulaire
- retournées
-
-4. il n'y a pas d'autres limitations sur le rql, il peut comporter des clauses
- de tris, de groupes... Des fonctions javascripts sont utilisées pour
- regénérer une requête à partir de la requête de départ et des valeurs
- séléctionnées dans les filtres de formulaire.
-
-
-La méthode `filterform_vocabulary(rtype, x, var, rqlst, args, cachekey)` prend
-en argument le nom d'une relation et la "cible", qui indique si l'entité sur
-laquelle la méthode est appellée est sujet ou objet de la relation. Elle doit
-retourner :
-
-* un 2-uple de None si elle ne sait pas gérer cette relation
-
-* un type et une liste contenant le vocabulaire
-
- * la liste doit contenir des couples (valeur, label)
- * le type indique si la valeur désigne un nombre entier (`type == 'int'`), une
- chaîne de caractères (`type == 'string'`) ou une entité non finale (`type
- == 'eid'`)
-
-Par exemple dans notre application de gestion de tickets, on veut pouvoir
-filtrés ceux-ci par :
-
-* type
-* priorité
-* état (in_state)
-* étiquette (tags)
-* version (done_in)
-
-On définit donc la méthode suivante : ::
-
-
- class Ticket(AnyEntity):
-
- ...
-
- def filterform_vocabulary(self, rtype, x, var, rqlst, args, cachekey):
- _ = self.req._
- if rtype == 'type':
- return 'string', [(x, _(x)) for x in ('bug', 'story')]
- if rtype == 'priority':
- return 'string', [(x, _(x)) for x in ('minor', 'normal', 'important')]
- if rtype == 'done_in':
- rql = insert_attr_select_relation(rqlst, var, rtype, 'num')
- return 'eid', self.req.execute(rql, args, cachekey)
- return super(Ticket, self).filterform_vocabulary(rtype, x, var, rqlst,
- args, cachekey)
-
-
-NOTE: Le support du filtrage sur les étiquettes et l'état est installé
-automatiquement, pas besoin de le gérer ici.
--- a/doc/book/fr/sect_definition_schema.txt Mon Nov 17 14:38:30 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,348 +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` (`EUser`) (quel utilisateur a créé l'entité)
-
- - `owned_by` (`EUser`) (à qui appartient l'entité, par défaut le
- créateur mais pas forcément et il peut exister plusieurs propriétaires)
-
- - `is` (`EEType`)
-
-
-* 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 = 'EUser'
-
-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')
-
-* `symetric` : 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_<ACTION>_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 <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é `EPermission` 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 EPermission(MetaEntityType):
- """entity type that may be used to construct some advanced security configuration
- """
- name = String(required=True, indexed=True, internationalizable=True, maxsize=100)
- require_group = SubjectRelation('EGroup', cardinality='+*',
- description=_('groups to which the permission is granted'))
- require_state = SubjectRelation('State',
- description=_("entity'state in which the permission is applyable"))
- # can be used on any entity
- require_permission = ObjectRelation('**', cardinality='*1', composite='subject',
- description=_("link a permission to the entity. This "
- "permission should be used in the security "
- "definition of the entity's type to be useful."))
-
-
-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é `EPermission` 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é `EPermission`, 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_<ACTION>_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.
--- a/doc/book/fr/sect_installation.txt Mon Nov 17 14:38:30 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,151 +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
-
-
--- a/doc/book/fr/sect_mercurial.txt Mon Nov 17 14:38:30 2008 -0800
+++ /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/
--- a/doc/book/fr/sect_stdlib_schemas.txt Mon Nov 17 14:38:30 2008 -0800
+++ /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"
-``````````````````
-
-* `EUser`, utilisateurs du système
-* `EGroup`, groupes d'utilisateurs
-* `EEType`, types d'entité
-* `ERType`, 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
-
-* `EProperty`, utilisé pour configurer l'application
-* `EPermission`, 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.
--- a/doc/book/fr/sect_stdlib_vues.txt Mon Nov 17 14:38:30 2008 -0800
+++ /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 (<ul>) 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 (<table>) 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
--- a/doc/book/fr/tut-create-app.fr.txt Mon Nov 17 14:38:30 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,394 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-
-Tutoriel : créer votre première application web pour Postgres
-=============================================================
-
-
-[TRANSLATE ME TO FRENCH]
-
-Ce tutoriel va vous guider pas à pas a construire une apllication web
-de gestion de Blog afin de vous faire découvrir les fonctionnalités de
-`CubicWeb`.
-
-Nous supposons que vous avec déjà suivi le guide :ref:`MiseEnPlaceEnv`
-
-
-This tutorial will guide you step by step to build a blog application
-and discover the unique features of `LAX`. It assumes that you followed
-the :ref:`installation` guidelines and that both the `AppEngine SDK` and the
-`LAX` framework are setup on your computer.
-
-Creating a new application
---------------------------
-
-We choosed in this tutorial to develop a blog as an example of web application
-and will go through each required steps/actions to have it running with `LAX`.
-When you installed `LAX`, you saw a directory named ``skel``. Make a copy of
-this directory and call it ``BlogDemo``.
-
-The location of this directory does not matter. But once decided, make sure your ``PYTHONPATH`` is properly set (:ref:`installation`).
-
-
-Defining a schema
------------------
-
-With `LAX`, the schema/datamodel is the core of the application. This is where
-you will define the type of content you have to hanlde in your application.
-
-Let us start with something simple and improve on it iteratively.
-
-In schema.py, we define two entities : ``Blog`` and ``BlogEntry``.
-
-::
-
- class Blog(EntityType):
- title = String(maxsize=50, required=True)
- description = String()
-
- class BlogEntry(EntityType):
- title = String(maxsize=100, required=True)
- publish_date = Date(default='TODAY')
- text = String(fulltextindexed=True)
- category = String(vocabulary=('important','business'))
- entry_of = SubjectRelation('Blog', cardinality='?*')
-
-A Blog has a title and a description. The title is a string that is
-required by the class EntityType and must be less than 50 characters.
-The description is a string that is not constrained.
-
-A BlogEntry has a title, a publish_date and a text. The title is a
-string that is required and must be less than 100 characters. The
-publish_date is a Date with a default value of TODAY, meaning that
-when a BlogEntry is created, its publish_date will be the current day
-unless it is modified. The text is a string that will be indexed in
-the full-text index and has no constraint.
-
-A BlogEntry also has a relationship ``entry_of`` that link it to a
-Blog. The cardinality ``?*`` means that a BlogEntry can be part of
-zero or one Blog (``?`` means `zero or one`) and that a Blog can
-have any number of BlogEntry (``*`` means `any number including
-zero`). For completeness, remember that ``+`` means `one or more`.
-
-Running the application
------------------------
-
-Defining this simple schema is enough to get us started. Make sure you
-followed the setup steps described in detail in the installation
-chapter (especially visiting http://localhost:8080/_load as an
-administrator), then launch the application with the command::
-
- python dev_appserver.py BlogDemo
-
-and point your browser at http://localhost:8080/ (if it is easier for
-you, use the on-line demo at http://lax.appspot.com/).
-
-.. image:: images/lax-book.00-login.fr.png
- :alt: login screen
-
-After you log in, you will see the home page of your application. It
-lists the entity types: Blog and BlogEntry. If these links read
-``blog_plural`` and ``blogentry_plural`` it is because
-internationalization (i18n) is not working for you yet. Please ignore
-this for now.
-
-.. image:: images/lax-book.01-start.fr.png
- :alt: home page
-
-Creating system entities
-------------------------
-You can only create new users if you decided not to use google authentication.
-
-
-[WRITE ME : create users manages permissions etc]
-
-
-
-Creating application entites
-----------------------------
-
-Create a Blog
-~~~~~~~~~~~~~
-
-Let us create a few of these entities. Click on the [+] at the right
-of the link Blog. Call this new Blog ``Tech-blog`` and type in
-``everything about technology`` as the description, then validate the
-form by clicking on ``Validate``.
-
-.. image:: images/lax-book.02-create-blog.fr.png
- :alt: from to create blog
-
-Click on the logo at top left to get back to the home page, then
-follow the Blog link that will list for you all the existing Blog.
-You should be seeing a list with a single item ``Tech-blog`` you
-just created.
-
-.. image:: images/lax-book.03-list-one-blog.fr.png
- :alt: displaying a list of a single blog
-
-Clicking on this item will get you to its detailed description except
-that in this case, there is not much to display besides the name and
-the phrase ``everything about technology``.
-
-.. image:: images/lax-book.04-detail-one-blog.fr.png
- :alt: displaying the detailed view of a blog
-
-Now get back to the home page by clicking on the top-left logo, then
-create a new Blog called ``MyLife`` and get back to the home page
-again to follow the Blog link for the second time. The list now
-has two items.
-
-.. image:: images/lax-book.05-list-two-blog.fr.png
- :alt: displaying a list of two blogs
-
-
-Create a BlogEntry
-~~~~~~~~~~~~~~~~~~
-
-Get back to the home page and click on [+] at the right of the link
-BlogEntry. Call this new entry ``Hello World`` and type in some text
-before clicking on ``Validate``. You added a new blog entry without
-saying to what blog it belongs. There is a box on the left entitled
-``actions``, click on the menu item ``modify``. You are back to the form
-to edit the blog entry you just created, except that the form now has
-another section with a combobox titled ``add relation``. Chose
-``entry_of`` in this menu and a second combobox appears where you pick
-``MyLife``.
-
-You could also have, at the time you started to fill the form for a
-new entity BlogEntry, hit ``Apply`` instead of ``Validate`` and the
-combobox titled ``add relation`` would have showed up.
-
-.. image:: images/lax-book.06-add-relation-entryof.fr.png
- :alt: editing a blog entry to add a relation to a blog
-
-Validate the changes by clicking ``Validate``. The entity BlogEntry
-that is displayed now includes a link to the entity Blog named
-``MyLife``.
-
-.. image:: images/lax-book.07-detail-one-blogentry.fr.png
- :alt: displaying the detailed view of a blogentry
-
-Remember that all of this was handled by the framework and that the
-only input that was provided so far is the schema. To get a graphical
-view of the schema, run the ``laxctl genschema BlogDemo`` command as
-explained in the installation section and point your browser to the
-URL http://localhost:8080/schema
-
-.. image:: images/lax-book.08-schema.fr.png
- :alt: graphical view of the schema (aka data-model)
-
-Site configuration
-------------------
-
-.. image:: images/lax-book.03-site-config-panel.fr.png
-
-This panel allows you to configure the appearance of your application site.
-Six menus are available and we will go through each of them to explain how
-to use them.
-
-Navigation
-~~~~~~~~~~
-This menu provides you a way to adjust some navigation options depending on
-your needs, such as the number of entities to display by page of results.
-Follows the detailled list of available options :
-
-* navigation.combobox-limit : maximum number of entities to display in related
- combo box (sample format: 23)
-* navigation.page-size : maximum number of objects displayed by page of results
- (sample format: 23)
-* navigation.related-limit : maximum number of related entities to display in
- the primary view (sample format: 23)
-* navigation.short-line-size : maximum number of characters in short description
- (sample format: 23)
-
-UI
-~~
-This menu provides you a way to customize the user interface settings such as
-date format or encoding in the produced html.
-Follows the detailled list of available options :
-
-* ui.date-format : how to format date in the ui ("man strftime" for format description)
-* ui.datetime-format : how to format date and time in the ui ("man strftime" for format
- description)
-* ui.default-text-format : default text format for rich text fields.
-* ui.encoding : user interface encoding
-* ui.fckeditor :should html fields being edited using fckeditor (a HTML WYSIWYG editor).
- You should also select text/html as default text format to actually get fckeditor.
-* ui.float-format : how to format float numbers in the ui
-* ui.language : language of the user interface
-* ui.main-template : id of main template used to render pages
-* ui.site-title : site title, which is displayed right next to the logo in the header
-* ui.time-format : how to format time in the ui ("man strftime" for format description)
-
-
-Actions
-~~~~~~~
-This menu provides a way to configure the context in which you expect the actions
-to be displayed to the user and if you want the action to be visible or not.
-You must have notice that when you view a list of entities, an action box is
-available on the left column which display some actions as well as a drop-down
-menu for more actions.
-
-The context available are :
-
-* mainactions : actions listed in the left box
-* moreactions : actions listed in the `more` menu of the left box
-* addrelated : add actions listed in the left box
-* useractions : actions listed in the first section of drop-down menu
- accessible from the right corner user login link
-* siteactions : actions listed in the second section of drop-down menu
- accessible from the right corner user login link
-* hidden : select this to hide the specific action
-
-Boxes
-~~~~~
-The application has already a pre-defined set of boxes you can use right away.
-This configuration section allows you to place those boxes where you want in the
-application interface to customize it.
-
-The available boxes are :
-
-* actions box : box listing the applicable actions on the displayed data
-
-* boxes_blog_archives_box : box listing the blog archives
-
-* possible views box : box listing the possible views for the displayed data
-
-* rss box : RSS icon to get displayed data as a RSS thread
-
-* search box : search box
-
-* startup views box : box listing the configuration options available for
- the application site, such as `Preferences` and `Site Configuration`
-
-Components
-~~~~~~~~~~
-[WRITE ME]
-
-Contextual components
-~~~~~~~~~~~~~~~~~~~~~
-[WRITE ME]
-
-Set-up a workflow
------------------
-
-Before starting, make sure you refresh your mind by reading [link to
-definition_workflow chapter].
-
-We want to create a workflow to control the quality of the BlogEntry
-submitted on your application. When a BlogEntry is created by a user
-its state should be `submitted`. To be visible to all, it needs to
-be in the state `published`. To move from `submitted` to `published`
-we need a transition that we can name `approve_blogentry`.
-
-We do not want every user to be allowed to change the state of a
-BlogEntry. We need to define a group of user, `moderators`, and
-this group will have appropriate permissions to approve BlogEntry
-to be published and visible to all.
-
-There are two ways to create a workflow, form the user interface,
-and also by defining it in ``migration/postcreate.py``. This script
-is executed each time a new ``./bin/laxctl db-init`` is done.
-If you create the states and transitions through the user interface
-this means that next time you will need to initialize the database
-you will have to re-create all the entities.
-We strongly recommand you create the workflow in ``migration\postcreate.py``
-and we will now show you how.
-The user interface would only be a reference for you to view the states
-and transitions but is not the appropriate interface to define your
-application workflow.
-
-Update the schema
-~~~~~~~~~~~~~~~~~
-To enable a BlogEntry to have a State, we have to define a relation
-``in_state`` in the schema of BlogEntry. Please do as follows, add
-the line ``in_state (...)``::
-
- class BlogEntry(EntityType):
- title = String(maxsize=100, required=True)
- publish_date = Date(default='TODAY')
- text_format = String(meta=True, internationalizable=True, maxsize=50,
- default='text/rest', constraints=[format_constraint])
- text = String(fulltextindexed=True)
- category = String(vocabulary=('important','business'))
- entry_of = SubjectRelation('Blog', cardinality='?*')
- in_state = SubjectRelation('State', cardinality='1*')
-
-As you updated the schema, you will have re-execute ``./bin/laxctl db-init``
-to initialize the database and migrate your existing entities.
-[WRITE ABOUT MIGRATION]
-
-Create states, transitions and group permissions
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-At the time the ``postcreate.py`` script is executed, several methods
-can be used. They are all defined in the ``class ServerMigrationHelper``.
-We will only discuss the method we use to create a wrokflow here.
-
-To define our workflow for BlogDemo, please add the following lines
-to ``migration/postcreate.py``::
-
- _ = unicode
-
- moderators = add_entity('EGroup', name=u"moderators")
-
- submitted = add_state(_('submitted'), 'BlogEntry', initial=True)
- published = add_state(_('published'), 'BlogEntry')
-
- add_transition(_('approve_blogentry'), 'BlogEntry', (submitted,), published, ('moderators', 'managers'),)
-
- checkpoint()
-
-``add_entity`` is used here to define the new group of users that we
-need to define the transitions, `moderators`.
-If this group required by the transition is not defined before the
-transition is created, it will not create the relation `transition
-require the group moderator`.
-
-``add_state`` expects as the first argument the name of the state you are
-willing to create, then the entity type on which the state can be applied,
-and an optionnal argument to set if the state is the initial state
-of the entity type or not.
-
-``add_transition`` expects as the first argument the name of the
-transition, then the entity type on which we can apply the transition,
-then the list of possible initial states from which the transition
-can be applied, the target state of the transition, and the permissions
-(e.g. list of the groups of users who can apply the transition).
-
-.. image:: images/lax-book.03-transitions-view.fr.png
-
-You can now notice that in the actions box of a BlogEntry, the state
-is now listed as well as the possible transitions from this state
-defined by the workflow. This transition, as defined in the workflow,
-will only being displayed for the users belonging to the group
-moderators of managers.
-
-Change view permission
-~~~~~~~~~~~~~~~~~~~~~~
-
-
-
-Conclusion
-----------
-
-Exercise
-~~~~~~~~
-
-Create new blog entries in ``Tech-blog``.
-
-What we learned
-~~~~~~~~~~~~~~~
-
-Creating a simple schema was enough to set up a new application that
-can store blogs and blog entries.
-
-What is next ?
-~~~~~~~~~~~~~~
-
-Although the application is fully functionnal, its look is very
-basic. In the following section we will learn to create views to
-customize how data is displayed.
-
-
--- a/doc/book/fr/tut-create-gae-app.fr.txt Mon Nov 17 14:38:30 2008 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,218 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _tutorielGAE:
-
-Tutoriel : créer votre première application web pour Google AppEngine
-=====================================================================
-
-Ce tutoriel va vous guider pas à pas a construire une apllication web
-de gestion de Blog afin de vous faire découvrir les fonctionnalités de
-`CubicWeb`.
-
-Nous supposons que vous avec déjà suivi le guide :ref:`installationGAE`.
-
-
-Créez une nouvelle application
-------------------------------
-
-Nous choisissons dans ce tutoriel de développer un blog comme un exemple
-d'application web et nous allons expliciter toutes les étapes nécessaires
-à sa réalisation.
-
-::
-
- cubicweb-ctl newgapp blogdemo
-
-`newgapp` est la commande permettant de créer une instance `CubicWeb` pour
-le datastore.
-
-Assurez-vous que votre variable d'environnement ``PYTHONPATH`` est correctement
-initialisée (:ref:`installationGAE`)
-
-Définissez un schéma
---------------------
-
-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.
-
-Commençons par un schéma simple que nous améliorerons progressivemment.
-
-Une fois votre instance ``blogdemo`` crée, vous trouverez un fichier ``schema.py``
-contenant la définition des entités suivantes : ``Blog`` and ``BlogEntry``.
-
-::
-
- class Blog(EntityType):
- title = String(maxsize=50, required=True)
- description = String()
-
- class BlogEntry(EntityType):
- title = String(maxsize=100, required=True)
- publish_date = Date(default='TODAY')
- text = String(fulltextindexed=True)
- category = String(vocabulary=('important','business'))
- 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 and 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`.
-
-Lancez l'application
---------------------
-
-Définir ce simple schéma est suffisant pour commencer. Assurez-vous
-que vous avez suivi les étapes décrites dans la section installation
-(en particulier visitez http://localhost:8080/_load en tant qu'administrateur
-afin d'initialiser le datastore), puis lancez votre application avec la commande ::
-
- python dev_appserver.py BlogDemo
-
-puis dirigez vous vers http://localhost:8080/ (ou si c'est plus facile
-vous pouvez utiliser la démo en ligne http://lax.appspot.com/).
-[FIXME] -- changer la demo en ligne en quelque chose qui marche (!)
-
-.. image:: images/lax-book.00-login.fr.png
- :alt: login screen
-
-Après vous être authentifié, vous arrivez sur la page d'accueil de votre
-application. Cette page liste les types d'entités accessibles dans votre
-application, en l'occurrence : Blog et Articles. Si vous lisez ``blog_plural``
-et ``blogentry_plural`` cela signifie que l'internationalisation (i18n)
-n'a pas encore fonctionné. Ignorez cela pour le moment.
-
-.. image:: images/lax-book.01-start.fr.png
- :alt: home page
-
-Créez des entités système
--------------------------
-
-Vous ne pourrez créer de nouveaux utilisateurs que dans le cas où vous
-avez choisi de ne pas utiliser l'authentification Google.
-
-
-[WRITE ME : create users manages permissions etc]
-
-
-
-Créez des entités applicatives
-------------------------------
-
-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/lax-book.02-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/lax-book.03-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``
-
-
-.. image:: images/lax-book.04-detail-one-blog.fr.png
- :alt: displaying the detailed view of a blog
-
-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/lax-book.05-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/lax-book.06-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/lax-book.07-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, exécutez
-la commande ``laxctl genschema blogdemo`` et vous pourrez visualiser
-votre schéma a l'URL suivante : http://localhost:8080/schema
-
-.. image:: images/lax-book.08-schema.fr.png
- :alt: graphical view of the schema (aka data-model)
-
-
-Change view permission
-~~~~~~~~~~~~~~~~~~~~~~
-
-
-
-Conclusion
-----------
-
-Exercise
-~~~~~~~~
-
-Create new blog entries in ``Tech-blog``.
-
-What we learned
-~~~~~~~~~~~~~~~
-
-Creating a simple schema was enough to set up a new application that
-can store blogs and blog entries.
-
-What is next ?
-~~~~~~~~~~~~~~
-
-Although the application is fully functionnal, its look is very
-basic. In the following section we will learn to create views to
-customize how data is displayed.
-
-