ERP5 Handbook/From form to API
From form to API - first look behind the scenes
[edit | edit source]Management interface of a form
[edit | edit source]When you look at the ERP5 screen, what you see is a rendered form (ERP5 Form, which is based on a Formulator form). Its name is usually at the end of the URL (like "Person_viewCareer"); often, the URL ends with "/view", which means that you are looking at the default form of an object. If you see a number of tabs (like "View / Details / Career"), click on any of them and you will have the form name in the URL. If you are in a module and there is no tabs, things are a bit more difficult, we will come to that a bit later.
Once you have the form name, append "/manage_main" to it - now you are in a management screen, and you have a complete list of fields which are visible in on the form (and possibly some which are not visible).
We won't be talking in detail about editing a form - you can consult Formulator documentation for that. The purpose here is show how fields are filled with values, and how they interact with the object.
Property fields and API
[edit | edit source]Simple fields - those containing strings, numbers, or checkboxes with boolean values, are bound to object attributes by naming convention. When a field is rendered, it invokes an appropriate accessor to get an attribute value. This is why all controls begin with "my_" - a field:
my_title
invokes a method:
.getTitle
to get value of an attribute:
title
Most of the accessors are auto-generated (see "Magic of ERP5" to know more) - if a property "title" is defined, an object has the accessor, but you won't find it in the code (!). Sometimes accessors are overwritten - e.g. a Person object has a different .getTitle method. This one you can find in the code.
When a form is submitted, and you had changed value of a "title" field, the script which is being called by the form (usu. "Base_edit") invokes a setter:
.setTitle
which, not surprisingly, sets the title. Replace the form_name/manage_main with "/Base_viewDict" - you will see raw data of the object, and you will find your title.
That's almost all there is to it. There is a number of special fields for different types of attributes - there is a StringField, TextAreaField, IntField, FloatField, DateField, EmailField. These fields check if the value you've entered is appropriate.
Relation fields and API
[edit | edit source]A relation field (specifically, RelationStringField) has already been described in UI section. Basically, it follows the same principle as property fields. The difference is that in most cases a relation field used for relation
source
is called
my_source_title
so it invokes accessor:
.getSourceTitle
the result being that it displays a nice title of the related object, instead of its relative url (like "/organisation_module/12"). And conversely, when you fill it and submit a form, it uses the title to search for the appropriate object.
You can also apply the same convention to use other properties then title, e.g. you could create a field:
my_source_relative_url
which will display and use a relative url of a related object.
There is also a MultiRelationStringField, which is used to get/set a relation to many objects:
my_destination_title_list
uses
.getDestinationTitleList
and has a funny behaviour, which will be explained somewhere else.
Category membership fields and API
[edit | edit source]Some fields allow you to assign an object to certain categories (in other words, to use categories for classification). For example, you can set a product_line on a product, or nationality on a person. For this purpose, a ListField is used. It follows the same principle:
my_nationality
allows you to choose a nationality, and it assigns the person to a chosen subcategory of "nationality" base category.
The way to field such a control with values is to give it a list of tuples containing title and url of categories, like:
'', '', ['German', 'd'], ['British', 'en']...
This is most easily achieved through the category's API; most commonly used method are:
.getCategoryChildLogicalPathItemList and getCategoryChildCompactLogicalPathItemList
The latter different from the former in that if the path made of titles becomes too long, it tries to trim it in a reasonable way.
A MultiListField works the same way, only it allows for selecting many categories (by ctrl-clicking), and, obviously, uses a:
.get[category]List
accessor.