<divclass="focus"align="center">This section contains some deprecated information. Documentation is currently being rewritten and will soon be available.</div>
<p>A gen-application is a simple Python module (a single Python file) or package (a hierarchy of folders where every (sub-)folder contains a file named __init__.py). In the <ahref="gen.html">main gen presentation page</a>, we've created a simple application in the form of a Python module, we've run it by installing Zope and Plone and by generating a Plone product. Working with a Python package instead of a Python module is quite easy: instead of creating MyModule.py in <aclass="code">[myZopeInstance]/lib/python</a> you simply create a folder "MyPackage" at the same place.</p>
<p>Within your Python module or package, you create standard Python classes. Those classes do not need to inherit from any base class provided by gen. If you want to turn a given class into a "gen-class" (= a class whose instances will be visualized, created and edited throug-the-web with Plone), you need to provide static attributes that will represent the associated data you need to edit and/or view through-the-web. Those attributes must be instances of any sub-class of <spanclass="code">appy.gen.Type</span>. We will see that some attribute and method names are "reserved" for specific uses; all other methods and attributes you will define on "gen-classes" will be kept untouched by gen. "gen-classes" do not need any constructor at all, because instances will be created throug-the-web or via some gen-specific mechanisms that we will explain later.</p>
<p>What gen tries to do is to be as invisible as possible, by leaving your Python classes as "pure" as possible.</p>
<h1><aname="classesAndAttributes"></a>Gen-classes and attributes</h1>
<p>The code below shows an example of a gen-class.</p>
<p><br/><spanclass="code">String</span>, <spanclass="code">Integer</span>, <spanclass="code">Float</span> and <spanclass="code">Date</span> all inherit from <spanclass="code">appy.gen.Type</span>. You may still define standard Python attributes like <spanclass="code">at5</span> and methods like <spanclass="code">sayHello</span>. The list of basic types provided by gen is shown below.</p>
<p>When defining instances of those types, you will typically give some parameters to it. Below is the list of parameters that are common to all types. In the next sections, we will see into more detail every type with its specificities.</p>
<td>A validator is something that restricts the valid range of values that the field may hold. It can be:
<ul>
<li>A Python (instance) method belonging to the class defining the field (or one of its parents). Every time an object is created or updated, this method will be called, with a single argument containing the new value the user has entered for the field. If this method returns a string (more precisely, an instance of <spanclass="code">basestring</span>), validation will fail and this string will be shown to the user as error message. Else, validation will succeed if the return value is True (or equivalent value) and will fail else. In this latter case, the error message that the user will get will correspond to i18n label <spanclass="code">[full_class_name]_[field_name]_valid</span> in the application-specific i18n domain, where <spanclass="code">[full_class_name]</span> is the class name including the package prefix where dots have been replaced with underscores. More information about i18n may be found <ahref="genCreatingAdvancedClasses.html#i18n">here</a>. Examples are presented hereafter.</li>
<li>A list of string values. It only applies for <spanclass="code">String</span> fields. This list contains the possible values the field may hold.</li>
<li>A regular expression (under the form of a compiled regular expression generated with <spanclass="code">re.compile</span>).</li>
</ul>
</td>
</tr>
<tr>
<tdclass="code">multiplicity</td>
<tdclass="code">(0,1)</td>
<td>Multiplicity is a 2-tuple that represents the minimum and maximum number of values the field may hold. <spanclass="code">(0,1)</span> means that the field may be empty or contain one value. <spanclass="code">(1,1)</span> means that a value is required. For all types excepted <spanclass="code">Ref</span> and some <spanclass="code">String</span>s, the maximum value must be 1. The Python value <spanclass="code">None</span> is used for representing an unbounded value: <spanclass="code">(1,None)</span> means "at least 1" (no upper bound).</td>
</tr>
<tr>
<tdclass="code">default</td>
<tdclass="code">None</td>
<td>The default value for the field. The default value must be a Python value that corresponds to the Appy type. Correspondence with Python and Appy types is given here:
<tableclass="appyTable"align="center">
<tr>
<th>Appy type</th>
<th>Python type</th>
</tr>
<tr>
<tdclass="code">Integer</td>
<tdclass="code">int, long</td>
</tr>
<tr>
<tdclass="code">Float</td>
<tdclass="code">float</td>
</tr>
<tr>
<tdclass="code">String</td>
<tdclass="code">str, unicode</td>
</tr>
<tr>
<tdclass="code">Boolean</td>
<tdclass="code">bool</td>
</tr>
<tr>
<tdclass="code">Date</td>
<td>The Date type shipped with Zope (class <spanclass="code">DateTime.DateTime</span>). The corresponding type from standard <spanclass="code">datetime</span> package is less sexy.</td>
</tr>
</table>
</td>
</tr>
<tr>
<tdclass="code">optional</td>
<tdclass="code">False</td>
<td>When you define a field as <spanclass="code">optional</span>, you may turn this field on or off in every flavour (a specific widget will be included in the flavour for this). If you turn the field on, it will appear in view/edit pages; else, it will completely disappear. This is one of the features that allow to tackle <i>variability</i>: in a given organisation the field may be used, in another one it may not. Or even within the same application, the field can be enabled in a given flavour and disabled in another. More information about this parameter may be found <ahref="genCreatingAdvancedClasses.html#optional">here</a>.</td>
</tr>
<tr>
<tdclass="code">editDefault</td>
<tdclass="code">False</td>
<td>When <spanclass="code">editDefault = True</span>, a special widget will be present in every flavour; it will allow you to enter or edit the default value for the field. Instead of "hardcoding" the default value through parameter <spanclass="code">default</span>, using <spanclass="code">editDefault</span> allows to do it through-the-web, flavour by flavour. More information about this parameter may be found <ahref="genCreatingAdvancedClasses.html#editDefault">here</a>.</td>
</tr>
<tr>
<tdclass="code">show</td>
<tdclass="code">True</td>
<td>You may specify here a special condition under which the field will be visible or not. This condition may be:
<ul>
<li>a simple boolean value;</li>
<li>a Python (instance) method that returns True, False (one any other equivalent value). This method does not take any argument.</li>
</ul>
Note that visibility of a given field does not only depend on this parameter. It also depends on its optionality (see parameter <spanclass="code">optional</span>) and on the user having or not the permission to view and/or edit the field (see parameters <spanclass="code">specificReadPermission</span> and <spanclass="code">specificWritePermission</span> below).
</td>
</tr>
<tr>
<tdclass="code">page</td>
<tdclass="code">main</td>
<td>By default, for every gen-class you define, gen will produce 2 views: one for consulting information about an instance, one for editing this information. If you have a limited number of fields, a single page is sufficient for displaying all fields on both views. You may also decide to create several pages. The default page is named "main". If, for this parameter, you specify another page, gen will automatically create it (on both views) and allow the user to navigate from one page to the other while consulting or editing an instance (every page will be represented as a tab). If you define several pages for a given class, the main page will take the internationalized name of the class (it corresponds to i18n label <spanclass="code">[full_class_name]</span> in i18n domain <spanclass="code">plone</span>, where <spanclass="code">[full_class_name]</span> is the class name including the package prefix where dots have been replaced with underscores), and the other pages will take their names from i18n label <spanclass="code">[full_class_name]_page_[page_name]</span> again in i18n domain <spanclass="code">plone</span>. More information about pages may be found <ahref="genCreatingAdvancedClasses.html#pagesAndGroups">here</a>; more information about i18n may be found <ahref="genCreatingAdvancedClasses.html#i18n">here</a>.</td>
</tr>
<tr>
<tdclass="code">group</td>
<tdclass="code">None</td>
<td>Within every page, you may put widgets into "groups" that will be graphically rendered as fieldsets. Normally, widgets are rendered in the same order as the order of their declaration in the Python class; putting them into groups may change this behaviour. If you specify a string here, a group will be created and this field will be rendered into it on both views (consult/edit). The name of the group will correspond to i18n label <spanclass="code">[full_class_name]_group_[group_name]</span> in i18n domain <spanclass="code">plone</span>, where <spanclass="code">[full_class_name]</span> is the class name including the package prefix where dots have been replaced with underscores. More information about i18n may be found <ahref="genCreatingAdvancedClasses.html#i18n">here</a>. If you add something like <spanclass="code">_[number]</span> to the group name, widgets from the group will be rendered into columns; <spanclass="code">number</span> being the number of columns in the group. For example, if you define several fields with parameter <spanclass="code">group="groupA_3"</span>, field values will be put in group <spanclass="code">groupA</span> that will span 3 columns. If you specify different number of columns every time you use the group parameter for different fields, all numbers will be ignored excepted the one of the first field declaration. For subsequent field declarations, you don't need to specify the columns number again. More information about pages and groups may be found <ahref="genCreatingAdvancedClasses.html#pagesAndGroups">here</a>.</td>
</tr>
<tr>
<tdclass="code">move</td>
<tdclass="code">0</td>
<td>Normally, fields are rendered in consult/edit pages in the order of their declaration in the Python class. You may change this by specifying an integer value for the parameter <spanclass="code">move</span>. For example, specifing <spanclass="code">move=-2</span> for a given field will move the field up to 2 positions in the list of field declarations. This feature may be useful when you have a class hierarchy and you want to place fields from a child class at a given position among the fields from a parent class.</td>
</tr>
<tr>
<tdclass="code">searchable</td>
<tdclass="code">False</td>
<td>When defining a field as <spanclass="code">searchable</span>, the field declaration will be registered in the low-level indexing mechanisms provided by Zope and Plone, allowing fast queries based on this field; the searches performed via the global "search" in Plone will take the field into account, too.</td>
</tr>
<tr>
<tdclass="code">specificReadPermission</td>
<tdclass="code">None</td>
<td>By default, permission to read every field declared in a class is granted if the user has the right to read class instances as a whole. If you want this field to get its own "read" permission, set this parameter to <spanclass="code">True</span>. More information about security may be found <ahref="genSecurityAndWorkflows.html">here</a>; specific details about usage of this field may be found <ahref="genSecurityAndWorkflows.html#specificFieldPermissions">here</a>.
</td>
</tr>
<tr>
<tdclass="code">specificWritePermission</td>
<tdclass="code">None</td>
<td>By default, permission to write (=edit) every field declared in a class is granted if the user has the right to create an edit instances as a whole. If you want this field to get its own "write" permission, set this parameter to <spanclass="code">True</span>. More information about security may be found <ahref="genSecurityAndWorkflows.html">here</a>; specific details about usage of this field may be found <ahref="genSecurityAndWorkflows.html#specificFieldPermissions">here</a>.
</td>
</tr>
<tr>
<tdclass="code">width</td>
<tdclass="code">None</td>
<td>An integer value that represents the width of a widget. For the moment, it is only used for <spanclass="code">String</span>s whose format is <spanclass="code">String.LINE</span>. For those Strings, default value is 50.</td>
</tr>
<tr>
<tdclass="code">master</td>
<tdclass="code">None</td>
<td>Another field that will in some manner influence the current field (display it or not, for example). More information about master/slave relationships between fields may be found <ahref="genCreatingAdvancedClasses.html#mastersAndSlaves">here</a>.</td>
</tr>
<tr>
<tdclass="code">masterValue</td>
<tdclass="code">None</td>
<td>If a <spanclass="code">master</span> is specified (see previous parameter), this parameter specifies the value of the master field that will influence the current field (display it or not, for example). More information about master/slave relationships between fields may be found <ahref="genCreatingAdvancedClasses.html#mastersAndSlaves">here</a>.</td>
</tr>
</table>
<h1><aname="integersAndFloats"></a>Integers and Floats</h1>
<p>Integers and floats have no additional parameters. In this section, we will simply illustrate, on Integers and Floats, some parameters defined in the previous section. Let's consider the following class:</p>
<p>Recall from <ahref="gen.html">the introduction</a> that a class declared as <spanclass="code">root</span> is of special importance: it represents a "main" concept in your application. For every root class, a tab is available in the dashboard for viewing, editing and deleting objects of this class.</p>
<p>Because <spanclass="code">i1</span> is defined with <spanclass="code">show=False</span>, it will never appear on Appy views. <spanclass="code">i2</span> illustrates a validator method that prevents entered values to be lower than 10 (be careful: because the value is not mandatory (default multiplicity=(0,1)), <spanclass="code">validate_i2</span> will still be called even if <spanclass="code">value</span> is <spanclass="code">None</span>. <spanclass="code">f1</span> illustrates how to define a Python method for the <spanclass="code">show</span> parameter; because this is a silly method that always return True, <spanclass="code">f1</span> will always be displayed. <spanclass="code">f1</span> will be displayed on another page named <spanclass="code">other</span>. <spanclass="code">f2</span> will be mandatory. So when creating an instance of <spanclass="code">Zzz</span> through-the-web, you get the following screen:</p>
<p>Plone needs a field named <spanclass="code">title</span>; because you did not had any field named <spanclass="code">title</span> in your class, Plone has added one automatically. This is because at several places Plone and gen use the title of objects. If you don't care about this, simply create an attribute <spanclass="code">title=String(multiplicity=(0,1), show=False)</span>. The field will disappear (don't forget to specify this multiplicity; else, the field will not show up but will still be mandatory: it will produce an error and you will be blocked); an internal title will be generated instead that will produce ugly results at some places: so it is not recommanded to do it. Let's see how the validation system behaves if we type a wrong value in <spanclass="code">i2</span> and nothing in <spanclass="code">f2</span>:</p>
<p>Now, through the green tabs, you may browse the 2 pages for any Zzz instance. Clicking into the tab will display the consult view, while clicking on the pen will bring the edit view. Going from one edit page to the other can also be done through "next" and "previous" buttons.</p>
<p>Beyond validation of specific fields, gen also allows to perform global, "inter-field" validation. More information <ahref="genCreatingAdvancedClasses.html#specialMethods">here</a>.</p>
<p>With <spanclass="code">String</span>s, adequate use of arguments <spanclass="code">validator</span> and <spanclass="code">multiplicity</span> may produce more widgets and/or behaviours. Consider the following class:</p>
<p>The edit view generated from this class looks like this:</p>
<palign="center"><imgsrc="img/strings7.png"></p>
<p>For field <spanclass="code">anEmail</span>, a valid email was entered so the validation machinery does not complain. For <spanclass="code">anUrl</span> and <spanclass="code">anAlphanumericValue</span> (the 2 other predefined regular expressions for validating String fields shipped with gen) an error message is generated. The field <spanclass="code">aSingleSelectedValue</span> uses a list of strings as validator and maximum multiplicity is 1: the generated widget is a listbox where a single value may be selected. The field <spanclass="code">aSingleMandatorySelectedValue</span> is mandatory because of the <spanclass="code">multiplicity</span> parameter being <spanclass="code">(1,1)</span>; a validation error is generated because no value was selected. The field <spanclass="code">aMultipleSelectedValue</span> does not limit the maximum number of chosen values (<spanclass="code">multiplicity=(1,None)</span>): the widget is a listbox where several values may be selected.</p>
<p>Field <spanclass="code">aMultipleSelectedValue</span> has also been specified as <spanclass="code">searchable</span>. Suppose we have created this instance of <spanclass="code">SeveralStrings</span>:</p>
<palign="center"><imgsrc="img/strings8.png"></p>
<p>When using the Plone global search in the right top corner, you will notice that entering "Value u" will produce a match for our instance:</p>
<palign="center"><imgsrc="img/strings9.png"></p>
<p>Entering "Value x" for example will produce no match at all because <spanclass="code">aSingleMandatorySelectedValue</span> was not specified as <spanclass="code">searchable</span>. Note that <spanclass="code">title</span> fields are automatically set as <spanclass="code">searchable</span>.</p>
<h1><aname="booleans"></a>Booleans</h1>
<p>Booleans have no additional parameters. Specifying <spanclass="code">aBooleanValue = Boolean(default=True)</span> will produce this on the edit view:</p>
<palign="center"><imgsrc="img/booleans1.png"></p>
<h1><aname="dates"></a>Dates</h1>
<p>Dates have an additional attribute named <spanclass="code">format</span> which may take the following values:</p>
<p>When editing a <spanclass="code">Date</span> in any format, instead of using the listboxes for selecting values for year, month and day, you may click on the icon with a "12" on it: a nice <spanclass="code">Date</span> chooser written in Javascript will pop up as shown above.</p>
<h1><aname="files"></a>Files</h1>
<p>When specifying this: <spanclass="code">anAttachedFile = File()</span> you get this result on the edit view when an object is being created:</p>
<palign="center"><imgsrc="img/files1.png"></p>
<p>("Parcourir" means "Browse" in french). You get this result on the consult view:</p>
<palign="center"><imgsrc="img/files2.png"></p>
<p>If you want to edit the corresponding object, you will get this:</p>
<palign="center"><imgsrc="img/files3.png"></p>
<p>Any kind of file may be uploaded in <spanclass="code">File</span> fields, but for png, jpg and gif files, you may specify an additional parameter <spanclass="code">isImage=True</span> and your gen-ified Plone will render the image. Let's define this field:</p>
<p>The consult view will render the image like on this example:</p>
<palign="center"><imgsrc="img/files4.png"></p>
<p>On the edit view, the widget that allows to modify the image will look like this:</p>
<palign="center"><imgsrc="img/files5.png"></p>
<h1><aname="references"></a>References</h1>
<p>References allow to specify associations between classes in order to build webs of interrelated objects. Suppose you want to implement this association:</p>
<palign="center"><imgsrc="img/refs1.png"></p>
<p>The corresponding gen model looks like this:</p>
<p>Such an association is expressed in gen by 2 "crossed" <spanclass="code">Ref</span> instances (see definition of attribute <spanclass="code">orders</span>):
<ul>
<li>the attribute named <spanclass="code">orders</span> specifies the "main" or "forward" reference;</li>
<li>the attribute named <spanclass="code">client</span> specifies the "secondary" or "backward" reference.</li>
</ul>
</p>
<p>As implemented in gen, an association is always dyssymmetric: one association end is more "important" than the other and provides some functionalities like adding or linking objects. In the above example, the association end named <spanclass="code">orders</span> allows to create and add new <spanclass="code">Order</span> instances (<spanclass="code">add=True</span>). In the generated product, once you have created a <spanclass="code">Client</span> instance, for field <spanclass="code">orders</span> you will get the following consult view:</p>
<palign="center"><imgsrc="img/refs2.png"></p>
<p>Remember that you can't get rid of the <spanclass="code">title</span> field. So one elegant solution is to specify it as invisible <spanclass="code">(show=False)</span> and compute it from other fields every time an object is created or updated (special method <spanclass="code">onEdit</span>: when an object was just created, parameter <spanclass="code">created</span> is <spanclass="code">True</span>; when an object was just modified, <spanclass="code">created</span> is <spanclass="code">False</span>). Here, in both cases, we update the value of field <spanclass="code">title</span> with <spanclass="code">firstName + ' ' + name</span>.</p>
<p>On this view, because you specified <spanclass="code">add=True</span> for field <spanclass="code">orders</span>, the corresponding widget displays a "plus" icon for creating new <spanclass="code">Order</span> instances and link them to you this client. Clicking on it will bring you to the edit view for <spanclass="code">Order</span>:</p>
<palign="center"><imgsrc="img/refs3.png"></p>
<p>Saving the order brings you to the consult view for this order:</p>
<palign="center"><imgsrc="img/refs4.png"></p>
<p>On this view, a specific widget was added (it corresponds to backward reference <spanclass="code">client</span>) that allows you to walk to the linked object. Clicking on "Gaetan Delannay" will bring you back to him. After repeating this process several times, you will get a result that will look like this:</p>
<palign="center"><imgsrc="img/refs5.png"></p>
<p>If you had specified <spanclass="code">multiplicity=(0,4)</span> for field <spanclass="code">orders</span>, the "plus" icon would have disappeared, preventing you from creating an invalid fifth order. Unlike standard Plone references, gen <spanclass="code">Ref</span> fields are <b>ordered</b>; the arrows allow you to move them up or down. The other icons allow you to edit and delete them.</p>
<p>Besides the "add" functionality, association ends may also provide the "link" functionality. This produces another widget that allows you to link an object to existing ones instead of creating + linking them. Suppose you extend you model with the concept of <spanclass="code">Product</span>: an order may now specify one or several products. The model would include the new <spanclass="code">Product</span> class and the <spanclass="code">Order</span> class would get an additional <spanclass="code">Ref</span> field:</p>
<p>Tip: when making changes to you model, re-generate it, relaunch Zope, go to "site setup"-> Add/Remove Products" and reinstall the generated product. Another tip: any change you make to your Python code needs a Zope restart; else it will not be taken into account.</p>
<p>So now you are able to create products. Because you specified class <spanclass="code">Product</span> with <spanclass="code">root=True</span>, on the main dashboard for you application you get a new tab that allows you to consult and create products. After some product creations you will get a setting like this:</p>
<palign="center"><imgsrc="img/refs6.png"></p>
<p>Now, if you go back to the first order made by Gaetan Delannay, and go to the edit view by clicking on the pen, a new widget will allow to select which products are concerned by this order:</p>
<palign="center"><imgsrc="img/refs7.png"></p>
<p>Clicking on "save" will bring you back to the consult view for this order:</p>
<palign="center"><imgsrc="img/refs8.png"></p>
<p>What is a bit annoying for the moment is that the <spanclass="code">Ref</span> widget configured with <spanclass="code">add=True</span> is rendered only on the consult view, while the <spanclass="code">Ref</span> widget configured with <spanclass="code">link=True</span> behaves "normally" and renders on both edit and consult views. This is a technical limitation; we will try to improve this in the near future. Another improvement will be to be able to select both <spanclass="code">add=True</span> and <spanclass="code">link=True</span> (this is not possible right now).</p>
<p>You will also notice that when defining an association, both <spanclass="code">Ref</span> instances are defined in one place (=at the forward reference, like in <spanclass="code">products = Ref(Product, add=False, link=True, multiplicity=(1,None),back=Ref(attribute='orders'))</span>). The main reason for this choice is to be able in the future to link gen-classes with external, standard Plone content types. The name of the backward reference is given in the <spanclass="code">attribute</span> parameter of the backward <spanclass="code">Ref</span> instance. For example, from a Product instance <spanclass="code">p</span> you may get all orders related to it by typing <spanclass="code">p.orders</span>. The consult view uses this feature and displays it:</p>
<palign="center"><imgsrc="img/refs9.png"></p>
<p>Rendering of backward references is currently less polished than forward references. If, for any reason, you don't want a backward reference to be visible, you can simply configure it like any other widget: <spanclass="code">back=Ref(attribute='orders', show=False)</span></p>
<p>Until now, all examples are done using the "admin" user. So for example all actions that one may trigger on objects (edit, delete, change order of references, etc) are enabled. We will present the security model that underlies Plone and gen later on; then we will be able to configure security.</p>
<p>For references, 2 more parameters allow to customize the way they are rendered: the boolean <spanclass="code">showHeaders</span> and <spanclass="code">shownInfo</span>. Let's consider again the consult view for a client (5 pictures above: gold client "Gaetan Delannay"). Beyond order's titles, I would like to display their description, too, in another column. But If I have several columns, it would be nice to get some columns headers. You may achieve the desired result by changing the definition of the field <spanclass="code">orders</span> this way:</p>
<p><spanclass="code">showHeaders</span> simply tells gen to display or not headers for the table; <spanclass="code">shownInfo</span> specifies (in a list or tuple) names of fields to display for the referenced objects. By default, field <spanclass="code">title</span> is always displayed; you don't have to specify it in <spanclass="code">shownInfo</span>. Here's the result:</p>
<palign="center"><imgsrc="img/refs10.png"></p>
<p>The <spanclass="code">shownInfo</span> parameter may also be used with <spanclass="code">Ref</span>s specifying <spanclass="code">link=True</span>. For <spanclass="code">Ref</span> field <spanclass="code">products</span> of class <spanclass="code">Order</span>, specifying <spanclass="code">shownInfo=('description',)</span> will produce this, when creating a new <spanclass="code">Order</span>:</p>
<palign="center"><imgsrc="img/refs10b.png"></p>
<p>The title/name of the referred object always appears; here, the <spanclass="code">description</span> also appears. If you want the <spanclass="code">title</span> to appear at a different place, simply specify it in the <spanclass="code">shownInfo</span> parameter. For example, specifying <spanclass="code">shownInfo=('description','title')</span> will produce:</p>
<palign="center"><imgsrc="img/refs10c.png"></p>
<p> By adding parameter <spanclass="code">wide=True</span>, <spanclass="code">Ref</span> tables take all available space. Returning to the previous example, specifying this parameter will produce this:</p>
<palign="center"><imgsrc="img/refs11.png"></p>
<p>When using <spanclass="code">shownInfo</span>, you may specify any field name, including <spanclass="code">Ref</span> fields. If you specify <spanclass="code">shownInfo=('description', 'products')</span> for the field <spanclass="code">orders</span> of class <spanclass="code">Client</span> and modify rendering of field <spanclass="code">products</span> from class <spanclass="code">Order</span> this way:</p>
<p>If, for field <spanclass="code">products</span>, <spanclass="code">add=True</span> was specified, on this screen you would have been able to add directly new products to orders through specific "plus" icons:</p>
<palign="center"><imgsrc="img/refs13.png"></p>
<p>Let's consider again attribute <spanclass="code">products</span> of class <spanclass="code">Order</span> (with <spanclass="code">add=False</span> and <spanclass="code">link=True</span>). When specifying this, gen allows every <spanclass="code">Order</span> to be associated with any <spanclass="code">Product</span> defined in the whole Plone site (in this case, <spanclass="code">Product A</span>, <spanclass="code">Product B</span> and <spanclass="code">Product C</span>):</p>
<palign="center"><imgsrc="img/refs14.png"></p>
<p>You may want to filter only some products instead of gathering all defined products. The <spanclass="code">select</span> parameter may be used for this. Here is an example:</p>
<p>This silly example only selects products whose description contains the word "Descr", which is only the case for Products <spanclass="code">Product B</span> and <spanclass="code">Product C</span>. So the "Products" widget will not contain <spanclass="code">Product A</span> anymore:</p>
<palign="center"><imgsrc="img/refs15.png"></p>
<p>The use of the <spanclass="code">select</span> attribute may cause performance problems for large numbers of objects; an alternative attribute may appear in the future.</p>
<h1><aname="computed"></a>Computed fields</h1>
<p>If you want to define a field whose value is not hardcoded in the database, but depends on some computation, then you must use a <spanclass="code">Computed</span> field. Computed fields have two main purposes:</p>
<ul>
<li>displaying fields whose values are computed from other fields or other data (like the "reference" of an item, that includes some elements like a category's acronym, a year, etc);</li>
<li>producing nice representations of a field (for example, the computation may produce a graphical representation of the field value).</li>
</ul>
<p>Because computed fields, like any other field, may be displayed on dashboards, it allows you to make the latters even more appealing! (please note how good I am at marketing gen)</p>
<p>Let's try it on our example. Suppose we want to produce nice references for orders, based on some random number (yes, it would have been better to use some incremental number: it it really easy to do this with gen, but you need to know how to customize the configuration panel, which is explained later). We need to define a field <spanclass="code">number</span> that will hold the order number and will be invisible. Then, we will define a <spanclass="code">Computed</span> field named <spanclass="code">reference</span> that will produce the reference based on some prefix and the order number. Class <spanclass="code">Order</span> need to be updated like this:</p>
<p>Method <spanclass="code">onEdit</span> is used to generate the order number when the order is created. The <spanclass="code">reference</span> field is a <spanclass="code">Computed</span> field: parameter <spanclass="code">method</span> specifies the Python method that will compute the field value. In this case, this value is simply the order <spanclass="code">number</span> with some prefix. Now, let's create this order and see what happens:</p>
<palign="center"><imgsrc="img/computed1.png"></p>
<p><spanclass="code">Computed</span> fields do not appear on edit views, only on consult views. Clicking on "Save" will bring you to the following consult view:</p>
<palign="center"><imgsrc="img/computed2.png"></p>
<p>Like any other field, <spanclass="code">Computed</span> fields may appear on <spanclass="code">Ref</span> fields or on dashboards. For example, if we change the definition of <spanclass="code">Ref</span> field <spanclass="code">orders</span> on class <spanclass="code">Client</span> this way:</p>
<p>order references will appear on the corresponding consult view:</p>
<palign="center"><imgsrc="img/computed3.png"></p>
<p>Python methods specified in attribute <spanclass="code">with</span> may return HTML code.</p>
<h1><aname="actions"></a>Actions</h1>
<p>Actions are special fields that allow to trigger functions. For the moment, they are represented as buttons and are shown only on consult views (not on edit views). Let's take an example. Suppose we modify class <spanclass="code">Product</span> this way:</p>
<p>Firstly, we have added attribute <spanclass="code">stock</span>, that allows us to know how many <spanclass="code">Product</span> items we have in stock. Then, we have added a dummy action named <spanclass="code">order</span> that allows us to re-order a product when the stock is too low. Suppose we have defined this product:</p>
<palign="center"><imgsrc="img/actions1.png"></p>
<p>Because the stock is lower than 3, the <spanclass="code">order</span> action (every action is defined as an instance of <spanclass="code">appy.gen.Action</span>) is visible (because of parameter <spanclass="code">show</span> of action <spanclass="code">order</span>). The triggered behaviour is specified by a Python method given in parameter <spanclass="code">action</span>. In this silly example, the action as the direct effect of setting stock to value 3. Clicking on button "order" will have this effect:</p>
<palign="center"><imgsrc="img/actions2.png"></p>
<p><spanclass="code">stock</span> is equal to 3; the <spanclass="code">order</span> action is not visible anymore (because the method specified in parameter <spanclass="code">show</span> returns <spanclass="code">False</span>.</p>
<p>Considering actions as "fields" is quite different from other frameworks or standard Plone. This has several advantages:</p>
<ul>
<li>You may reuse the security machinery linked to fields;</li>
<li>You may render them where you want, on any page/group, on <spanclass="code">Ref</span> fields, or on dashboards.</li>
</ul>
<p>Note that the <spanclass="code">action</span> parameter may hold a list/tuple of Python methods instead of a single method (like in the previous example).</p>
<p>In the example, you've seen that a standard message was rendered: "The action has been successfully executed.". If you want to change this message, please read the <ahref="genCreatingAdvancedClasses.html#i18n">section on i18n</a> first. In fact, for every action field, gen generates 2 i18n labels: <spanclass="code">[full_class_name]_[field_name]_action_ok</span> and <spanclass="code">[full_class_name]_[field_name]_action_ko</span>. The first is rendered when the action succeeds; the second one is rendered when the action fails. The action succeeds when the Python method given in the <spanclass="code">action</span> parameter:</p>
<ul>
<li>returns nothing (or <spanclass="code">None</span>) (it was the case in the example);<li>
<li>returns the boolean value <spanclass="code">True</span> or any Python equivalent.</li>
</ul>
<p>The action fails when the Python method returns <spanclass="code">False</span> or if it raises an exception. In this latter case, the exception message is part of the rendered message.</p>
<p>If the <spanclass="code">action</span> parameter specifies several Python methods, the action succeeds if all Python methods succeed.</p>
<p>If you need to render different messages under different circumstances, the 2 labels generated by gen may not be sufficient. This is why a Python method specified in an <spanclass="code">action</span> parameter may return a 2-tuple instead of <spanclass="code">None</span>, <spanclass="code">True</span> or <spanclass="code">False</span>. The first element of this tuple determines if the method succeeded or not (<spanclass="code">True</span> or <spanclass="code">False</span>); the second element is a string containing the specific message to render. If this latter must be i18n'ed, you can create your own i18n label and use the method <spanclass="code">translate</span> as described <ahref="genCreatingAdvancedClasses.html#i18n">here</a> (near the end of the section). In the case of multiple Python methods, messages returned are concatenated.</p>
<p>The installation procedure for your gen-application is defined as an action. More information about this <ahref="genCreatingAdvancedClasses.html#customToolAndFlavour">here</a>.</p>
<p>In future gen releases, you will be able to define an icon as an alternative way to render the action. We will also add the concept of action <i>parameters</i>.</p>
<h1><aname="objectStorage"></a>Some thoughts about how gen-controlled objects are stored</h1>
<p>Remember that the ZODB is a kind of folder hierarchy; the Plone site itself is a "folderish" object within that hierarchy. For every gen-application, a folder is created within the Plone site object. All objects created through this application (with the exception of objects tied to the application "configuration", more info <ahref="genCreatingAdvancedClasses.html#customToolAndFlavour">here</a>) will be created within this folder.</p>
<p>This screenshot shows the ZMI (Zope Management Interface) available at http://localhost:8080/manage. You see that within the <spanclass="code">Appy</span> object (which is a Plone site) you have, among some predefined Plone objects like <spanclass="code">MailHost</span> or <spanclass="code">Members</span>, 2 folders named <spanclass="code">ZopeComponent</span> and <spanclass="code">Zzz</span>. Each of these 2 folders correspond to a gen-application that has the same name. Those folders are an Appy adaptation of the Plone standard content type named "Large Plone Folder", which is used for storing a large number of objects. If you click on this folder you will see its content (=all objects created through the corresponding gen-application). For several reasons, you may want to put more structure among this folder. Firstly, if you reach a large number of objects, it could lead to performance problems. Secondly, if you use the standard Plone "navigation" portlet, you will see in it all your objects in a single long and unstructured list under a single folder entry named according to your application. The solution is to tell gen that some classes are "folderish". You simply tell this by specifying <spanclass="code">folder=True</span> on your class. Suppose you do this on class <spanclass="code">Client</span>:</p>