Servoy Best Practices/Chapter 3
From ServoyFORGE Wiki
Contents |
[edit] Introduction
There is no single naming convention for Servoy or any other platform for that matter. This page doesn’t dictate how you should name your objects in Servoy. The purpose of this page is merely to show you all the considerations and to give you a guideline for defining your own naming convention and in the end also provides you one ready to use.
[edit] Module development considerations
When developing (and using) modules you will notice that certain objects need to have a unique name or it will conflict with other loaded modules. The following objects will be part of the solution it is loaded in and are therefore subject to a strict naming convention.
- Global methods
- Global variables
- Global JavaScript variables (the ones defined without 'var')
- Relations
- Valuelists
- Forms
- Stylesheets
- i18n keys
- Solutions
- Database connections
The last 4 objects are probably the last ones that will be a problem within a single
development environment. The problems with these however will come when you import
third-party modules/solutions into your repository. Or the other way around, when you
sell/distribute your solutions to others.
[edit] General
In this chapter we use the term ‘camelcase’ a lot. For those who don’t know what that means here is an example: thisIsAnExampleOfCamelCasing
(more info on prefixing)
| type | prefix | comment/example |
|---|---|---|
| Solutions | cmp_sol_ | companyprefix_solutionprefix_ |
| Forms | sol_ | rest camelcase |
| Relations | sol_ | rest lowercase |
| Valuelists | sol_ | rest camelcase |
| Global var | _g_sol_ | rest camelcase |
| Global var as constant | _k_SOL_ | rest UPPERCASE |
| Global method | sol_ | rest camelcase |
| Stylesheet | sol_ | rest camelcase |
| i18n keys | sol.typeofobject.name | sol.button.cancel |
A global constant is a global variable where the value doesn't change.
[edit] Form Elements
Form elements are any element placed on a form. You can differentiate them by their basic object (field, label/button, tabpanel, etc) or by format (combobox, date/timefield, checkbox, radiobutton, etc.) But there are also form objects that look like different object but are in fact one single base object for instance a button, label and image are all the same object ‘label’. It’s only when put an image in there or link a method to it that it changes it’s function. So should we name it a label or should we differentiate them by their function. In the following list we will differentiate them by their base object, format and their function.
| type | prefix | comment/example |
|---|---|---|
| field | fld | fldMyFieldName |
| labels | lbl | lblMyFieldName |
| buttons | btn | btnMyButtonName |
| tabpanel | tpl | tplMyTabPanelName |
| tab | tab | tabMyTabName |
| bean | obj | objMyBeanName |
| portal | ptl | ptlMyPortalName |
| images | img | imgMyImageName |
Now image objects are a special case since they can be used for a lot of things like buttons
and headers. Here are some examples for naming them. Any image that doesn’t fall under
this should be prefixed with ‘img’ as proposed in the list above.
| type | prefix | comment/example |
|---|---|---|
| images as buttons | btn | btnMyButtonName |
Of course you could also have a label with an onAction method but with the showClick property disabled. This won’t draw the button but it still functions as one. So lets propose to name these also as a regular button.
| type | prefix | comment/example |
|---|---|---|
| labels as buttons | btn | btnMyButtonName |
[edit] Form Methods
Form methods connected to form elements will prefix with the element name (as per convention stated above) and then followed by the event name it gets triggered from like "fldFieldName_eventName"
When form methods are called from several events from that same element ONLY then use a descriptive suffix like fldSearch_executeSearch.
When a method is called from several locations/elements then use the above convention and call the general method from there. This general method uses only a descriptive name using camelcasing like "initForm" or "setSplitPane".
Standard prefixes used for general form (sub) scripts… initSomething, getSomething, setSomething, doSomething, onEventName…
[edit] Variables
Variables are in camelcase and start with an underscore for beter visibility in your code.
Constants are in uppercase and don't have a type prefix (s/n/b/etc).
(discussion about type prefix)
| type | prefix | comment/example | |||
|---|---|---|---|---|---|
| String | _s | _sMyVar | |||
| Number | _n | _nMyVar | |||
| Date | _d | _dMyVar | |||
| Boolean | _b | _bMyVar | |||
| Array | _a | _aMyVar | |||
| Object | _o | _oMyVar | |||
| Special objects use a 2 character prefix | |||||
| Dataset | _ds | _dsMyVar | |||
| Foundset | _fs | _fsMyVar | |||
| Record | _rc | _rcMyVar | |||
| Other less used objects can use the _o prefix. | |||||
| JS globals (the ones declared without 'var') will use the solution prefix plus '_g_js_' | |||||
| global JS var | _g_js_cmp_ | _g_js_cmp_sMyVar | |||
| global JS var as constant | _k_js_CMP_ | _k_js_CMP_MYVAR | |||
| Form variables | _g_ | _g_sMyVar | |||
| Form variables as constant | _k_ | _k_MYVAR | |||
A global JS or form constant is a global JS or form variable where the value doesn't change.
[edit] Media Objects
| type | prefix | comment/example |
|---|---|---|
| logo | lgo_ | lgo_company.png |
| button | btn_ | btn_imagename.png |
| any icon/widget | ico_ | ico_name.png |
Don’t mix and match hyphens and underscores. Preferably only use underscores. Preferably use all lowercase names for media objects.
Extra consideration for button naming:
The string after the btn_ prefix will be descriptive of the button's image rather than of its
action. For example btn_paperclip rather than btn_attach, and btn_plus rather than
btn_newrecord.
Keep in mind we are naming media objects here, these can have totally different form
element names to match their function.
[edit] Table/Columns
Using column prefixes has 2 big advantages. One is that you can use reserved words like password, date, etc. So you can keep your columns descriptive. The other is that in pure SQL you don’t really have to prefix the columns with a tablename to make sure the database knows what column you are talking about. And of course you yourself know immediately at what table you are looking at just by the column prefix.
Any table, column, calculation and aggregate name should be in lowercase.
| type | prefix | comment/example |
|---|---|---|
| Table | cmp_ | companyprefix_tablename |
| Column names will have a 3 character prefix of the table name (ex. table prefix) | ||
| i.e. ctc_ for column of table cmp_contact | ||
| Column | pfx_ | ctc_fullname |
| Primary Key/id column | pfx_id | |
| Foreign Key column | pfx_fk_ | rest lowercase and a descriptive name of referenced table or column |
| Boolean column | pfx_is_ | rest lowercase |
| boolean column will be of datatype Integer and will have an auto-enter value of 0 or 1 (no nulls) | ||
| Unstored calculations | c_ | rest lowercase |
| Agreggates | a_ | rest lowercase |