This document provides patterns and rules for working with content layout forms
used in ERP5, especially on the use on custom fields.
Table of Contents
Guideline¶ for field library¶
This guideline provides an advice of how to make field library in your business
template.
Field library is an ERP5 form which will not be accessed from users but used as
a container of proxy fields used as template field by other fields contained in
other real forms and reports. In other words, it is a collection of template
fields of proxy fields commonly used in a business template.
Why field library and proxy field?¶
Using proxy field is very useful for providing consistent UI and reducing code
duplications.
For UI¶
For example, comment field is one of the very common fields in whole ERP5 system
and it should be always the same size everywhere. Then we use proxy field, we can
define the height and width only once to the template field in the core field
library and the remaining is that all other comment fields just inherit the core
template field. This way, we can make consistent UI easily. If we did not use
proxy field, we had to set the same height and width for all comment fields one
by one, this is very hard to maintain.
About field library, this is a kind of buffer between the core field library in
erp5_core and the real fields to be displayed to users. We saw an example of
comment field above, it was a common field globally. But sometimes we want to
change an appearance of generic fields only in some business template. In such
case, we cannot change the core template fields, because they are used globally.
So we can change a field library of a target business template instead. Then we
can customize some fields only in a business template and this does not affect
UIs defined by other business templates.
For code reuse/abstraction¶
Sometimes we can find similar patterns in ERP5. For example, when we use a
RelationStringField, we often name it like "my_source_title" by following our
naming convention. And from such names, we can find a pattern. The name suggests
this field uses source category and searches document by title. And we can make
a template field for RelationStringField and put a tales expression to parse
field id and find category name and index property. Once we have such a template
field which is an abstraction of a pattern we don't have to enter a category
name and an index property name each time when adding RelationStringField,
but just using a proxy field and inherit the template field is enough. We can
omit entering various parameters and it is also useful for maintenance, future
changes. Above is a very wide range example which can apply whole ERP5, but we
can find many other small patterns in a specific context managed by single business
template like Accounting, DMS. Therefore finding a pattern and making a template
field is very practical use case of proxy field and field library.
Define once and applying to many¶
Sometimes we have to enter the same information in multiple places. For example,
a company has the same reference naming rule for Service and Product. In such case,
we have to apply the same input validation functionality to Product_view.my_reference
and Service_view.my_reference. Then we can say that both my_reference in Product_view
and Service_view are the same in reality. In such case, we should make a template field
in field library and reuse the field to inherit from proxy fields in both Product_view
nd Service_view. And in this way even if the input validation rule was changed, we
only have to update the template field and no need to touch proxy fields.
Rules¶
Create only 1 field library per business template¶
A business template represents one field of application. As the field libraries
are used to shared the semantic configuration of forms, there should be only one
field library per business template (even if this one contains multiple skin folders).
Exception¶¶
It is sometimes required to surcharge the behaviour of a field library. In this
case, it is required to create another skin folder (following the convention [surcharged_context]_[original_skin_folder_name])
and an empty field library could be created to surcharge the original one.
Example:
# In the erp5_project BT5:
erp5_project_trade/Base_viewTradeFieldLibrary[my_view_mode_title]
-> erp5_trade/Base_viewTradeFieldLibrary[my_view_mode_title]
But, this other example should never happen:
erp5_project/Base_viewTradeFieldLibrary[my_view_mode_title]
-> erp5_trade/Base_viewTradeFieldLibrary[my_view_mode_title]
No proxy field linking to an external field library are allowed¶
All proxy fields defined in a BT5 should link to the Field Library defined in this bt5.
Here are some examples that should never happen:
ApparelComponent_view[my_title]
-> Base_viewApparelFieldLibrary[my_view_mode_title]
-> Base_viewPDMFieldLibrary[my_view_mode_title]
-> ...
ApparelComponent_view[my_title]
-> Base_viewPDMFieldLibrary[my_view_mode_title]
-> ...
Exception¶¶s
Semantic field defined in a field library could link to Base_viewFieldLibrary
Example:
Base_viewPDMFieldLibrary[my_view_mode_title]
-> Base_viewFieldLibrary[my_view_mode_title]
-> ...
Surcharged skin folder
It is sometimes required to surcharge the behaviour of a skin folder. In this case,
it is required to create another skin folder (following the convention [surcharged_context]_[original_skin_folder_name])
and forms contained in this skin folder could link to the field library defined in the original BT5.
Example:
In the erp5_project BT5: erp5_project_trade/PurchaseOrder_view[my_title]
-> erp5_project_trade/Base_viewTradeFieldLibrary[my_view_mode_title]
-> erp5_trade/Base_viewTradeFieldLibrary[my_view_mode_title]
But, this other example should never happen:
erp5_project/PurchaseOrder_view[my_title]
-> erp5_trade/Base_viewTradeFieldLibrary[my_view_mode_title]
Technical template field should only be defined in Base_viewFieldLibrary¶
As the technical fields have no semantic, it is useless to duplicate them in
each field library. So, only Base_viewFieldLibrary should contains technical
field library. This will ease maintenance (no need to update all field libraries
if a new technical field is created).
Here are some examples that should never happen:
Base_viewTradeFieldLibrary[my_listbox]
Base_viewTradeFieldLibrary[my_multi_list_field]
Technical template field name should follow the my_FIELD_CLASS_NAME convention¶
This is a convention to prevent creating multiple technical template fields
(for view, dialog, report) related to the same field class.
Here are some example that should never happen:
Base_viewFieldLibrary[listbox]
Base_viewFieldLibrary[your_string_field]
Instead, it should be:
Base_viewFieldLibrary[my_listbox]
Base_viewFieldLibrary[my_string_field]
Semantic template field should use proxy field class¶
All semantic template field defined in a field library should be proxy field (either of semantic or technical field).
The semantic field name needs to be associated with the technical context¶
Here some examples of technical context :
- A form in view mode
- A form in list mode
- A form in dialog mode
- A form in report mode
The technical context is important, we do not always display things in the same
way, and we can have different technical configuration depending on the technical
context.
This naming should be used for all non-technical fields in field libraries:
my_[technical_context_name][semantic_name]
with technical_context_name having such values:
- list_mode
- view_mode
- dialog_mode
- report_mode
- core_mode (if we wish to define fields in library that are independant of the technical context).
So we can have :
OrderModule_viewOrderReport[your_order]
-> Base_viewTradeFieldLibrary[my_report_mode_order]
-> Base_viewFieldLibrary[my_report_mode_category]
-> Base_viewFieldLibrary[my_core_mode_category]
-> Base_viewFieldLibrary[my_list_field]
OrderModule_viewOrderReportDialog[your_at_date]
-> Base_viewTradeFieldLibrary[my_dialog_mode_at_date]
-> Base_viewFieldLibrary[my_dialog_mode_at_date]
-> Base_viewFieldLibrary[my_date_time_field
SaleOrder_view[my_title]
-> Base_viewTradeFieldLibrary[my_view_mode_title]
-> Base_viewFieldLibrary[my_view_mode_title]
-> Base_viewFieldLibrary[my_core_mode_title]
-> Base_viewFieldLibrary[my_string_field]
Base_viewStockReportBySite[your_site_title]
-> Base_viewTradeFieldLibrary[my_report_mode_title]
-> Base_viewFieldLibrary[my_report_mode_title]
-> Base_viewFieldLibrary[my_core_mode_title]
-> Base_viewFieldLibrary[my_string_field]
SaleOrder_view[my_source_section]
-> Base_viewTradeFieldLibrary[my_view_mode_sale_source_section]
-> Base_viewFieldLibrary[my_list_field]
SaleOrder_view[listbox]
-> Base_viewTradeFieldLibrary[my_view_mode_listbox]
-> Base_viewFieldLibrary[my_view_mode_listbox]
-> Base_viewFieldLibrary[my_listbox]
Non-field library forms should only contain proxy field¶
Proxy field should share semantic if possible¶
Nothing particular for many fields, share semantic:
SaleOrder_view[my_total_price]
-> Base_viewTradeFieldLibrary[my_view_mode_total_price]
-> Base_viewFieldLibrary[my_view_mode_money_quantity]
-> Base_viewFieldLibrary[my_float_field]
SaleOrder_view[my_title]
-> Base_viewTradeFieldLibrary[my_view_mode_title]
-> Base_viewFieldLibrary[my_view_mode_title]
-> Base_viewFieldLibrary[my_string_field]
If no semantic field is found, it means that the proxy field will link to a technical
field (which are only defined in Base_viewFieldLibrary).
If some specific semantic needed, use prefix consistent with those defined in glossary¶
Example:
for Arrow, there is a specific semantic for trade, sometimes there is the point
of view of the seller, sometimes from the buyer (and even sometimes it's only
internal movement, I didn't worked on it yet). So here for every field about
source/destination, I use 2 different names with "sale" or "purchase" inside:
SaleOrder_view[my_source_section]
-> Base_viewTradeFieldLibrary[my_sale_source_section]
-> Base_viewFieldLibrary[my_list_field]
PurchaseOrder_view[my_destination_section]
-> Base_viewTradeFieldLibrary[my_purchase_destination_section]
-> Base_viewFieldLibrary[my_list_field]
Please try as much as possible to use prefix which are consistent with those
defined in business_fields of the Glossary.
Sharing semantic as priority other sharing technical¶
SaleOrder_view[my_title]
-> Base_viewTradeFieldLibrary[my_view_mode_title]
-> Base_viewFieldLibrary[my_view_mode_title]
-> Base_viewFieldLibrary[my_string_field]
should not be:
SaleOrder_view[my_title]
-> Base_viewTradeFieldLibrary[my_view_mode_title]
-> Base_viewFieldLibrary[my_string_field]
Exception¶¶
If a technical field is always used for the same purpose and if it is good
enough to share for all usages, we don't need semantic field in Base_viewFieldLibrary
and it is acceptable to link to the technical field directly outside from the
default field library.
This is OK, because relation string field is always used for category:
SaleOrder_view[my_source_title]
-> Base_viewTradeFieldLibrary[my_view_mode_source_title]
-> Base_viewFieldLibrary[my_relation_field]
this is bad, because list_field can be used for different purpose :
SaleOrder_view[my_incoterm]
-> Base_viewTradeFieldLibrary[my_view_mode_incoterm]
-> Base_viewFieldLibrary[my_list_field]
the above one should be:
SaleOrder_view[my_incoterm]
-> Base_viewTradeFieldLibrary[my_view_mode_incoterm]
-> Base_viewFieldLibrary[my_view_mode_category]
-> Base_viewFieldLibrary[my_list_field]
Guideline¶
In each business field should have only one field library. Before we added many
field libraries in a business template and it was hard to understand each form
dependencies and was also hard to maintain.
Field library would be only one in your business template, then let's define
naming rule. we follow the names of core field libraries.
Basic naming pattern is Base_view(???)FieldLibrary. (???) would be replaced with
your business template name. For example:
- For erp5_trade, the name is Base_viewTradeFieldLibrary.
- For erp5_pdm, the name is Base_viewPDMFieldLibrary.
Structure of form and field library in a non-core business template would be following:
-
Normal form contains several fields which would be proxy field. Their template
fields would be in field library of the same business template.
-
Field library contains several fields which would be mostly proxy field. Their
template fields would be in field libraries of erp5_core(core field libraries).
Each field of field library should be unified semantically. For example, if our
business template has these three fields my_reference, my_code and my_product_name,
add my_reference, my_code and my_product_name in the field library. If multiple
portal types ( A and B ) use a my_reference field and if they are semantically
distinct, add 2 fields in the field library named my_A_reference and my_B_reference.
Finally, those 2 fields will be proxy fields of a generic my_reference.
A procedure of making field library is following:
- Add normal fields and forms to your business template.
- Add only one field library in your business template.
-
Unify existing fields semantically and make their template fields to your field
library. Those template fields should be proxy field of core field libraries.
-
Find fields which match common type defined in erp5_core.Base_viewFieldLibrary(my_view_mode_title for example)
and add template fields to the field library of your business template.
Utilities¶
There are some utility scripts in erp5_forge/erp5_toolbox skin folder.
-
SkinsTool_getDeadProxyFieldList: This is useful to find dead proxy fields if
you have existing customized forms in your custom business template and have
to merge the recent field library changes.
-
Base_checkSkinFolderForms: This is useful to check that proxification did not
modify behaviour of the forms.
Use Cases¶
Questions¶
Q:
The appearance of list fields must be different possibly
for region, role, function etc.?
A:
As field library are organized semantically, there will be category specific
template fields like my_region, my_role, my_function in a local field library.
In this way you can unify many my_region fields in your business template to
one and can customize as you want.
Q:
source_title is a different field with different UI possibly
between ticket and event (ie. This means source_title field for ticket probably
uses proxy field of another skin than crm)?
A:
You must add my_event_source_title and my_ticket_source_title as a special template
field and this template field should inherit a normal source_title.proxy order
will be following:
(Ticket is a special case)
Ticket_view.my_source_title
Base_viewCRMFieldLibrary.my_ticket_source_title
Base_viewCRMFieldLibrary.my_relation_field
Base_viewFieldLibrary.my_relation_field
(Event is a normal case)
Event_view.my_source_title
Base_viewCRMFieldLibrary.my_relation_field
Base_viewFieldLibrary.my_relation_field
In this way we can handle both special case and normal case in one local field
library and because everything is in one local field library, it is easy to
understand proxy field dependencies.
Please try as much as possible to use prefix which are consistent with those
defined in business_fields of the Glossary.
Q:
What about localised form boxes (ex.. Japanese address is
not same as French and FormBox must be used)
A:
I think there is nothing special about proxifying formbox. FormBox job is just
choosing an appropriate erp5 form to embed by user language. Probably we define
a naming rule for it and prepare a template field and enter a clever tales
expression to extract required values to make it work, just like RelationStringField.
Q:
What about fields with a lot of many specific semantic (ex. Resources in a
purchase order line should be of category use/component whereas resources in
a sale order line should be of category use/product)
A:
I think preparing a template field per specific semantic is enough. In above
example, add my_purchase_resource as a template field and use it from proxy
fields of PurchaseOrderLine and PurchaseOrderCell.Then Add my_sale_resource as
another template field and use it from another proxy fields.
Q:
If it's only used in one form, is it useful to have proxy
field ? it's same amount of work to maintain customized field library than to
maintain customized form.
A:
Good point. Having a proxy field is useful, because almost all fields should
follow user's preference and proxy field is the most useful way to realize it.
But I don't think it is useful to have dedicated proxy field for each field.
That's why the current field library provides very few template fields and
basically proxy is made per data type. But there is another opinion. Because
we cannot assume future customisation requirement, and if we want to customise
such minor fields which is used only once in standard business template, then
we have to make a proxy field from scratch and it is boring. So that all fields
should be replaced with proxy field. This is another opinion and we consider
to realize this idea now.
Q:
Why some fields in the form displayed to the user might
be not proxy fields ? Isn't it better to make ALL of them proxy field ? I can
understand exceptions for project's specific forms, but it might be better to
do no exception on generic business templates.
A:
Yes, all fields in generic business templates should be proxy fields. If you
find a non-proxy field, it is a mistake, a bug.
Q:
Why is it better to use proxy fields in generic business
templates ?
A:
It allows easier customization in customer projects and help having consistent user interface.
Missing¶
- a tool to rename proxy fields
- a tool to merge proxy fields
- naming conventions for proxied listbox fields in the field library
- naming conventions for proxy fields (ex. my_source_title)
Related Articles¶