<p><b>gen</b> is a code <b>gen</b>erator that allows you write web apps without having to face and understand the plumbery of a given web framework. Concentrate on functionalities that need to be implemented: <b>gen</b> protects you from the complexity of low-level twisted machineries and will let you evolve in your pure, elegant and minimalistic Python world.</p>
<p>Install Zope 2.9. On Unix/Linux, the easiest way to do that is to download the <ahref="https://launchpad.net/plone/2.5/2.5.5/+download/Plone-2.5.5-UnifiedInstaller.tgz">Plone unified installer</a>, that includes Zope.</p>
<p>You just installed a lot of (deprecated) lines of code, but we will only use a very small subset of it: absolutely no line from Plone, a tiny subset of Zope and the Python interpreter that was also included.</p><br/>
<p>Create a Zope instance. A Zope instance is a web server that will listen for browser requests on some port. Launch the script named <spanclass="code">mkzopeinstance.py</span> that is included with Zope. The following lines of code create a Zope instance in <spanclass="code">/home/gdy/instances/RegInstance</span>.</p>
<p>Type anything as username and password: Appy will ignore it and create user <spanclass="code">admin</span>, password <spanclass="code">admin</span>.</p>
<p>Now, we need to write a webapp and install it into this instance. We will create a small webapp, called Registration, that will allow anonymous people to register to the Appy webapp awards and propose a webapp. The administrator of the awards will be able to consult and search registrations.</p><br/>
<p>File <spanclass="code">__init__.py</span> is required by Python, to tranform folder <spanclass="code">Registration</span> into a Python package. File <spanclass="code">Registration.py</span> will contain the definition of the class Registration: one instance of this class will be created and stored in the database every time a user registers itself though the web.</p>
<p>This class is declared as <spanclass="code">root</span>: for the moment, just remember that it gives it a special, first-class status. One line below, we define the roles that are allowed to create instances of this class. <spanclass="code">Anonymous</span> and <spanclass="code">Manager</span> are 2 standard Appy roles. The remaining lines define the attributes of every registration. Dict <spanclass="code"><i>p</i></span> is simply a shorthand for specifying the same (group of) attribute(s) to several methods.</p><br/>
<p>Zope requires a bit more than our 11-lines file to consider it to be a serious webapp. So gen includes a script that will generate a so-called "Zope product". Create, in your app, a file named <spanclass="code">generate.sh</span> with the following content.</p>
<p>Now, in your webapp, you have 2 more folders: <spanclass="code">zope</span> and <spanclass="code">tr</span>. Folder <spanclass="code">zope</span> contains the "product" as required by Zope, while <spanclass="code">tr</span> contains i18n (internationalization) files: forget about it for the moment. We can now link the webapp to the Zope instance by creating 2 symbolic links.</p>
<pclass="code codePara">
cd /home/gdy/instances/RegInstance/lib/python<br/>
<p>The first link allows the Zope instance to import your Python package, while the second one allows Zope to realize that he must take care about a third-party plug-in.</p>
<h1>Play with the webapp</h1>
<p>Launch now your Zope instance:</p>
<pclass="code codePara">
cd /home/gdy/instances/RegInstance/bin
./zopectl fg
</p>
<p>You should get something like this (with additional lines if it is the first time you launch the instance).</p>
<p>Congratulations! Now, without logging in (as anonymous user), let's create a new registration by clicking on the "plus" icon. You should get this form:</p>
<p>Of course, it was deduced from our class <spanclass="code">Registration</span>. Notice that an additional field, named <spanclass="code">title</span>, has been automatically added. Indeed, this field is of special importance to Appy, so is added if not explicitly defined. Of course, we will see that it is possible to hide it and compute it automatically, or simply to label it differently, but for the moment we will simply consider that it corresponds to the name of the webapp proposed by the user. Fields defined as <spanclass="code">String</span>s with <spanclass="code">format=String.XHTML</span> are rendered with ckeditor, an popular on-line editor integrated within Appy.</p><br/>
<p>If you do not complete the form correctly, you will get validation errors.</p>
<p>In this example, I have entered an email with a wrong format (remember, a validator <spanclass="code">String.EMAIL</span> was defined) and I entered no value for a mandatory field. <spanclass="code">multiplicity=(1,1)</span> means: at least and at most one value is required.</p><br/>